LLVM: lib/Object/MachOObjectFile.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

41#include

42#include

43#include

44#include

45#include

46#include

47#include

48#include

49#include <system_error>

50

51using namespace llvm;

52using namespace object;

53

54namespace {

55

56 struct section_base {

57 char sectname[16];

58 char segname[16];

59 };

60

61}

62

64 return make_error("truncated or malformed object (" +

65 Msg + ")",

66 object_error::parse_failed);

67}

68

69

70template

72

73 if (P < O.getData().begin() || P + sizeof(T) > O.getData().end())

75

76 T Cmd;

77 memcpy(&Cmd, P, sizeof(T));

80 return Cmd;

81}

82

83template

85

86 if (P < O.getData().begin() || P + sizeof(T) > O.getData().end())

88

89 T Cmd;

90 memcpy(&Cmd, P, sizeof(T));

93 return Cmd;

94}

95

96static const char *

98 unsigned Sec) {

99 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);

100

101 bool Is64 = O.is64Bit();

106

107 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;

108 return reinterpret_cast<const char*>(SectionAddr);

109}

110

112 size_t MachOFilesetEntryOffset = 0) {

114 MachOFilesetEntryOffset <= O.getData().size());

115 return O.getData().data() + Offset + MachOFilesetEntryOffset;

116}

117

120 const char *P = reinterpret_cast<const char *>(DRI.p);

121 return getStructMachO::nlist\_base(O, P);

122}

123

125 if (P[15] == 0)

126

127 return P;

128

130}

131

133 return O.getHeader().cputype;

134}

135

137 return O.getHeader().cpusubtype & ~MachO::CPU_SUBTYPE_MASK;

138}

139

143}

144

145static unsigned

147 return RE.r_word0 & 0xffffff;

148}

149

152 if (O.isLittleEndian())

153 return (RE.r_word1 >> 24) & 1;

154 return (RE.r_word1 >> 7) & 1;

155}

156

157static bool

159 return (RE.r_word0 >> 30) & 1;

160}

161

164 if (O.isLittleEndian())

165 return (RE.r_word1 >> 25) & 3;

166 return (RE.r_word1 >> 5) & 3;

167}

168

169static unsigned

171 return (RE.r_word0 >> 28) & 3;

172}

173

176 if (O.isLittleEndian())

179}

180

183 if (O.is64Bit()) {

185 return Sect.flags;

186 }

188 return Sect.flags;

189}

190

194 if (auto CmdOrErr = getStructOrErrMachO::load\_command(Obj, Ptr)) {

195 if (CmdOrErr->cmdsize + Ptr > Obj.getData().end())

197 " extends past end of file");

198 if (CmdOrErr->cmdsize < 8)

200 " with size less than 8 bytes");

202 } else

203 return CmdOrErr.takeError();

204}

205

211 return malformedError("load command 0 extends past the end all load "

212 "commands in the file");

215}

216

226 " extends past the end all load commands in the file");

227 return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize, LoadCommandIndex + 1);

228}

229

230template

234 Err = malformedError("the mach header extends past the end of the "

235 "file");

236 return;

237 }

238 if (auto HeaderOrErr = getStructOrErr(

240 Header = *HeaderOrErr;

241 else

242 Err = HeaderOrErr.takeError();

243}

244

245

250};

251

254 const char *Name) {

255 if (Size == 0)

257

258 for (auto it = Elements.begin(); it != Elements.end(); ++it) {

259 const auto &E = *it;

260 if ((Offset >= E.Offset && Offset < E.Offset + E.Size) ||

262 (Offset <= E.Offset && Offset + Size >= E.Offset + E.Size))

264 " with a size of " + Twine(Size) + ", overlaps " +

265 E.Name + " at offset " + Twine(E.Offset) + " with "

266 "a size of " + Twine(E.Size));

267 auto nt = it;

268 nt++;

269 if (nt != Elements.end()) {

270 const auto &N = *nt;

274 }

275 }

276 }

279}

280

281

282

283

284template <typename Segment, typename Section>

288 uint32_t LoadCommandIndex, const char *CmdName, uint64_t SizeOfHeaders,

289 std::list &Elements) {

290 const unsigned SegmentLoadSize = sizeof(Segment);

291 if (Load.C.cmdsize < SegmentLoadSize)

293 " " + CmdName + " cmdsize too small");

294 if (auto SegOrErr = getStructOrErr(Obj, Load.Ptr)) {

295 Segment S = SegOrErr.get();

296 const unsigned SectionSize = sizeof(Section);

298 if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||

299 S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize)

301 " inconsistent cmdsize in " + CmdName +

302 " for the number of sections");

303 for (unsigned J = 0; J < S.nsects; ++J) {

306 auto SectionOrErr = getStructOrErr

(Obj, Sec);

307 if (!SectionOrErr)

308 return SectionOrErr.takeError();

309 Section s = SectionOrErr.get();

314 s.offset > FileSize)

316 CmdName + " command " + Twine(LoadCommandIndex) +

317 " extends past the end of the file");

322 s.offset < SizeOfHeaders && s.size != 0)

324 CmdName + " command " + Twine(LoadCommandIndex) +

325 " not past the headers of the file");

327 BigSize += s.size;

332 BigSize > FileSize)

333 return malformedError("offset field plus size field of section " +

334 Twine(J) + " in " + CmdName + " command " +

335 Twine(LoadCommandIndex) +

336 " extends past the end of the file");

341 s.size > S.filesize)

343 Twine(J) + " in " + CmdName + " command " +

344 Twine(LoadCommandIndex) +

345 " greater than the segment");

348 s.addr < S.vmaddr)

350 CmdName + " command " + Twine(LoadCommandIndex) +

351 " less than the segment's vmaddr");

352 BigSize = s.addr;

353 BigSize += s.size;

355 BigEnd += S.vmsize;

356 if (S.vmsize != 0 && s.size != 0 && BigSize > BigEnd)

358 " in " + CmdName + " command " +

359 Twine(LoadCommandIndex) +

360 " greater than than "

361 "the segment's vmaddr plus vmsize");

367 "section contents"))

368 return Err;

369 if (s.reloff > FileSize)

371 CmdName + " command " + Twine(LoadCommandIndex) +

372 " extends past the end of the file");

373 BigSize = s.nreloc;

375 BigSize += s.reloff;

376 if (BigSize > FileSize)

377 return malformedError("reloff field plus nreloc field times sizeof("

378 "struct relocation_info) of section " +

379 Twine(J) + " in " + CmdName + " command " +

380 Twine(LoadCommandIndex) +

381 " extends past the end of the file");

383 sizeof(struct

385 "section relocation entries"))

386 return Err;

387 }

388 if (S.fileoff > FileSize)

390 " fileoff field in " + CmdName +

391 " extends past the end of the file");

392 uint64_t BigSize = S.fileoff;

393 BigSize += S.filesize;

394 if (BigSize > FileSize)

396 " fileoff field plus filesize field in " +

397 CmdName + " extends past the end of the file");

398 if (S.vmsize != 0 && S.filesize > S.vmsize)

400 " filesize field in " + CmdName +

401 " greater than vmsize field");

402 IsPageZeroSegment |= StringRef("__PAGEZERO") == S.segname;

403 } else

404 return SegOrErr.takeError();

405

407}

408

412 const char **SymtabLoadCmd,

413 std::list &Elements) {

416 " LC_SYMTAB cmdsize too small");

417 if (*SymtabLoadCmd != nullptr)

418 return malformedError("more than one LC_SYMTAB command");

419 auto SymtabOrErr = getStructOrErrMachO::symtab\_command(Obj, Load.Ptr);

420 if (!SymtabOrErr)

421 return SymtabOrErr.takeError();

425 " has incorrect cmdsize");

427 if (Symtab.symoff > FileSize)

428 return malformedError("symoff field of LC_SYMTAB command " +

429 Twine(LoadCommandIndex) + " extends past the end "

430 "of the file");

432 const char *struct_nlist_name;

435 struct_nlist_name = "struct nlist_64";

436 } else {

438 struct_nlist_name = "struct nlist";

439 }

440 uint64_t BigSize = SymtabSize;

441 BigSize += Symtab.symoff;

442 if (BigSize > FileSize)

443 return malformedError("symoff field plus nsyms field times sizeof(" +

444 Twine(struct_nlist_name) + ") of LC_SYMTAB command " +

445 Twine(LoadCommandIndex) + " extends past the end "

446 "of the file");

448 "symbol table"))

449 return Err;

450 if (Symtab.stroff > FileSize)

451 return malformedError("stroff field of LC_SYMTAB command " +

452 Twine(LoadCommandIndex) + " extends past the end "

453 "of the file");

454 BigSize = Symtab.stroff;

455 BigSize += Symtab.strsize;

456 if (BigSize > FileSize)

457 return malformedError("stroff field plus strsize field of LC_SYMTAB "

458 "command " + Twine(LoadCommandIndex) + " extends "

459 "past the end of the file");

461 Symtab.strsize, "string table"))

462 return Err;

463 *SymtabLoadCmd = Load.Ptr;

465}

466

470 const char **DysymtabLoadCmd,

471 std::list &Elements) {

474 " LC_DYSYMTAB cmdsize too small");

475 if (*DysymtabLoadCmd != nullptr)

476 return malformedError("more than one LC_DYSYMTAB command");

477 auto DysymtabOrErr =

478 getStructOrErrMachO::dysymtab\_command(Obj, Load.Ptr);

479 if (!DysymtabOrErr)

480 return DysymtabOrErr.takeError();

484 " has incorrect cmdsize");

486 if (Dysymtab.tocoff > FileSize)

487 return malformedError("tocoff field of LC_DYSYMTAB command " +

488 Twine(LoadCommandIndex) + " extends past the end of "

489 "the file");

492 BigSize += Dysymtab.tocoff;

493 if (BigSize > FileSize)

494 return malformedError("tocoff field plus ntoc field times sizeof(struct "

495 "dylib_table_of_contents) of LC_DYSYMTAB command " +

496 Twine(LoadCommandIndex) + " extends past the end of "

497 "the file");

499 Dysymtab.ntoc * sizeof(struct

501 "table of contents"))

502 return Err;

503 if (Dysymtab.modtaboff > FileSize)

504 return malformedError("modtaboff field of LC_DYSYMTAB command " +

505 Twine(LoadCommandIndex) + " extends past the end of "

506 "the file");

507 BigSize = Dysymtab.nmodtab;

508 const char *struct_dylib_module_name;

512 struct_dylib_module_name = "struct dylib_module_64";

513 } else {

515 struct_dylib_module_name = "struct dylib_module";

516 }

517 BigSize *= sizeof_modtab;

519 if (BigSize > FileSize)

520 return malformedError("modtaboff field plus nmodtab field times sizeof(" +

521 Twine(struct_dylib_module_name) + ") of LC_DYSYMTAB "

522 "command " + Twine(LoadCommandIndex) + " extends "

523 "past the end of the file");

525 Dysymtab.nmodtab * sizeof_modtab,

526 "module table"))

527 return Err;

529 return malformedError("extrefsymoff field of LC_DYSYMTAB command " +

530 Twine(LoadCommandIndex) + " extends past the end of "

531 "the file");

535 if (BigSize > FileSize)

536 return malformedError("extrefsymoff field plus nextrefsyms field times "

537 "sizeof(struct dylib_reference) of LC_DYSYMTAB "

538 "command " + Twine(LoadCommandIndex) + " extends "

539 "past the end of the file");

543 "reference table"))

544 return Err;

546 return malformedError("indirectsymoff field of LC_DYSYMTAB command " +

547 Twine(LoadCommandIndex) + " extends past the end of "

548 "the file");

552 if (BigSize > FileSize)

553 return malformedError("indirectsymoff field plus nindirectsyms field times "

554 "sizeof(uint32_t) of LC_DYSYMTAB command " +

555 Twine(LoadCommandIndex) + " extends past the end of "

556 "the file");

560 "indirect table"))

561 return Err;

562 if (Dysymtab.extreloff > FileSize)

563 return malformedError("extreloff field of LC_DYSYMTAB command " +

564 Twine(LoadCommandIndex) + " extends past the end of "

565 "the file");

566 BigSize = Dysymtab.nextrel;

569 if (BigSize > FileSize)

570 return malformedError("extreloff field plus nextrel field times sizeof"

571 "(struct relocation_info) of LC_DYSYMTAB command " +

572 Twine(LoadCommandIndex) + " extends past the end of "

573 "the file");

577 "external relocation table"))

578 return Err;

579 if (Dysymtab.locreloff > FileSize)

580 return malformedError("locreloff field of LC_DYSYMTAB command " +

581 Twine(LoadCommandIndex) + " extends past the end of "

582 "the file");

583 BigSize = Dysymtab.nlocrel;

586 if (BigSize > FileSize)

587 return malformedError("locreloff field plus nlocrel field times sizeof"

588 "(struct relocation_info) of LC_DYSYMTAB command " +

589 Twine(LoadCommandIndex) + " extends past the end of "

590 "the file");

594 "local relocation table"))

595 return Err;

596 *DysymtabLoadCmd = Load.Ptr;

598}

599

603 const char **LoadCmd, const char *CmdName,

604 std::list &Elements,

605 const char *ElementName) {

608 CmdName + " cmdsize too small");

609 if (*LoadCmd != nullptr)

611 auto LinkDataOrError =

612 getStructOrErrMachO::linkedit\_data\_command(Obj, Load.Ptr);

613 if (!LinkDataOrError)

614 return LinkDataOrError.takeError();

618 Twine(LoadCommandIndex) + " has incorrect cmdsize");

620 if (LinkData.dataoff > FileSize)

621 return malformedError("dataoff field of " + Twine(CmdName) + " command " +

622 Twine(LoadCommandIndex) + " extends past the end of "

623 "the file");

625 BigSize += LinkData.datasize;

626 if (BigSize > FileSize)

627 return malformedError("dataoff field plus datasize field of " +

628 Twine(CmdName) + " command " +

629 Twine(LoadCommandIndex) + " extends past the end of "

630 "the file");

632 LinkData.datasize, ElementName))

633 return Err;

634 *LoadCmd = Load.Ptr;

636}

637

641 const char **LoadCmd, const char *CmdName,

642 std::list &Elements) {

645 CmdName + " cmdsize too small");

646 if (*LoadCmd != nullptr)

647 return malformedError("more than one LC_DYLD_INFO and or LC_DYLD_INFO_ONLY "

648 "command");

649 auto DyldInfoOrErr =

650 getStructOrErrMachO::dyld\_info\_command(Obj, Load.Ptr);

651 if (!DyldInfoOrErr)

652 return DyldInfoOrErr.takeError();

656 Twine(LoadCommandIndex) + " has incorrect cmdsize");

660 " command " + Twine(LoadCommandIndex) + " extends "

661 "past the end of the file");

664 if (BigSize > FileSize)

665 return malformedError("rebase_off field plus rebase_size field of " +

666 Twine(CmdName) + " command " +

667 Twine(LoadCommandIndex) + " extends past the end of "

668 "the file");

671 "dyld rebase info"))

672 return Err;

673 if (DyldInfo.bind_off > FileSize)

675 " command " + Twine(LoadCommandIndex) + " extends "

676 "past the end of the file");

679 if (BigSize > FileSize)

680 return malformedError("bind_off field plus bind_size field of " +

681 Twine(CmdName) + " command " +

682 Twine(LoadCommandIndex) + " extends past the end of "

683 "the file");

686 "dyld bind info"))

687 return Err;

690 " command " + Twine(LoadCommandIndex) + " extends "

691 "past the end of the file");

694 if (BigSize > FileSize)

695 return malformedError("weak_bind_off field plus weak_bind_size field of " +

696 Twine(CmdName) + " command " +

697 Twine(LoadCommandIndex) + " extends past the end of "

698 "the file");

701 "dyld weak bind info"))

702 return Err;

705 " command " + Twine(LoadCommandIndex) + " extends "

706 "past the end of the file");

709 if (BigSize > FileSize)

710 return malformedError("lazy_bind_off field plus lazy_bind_size field of " +

711 Twine(CmdName) + " command " +

712 Twine(LoadCommandIndex) + " extends past the end of "

713 "the file");

716 "dyld lazy bind info"))

717 return Err;

720 " command " + Twine(LoadCommandIndex) + " extends "

721 "past the end of the file");

724 if (BigSize > FileSize)

725 return malformedError("export_off field plus export_size field of " +

726 Twine(CmdName) + " command " +

727 Twine(LoadCommandIndex) + " extends past the end of "

728 "the file");

731 "dyld export info"))

732 return Err;

733 *LoadCmd = Load.Ptr;

735}

736

739 uint32_t LoadCommandIndex, const char *CmdName) {

742 CmdName + " cmdsize too small");

743 auto CommandOrErr = getStructOrErrMachO::dylib\_command(Obj, Load.Ptr);

744 if (!CommandOrErr)

745 return CommandOrErr.takeError();

749 CmdName + " name.offset field too small, not past "

750 "the end of the dylib_command struct");

751 if (D.dylib.name >= D.cmdsize)

753 CmdName + " name.offset field extends past the end "

754 "of the load command");

755

756

758 const char *P = (const char *)Load.Ptr;

759 for (i = D.dylib.name; i < D.cmdsize; i++)

760 if (P[i] == '\0')

761 break;

762 if (i >= D.cmdsize)

764 CmdName + " library name extends past the end of the "

765 "load command");

767}

768

772 const char **LoadCmd) {

774 "LC_ID_DYLIB"))

775 return Err;

776 if (*LoadCmd != nullptr)

777 return malformedError("more than one LC_ID_DYLIB command");

780 return malformedError("LC_ID_DYLIB load command in non-dynamic library "

781 "file type");

782 *LoadCmd = Load.Ptr;

784}

785

788 uint32_t LoadCommandIndex, const char *CmdName) {

791 CmdName + " cmdsize too small");

792 auto CommandOrErr = getStructOrErrMachO::dylinker\_command(Obj, Load.Ptr);

793 if (!CommandOrErr)

794 return CommandOrErr.takeError();

798 CmdName + " name.offset field too small, not past "

799 "the end of the dylinker_command struct");

800 if (D.name >= D.cmdsize)

802 CmdName + " name.offset field extends past the end "

803 "of the load command");

804

805

807 const char *P = (const char *)Load.Ptr;

808 for (i = D.name; i < D.cmdsize; i++)

809 if (P[i] == '\0')

810 break;

811 if (i >= D.cmdsize)

813 CmdName + " dyld name extends past the end of the "

814 "load command");

816}

817

821 const char **LoadCmd, const char *CmdName) {

824 CmdName + " has incorrect cmdsize");

825 if (*LoadCmd != nullptr)

826 return malformedError("more than one LC_VERSION_MIN_MACOSX, "

827 "LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS or "

828 "LC_VERSION_MIN_WATCHOS command");

829 *LoadCmd = Load.Ptr;

831}

832

836 std::list &Elements) {

839 " LC_NOTE has incorrect cmdsize");

840 auto NoteCmdOrErr = getStructOrErrMachO::note\_command(Obj, Load.Ptr);

841 if (!NoteCmdOrErr)

842 return NoteCmdOrErr.takeError();

845 if (Nt.offset > FileSize)

846 return malformedError("offset field of LC_NOTE command " +

847 Twine(LoadCommandIndex) + " extends "

848 "past the end of the file");

850 BigSize += Nt.size;

851 if (BigSize > FileSize)

852 return malformedError("size field plus offset field of LC_NOTE command " +

853 Twine(LoadCommandIndex) + " extends past the end of "

854 "the file");

856 "LC_NOTE data"))

857 return Err;

859}

860

866 auto BVCOrErr =

867 getStructOrErrMachO::build\_version\_command(Obj, Load.Ptr);

868 if (!BVCOrErr)

869 return BVCOrErr.takeError();

871 if (Load.C.cmdsize !=

875 " LC_BUILD_VERSION_COMMAND has incorrect cmdsize");

876

879 for (unsigned i = 0; i < BVC.ntools; ++i)

881

883}

884

890 " LC_RPATH cmdsize too small");

891 auto ROrErr = getStructOrErrMachO::rpath\_command(Obj, Load.Ptr);

892 if (!ROrErr)

893 return ROrErr.takeError();

897 " LC_RPATH path.offset field too small, not past "

898 "the end of the rpath_command struct");

899 if (R.path >= R.cmdsize)

901 " LC_RPATH path.offset field extends past the end "

902 "of the load command");

903

904

906 const char *P = (const char *)Load.Ptr;

907 for (i = R.path; i < R.cmdsize; i++)

908 if (P[i] == '\0')

909 break;

910 if (i >= R.cmdsize)

912 " LC_RPATH library name extends past the end of the "

913 "load command");

915}

916

921 const char **LoadCmd, const char *CmdName) {

922 if (*LoadCmd != nullptr)

923 return malformedError("more than one LC_ENCRYPTION_INFO and or "

924 "LC_ENCRYPTION_INFO_64 command");

926 if (cryptoff > FileSize)

928 " command " + Twine(LoadCommandIndex) + " extends "

929 "past the end of the file");

931 BigSize += cryptsize;

932 if (BigSize > FileSize)

933 return malformedError("cryptoff field plus cryptsize field of " +

934 Twine(CmdName) + " command " +

935 Twine(LoadCommandIndex) + " extends past the end of "

936 "the file");

937 *LoadCmd = Load.Ptr;

939}

940

946 " LC_LINKER_OPTION cmdsize too small");

947 auto LinkOptionOrErr =

948 getStructOrErrMachO::linker\_option\_command(Obj, Load.Ptr);

949 if (!LinkOptionOrErr)

950 return LinkOptionOrErr.takeError();

952

953 const char *string = (const char *)Load.Ptr +

957 while (left > 0) {

958 while (*string == '\0' && left > 0) {

959 string++;

960 left--;

961 }

962 if (left > 0) {

963 i++;

965 if (0xffffffff == NullPos)

967 " LC_LINKER_OPTION string #" + Twine(i) +

968 " is not NULL terminated");

969 uint32_t len = std::min(NullPos, left) + 1;

970 string += len;

971 left -= len;

972 }

973 }

974 if (L.count != i)

976 " LC_LINKER_OPTION string count " + Twine(L.count) +

977 " does not match number of strings");

979}

980

983 uint32_t LoadCommandIndex, const char *CmdName,

984 size_t SizeOfCmd, const char *CmdStructName,

985 uint32_t PathOffset, const char *PathFieldName) {

986 if (PathOffset < SizeOfCmd)

988 CmdName + " " + PathFieldName + ".offset field too "

989 "small, not past the end of the " + CmdStructName);

990 if (PathOffset >= Load.C.cmdsize)

992 CmdName + " " + PathFieldName + ".offset field "

993 "extends past the end of the load command");

994

995

997 const char *P = (const char *)Load.Ptr;

998 for (i = PathOffset; i < Load.C.cmdsize; i++)

999 if (P[i] == '\0')

1000 break;

1001 if (i >= Load.C.cmdsize)

1003 CmdName + " " + PathFieldName + " name extends past "

1004 "the end of the load command");

1006}

1007

1011 const char *CmdName) {

1014 CmdName + " cmdsize too small");

1015 auto ThreadCommandOrErr =

1016 getStructOrErrMachO::thread\_command(Obj, Load.Ptr);

1017 if (!ThreadCommandOrErr)

1018 return ThreadCommandOrErr.takeError();

1021 const char *end = Load.Ptr + T.cmdsize;

1024 while (state < end) {

1025 if(state + sizeof(uint32_t) > end)

1027 "flavor in " + CmdName + " extends past end of "

1028 "command");

1030 memcpy(&flavor, state, sizeof(uint32_t));

1034

1035 if(state + sizeof(uint32_t) > end)

1037 " count in " + CmdName + " extends past end of "

1038 "command");

1044

1049 " count not x86_THREAD_STATE32_COUNT for "

1050 "flavor number " + Twine(nflavor) + " which is "

1051 "a x86_THREAD_STATE32 flavor in " + CmdName +

1052 " command");

1055 " x86_THREAD_STATE32 extends past end of "

1056 "command in " + CmdName + " command");

1058 } else {

1060 " unknown flavor (" + Twine(flavor) + ") for "

1061 "flavor number " + Twine(nflavor) + " in " +

1062 CmdName + " command");

1063 }

1068 " count not x86_THREAD_STATE_COUNT for "

1069 "flavor number " + Twine(nflavor) + " which is "

1070 "a x86_THREAD_STATE flavor in " + CmdName +

1071 " command");

1074 " x86_THREAD_STATE extends past end of "

1075 "command in " + CmdName + " command");

1080 " count not x86_FLOAT_STATE_COUNT for "

1081 "flavor number " + Twine(nflavor) + " which is "

1082 "a x86_FLOAT_STATE flavor in " + CmdName +

1083 " command");

1086 " x86_FLOAT_STATE extends past end of "

1087 "command in " + CmdName + " command");

1092 " count not x86_EXCEPTION_STATE_COUNT for "

1093 "flavor number " + Twine(nflavor) + " which is "

1094 "a x86_EXCEPTION_STATE flavor in " + CmdName +

1095 " command");

1098 " x86_EXCEPTION_STATE extends past end of "

1099 "command in " + CmdName + " command");

1104 " count not x86_THREAD_STATE64_COUNT for "

1105 "flavor number " + Twine(nflavor) + " which is "

1106 "a x86_THREAD_STATE64 flavor in " + CmdName +

1107 " command");

1110 " x86_THREAD_STATE64 extends past end of "

1111 "command in " + CmdName + " command");

1116 " count not x86_EXCEPTION_STATE64_COUNT for "

1117 "flavor number " + Twine(nflavor) + " which is "

1118 "a x86_EXCEPTION_STATE64 flavor in " + CmdName +

1119 " command");

1122 " x86_EXCEPTION_STATE64 extends past end of "

1123 "command in " + CmdName + " command");

1125 } else {

1127 " unknown flavor (" + Twine(flavor) + ") for "

1128 "flavor number " + Twine(nflavor) + " in " +

1129 CmdName + " command");

1130 }

1135 " count not ARM_THREAD_STATE_COUNT for "

1136 "flavor number " + Twine(nflavor) + " which is "

1137 "a ARM_THREAD_STATE flavor in " + CmdName +

1138 " command");

1141 " ARM_THREAD_STATE extends past end of "

1142 "command in " + CmdName + " command");

1144 } else {

1146 " unknown flavor (" + Twine(flavor) + ") for "

1147 "flavor number " + Twine(nflavor) + " in " +

1148 CmdName + " command");

1149 }

1155 " count not ARM_THREAD_STATE64_COUNT for "

1156 "flavor number " + Twine(nflavor) + " which is "

1157 "a ARM_THREAD_STATE64 flavor in " + CmdName +

1158 " command");

1161 " ARM_THREAD_STATE64 extends past end of "

1162 "command in " + CmdName + " command");

1164 } else {

1166 " unknown flavor (" + Twine(flavor) + ") for "

1167 "flavor number " + Twine(nflavor) + " in " +

1168 CmdName + " command");

1169 }

1174 " count not PPC_THREAD_STATE_COUNT for "

1175 "flavor number " + Twine(nflavor) + " which is "

1176 "a PPC_THREAD_STATE flavor in " + CmdName +

1177 " command");

1180 " PPC_THREAD_STATE extends past end of "

1181 "command in " + CmdName + " command");

1183 } else {

1185 " unknown flavor (" + Twine(flavor) + ") for "

1186 "flavor number " + Twine(nflavor) + " in " +

1187 CmdName + " command");

1188 }

1189 } else {

1191 "command " + Twine(LoadCommandIndex) + " for " +

1192 CmdName + " command can't be checked");

1193 }

1194 nflavor++;

1195 }

1197}

1198

1201 &Load,

1203 const char **LoadCmd,

1204 std::list &Elements) {

1207 " LC_TWOLEVEL_HINTS has incorrect cmdsize");

1208 if (*LoadCmd != nullptr)

1209 return malformedError("more than one LC_TWOLEVEL_HINTS command");

1210 auto HintsOrErr = getStructOrErrMachO::twolevel\_hints\_command(Obj, Load.Ptr);

1211 if(!HintsOrErr)

1212 return HintsOrErr.takeError();

1215 if (Hints.offset > FileSize)

1216 return malformedError("offset field of LC_TWOLEVEL_HINTS command " +

1217 Twine(LoadCommandIndex) + " extends past the end of "

1218 "the file");

1221 BigSize += Hints.offset;

1222 if (BigSize > FileSize)

1223 return malformedError("offset field plus nhints times sizeof(struct "

1224 "twolevel_hint) field of LC_TWOLEVEL_HINTS command " +

1225 Twine(LoadCommandIndex) + " extends past the end of "

1226 "the file");

1229 "two level hints"))

1230 return Err;

1231 *LoadCmd = Load.Ptr;

1233}

1234

1235

1236

1237

1239 if (cmd == MachO::LC_SYMSEG ||

1240 cmd == MachO::LC_LOADFVMLIB ||

1241 cmd == MachO::LC_IDFVMLIB ||

1242 cmd == MachO::LC_IDENT ||

1243 cmd == MachO::LC_FVMFILE ||

1244 cmd == MachO::LC_PREPAGE ||

1245 cmd == MachO::LC_PREBOUND_DYLIB ||

1246 cmd == MachO::LC_TWOLEVEL_HINTS ||

1247 cmd == MachO::LC_PREBIND_CKSUM)

1248 return true;

1249 return false;

1250}

1251

1254 bool Is64Bits, uint32_t UniversalCputype,

1256 size_t MachOFilesetEntryOffset) {

1258 std::unique_ptr Obj(new MachOObjectFile(

1259 std::move(Object), IsLittleEndian, Is64Bits, Err, UniversalCputype,

1260 UniversalIndex, MachOFilesetEntryOffset));

1261 if (Err)

1262 return std::move(Err);

1263 return std::move(Obj);

1264}

1265

1266MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,

1267 bool Is64bits, Error &Err,

1270 size_t MachOFilesetEntryOffset)

1271 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),

1272 MachOFilesetEntryOffset(MachOFilesetEntryOffset) {

1280 } else {

1284 }

1285 if (Err)

1286 return;

1289 Err = malformedError("load commands extend past the end of the file");

1290 return;

1291 }

1292 if (UniversalCputype != 0 && cputype != UniversalCputype) {

1293 Err = malformedError("universal header architecture: " +

1294 Twine(UniversalIndex) + "'s cputype does not match "

1295 "object file's mach header");

1296 return;

1297 }

1298 std::list Elements;

1299 Elements.push_back({0, SizeOfHeaders, "Mach-O headers"});

1300

1302 LoadCommandInfo Load;

1303 if (LoadCommandCount != 0) {

1305 Load = *LoadOrErr;

1306 else {

1307 Err = LoadOrErr.takeError();

1308 return;

1309 }

1310 }

1311

1312 const char *DyldIdLoadCmd = nullptr;

1313 const char *SplitInfoLoadCmd = nullptr;

1314 const char *CodeSignDrsLoadCmd = nullptr;

1315 const char *CodeSignLoadCmd = nullptr;

1316 const char *VersLoadCmd = nullptr;

1317 const char *SourceLoadCmd = nullptr;

1318 const char *EntryPointLoadCmd = nullptr;

1319 const char *EncryptLoadCmd = nullptr;

1320 const char *RoutinesLoadCmd = nullptr;

1321 const char *UnixThreadLoadCmd = nullptr;

1322 const char *TwoLevelHintsLoadCmd = nullptr;

1323 for (unsigned I = 0; I < LoadCommandCount; ++I) {

1325 if (Load.C.cmdsize % 8 != 0) {

1326

1327

1328

1330 Load.C.cmd != MachO::LC_THREAD || Load.C.cmdsize % 4) {

1332 "multiple of 8");

1333 return;

1334 }

1335 }

1336 } else {

1337 if (Load.C.cmdsize % 4 != 0) {

1339 "multiple of 4");

1340 return;

1341 }

1342 }

1344 if (Load.C.cmd == MachO::LC_SYMTAB) {

1345 if ((Err = checkSymtabCommand(*this, Load, I, &SymtabLoadCmd, Elements)))

1346 return;

1347 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {

1349 Elements)))

1350 return;

1351 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {

1353 "LC_DATA_IN_CODE", Elements,

1354 "data in code info")))

1355 return;

1356 } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {

1358 "LC_LINKER_OPTIMIZATION_HINT",

1359 Elements, "linker optimization "

1360 "hints")))

1361 return;

1362 } else if (Load.C.cmd == MachO::LC_FUNCTION_STARTS) {

1364 "LC_FUNCTION_STARTS", Elements,

1365 "function starts data")))

1366 return;

1367 } else if (Load.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO) {

1369 "LC_SEGMENT_SPLIT_INFO", Elements,

1370 "split info data")))

1371 return;

1372 } else if (Load.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) {

1374 "LC_DYLIB_CODE_SIGN_DRS", Elements,

1375 "code signing RDs data")))

1376 return;

1377 } else if (Load.C.cmd == MachO::LC_CODE_SIGNATURE) {

1379 "LC_CODE_SIGNATURE", Elements,

1380 "code signature data")))

1381 return;

1382 } else if (Load.C.cmd == MachO::LC_DYLD_INFO) {

1384 "LC_DYLD_INFO", Elements)))

1385 return;

1386 } else if (Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {

1388 "LC_DYLD_INFO_ONLY", Elements)))

1389 return;

1390 } else if (Load.C.cmd == MachO::LC_DYLD_CHAINED_FIXUPS) {

1392 *this, Load, I, &DyldChainedFixupsLoadCmd,

1393 "LC_DYLD_CHAINED_FIXUPS", Elements, "chained fixups")))

1394 return;

1395 } else if (Load.C.cmd == MachO::LC_DYLD_EXPORTS_TRIE) {

1397 *this, Load, I, &DyldExportsTrieLoadCmd, "LC_DYLD_EXPORTS_TRIE",

1398 Elements, "exports trie")))

1399 return;

1400 } else if (Load.C.cmd == MachO::LC_UUID) {

1403 "cmdsize");

1404 return;

1405 }

1406 if (UuidLoadCmd) {

1407 Err = malformedError("more than one LC_UUID command");

1408 return;

1409 }

1410 UuidLoadCmd = Load.Ptr;

1411 } else if (Load.C.cmd == MachO::LC_SEGMENT_64) {

1414 *this, Load, Sections, HasPageZeroSegment, I,

1415 "LC_SEGMENT_64", SizeOfHeaders, Elements)))

1416 return;

1417 } else if (Load.C.cmd == MachO::LC_SEGMENT) {

1420 *this, Load, Sections, HasPageZeroSegment, I,

1421 "LC_SEGMENT", SizeOfHeaders, Elements)))

1422 return;

1423 } else if (Load.C.cmd == MachO::LC_ID_DYLIB) {

1425 return;

1426 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB) {

1428 return;

1430 } else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) {

1431 if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_WEAK_DYLIB")))

1432 return;

1434 } else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) {

1435 if ((Err = checkDylibCommand(*this, Load, I, "LC_LAZY_LOAD_DYLIB")))

1436 return;

1438 } else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB) {

1440 return;

1442 } else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {

1443 if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_UPWARD_DYLIB")))

1444 return;

1446 } else if (Load.C.cmd == MachO::LC_ID_DYLINKER) {

1448 return;

1449 } else if (Load.C.cmd == MachO::LC_LOAD_DYLINKER) {

1450 if ((Err = checkDyldCommand(*this, Load, I, "LC_LOAD_DYLINKER")))

1451 return;

1452 } else if (Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {

1453 if ((Err = checkDyldCommand(*this, Load, I, "LC_DYLD_ENVIRONMENT")))

1454 return;

1455 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {

1457 "LC_VERSION_MIN_MACOSX")))

1458 return;

1459 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {

1461 "LC_VERSION_MIN_IPHONEOS")))

1462 return;

1463 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) {

1465 "LC_VERSION_MIN_TVOS")))

1466 return;

1467 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {

1469 "LC_VERSION_MIN_WATCHOS")))

1470 return;

1471 } else if (Load.C.cmd == MachO::LC_NOTE) {

1473 return;

1474 } else if (Load.C.cmd == MachO::LC_BUILD_VERSION) {

1476 return;

1477 } else if (Load.C.cmd == MachO::LC_RPATH) {

1479 return;

1480 } else if (Load.C.cmd == MachO::LC_SOURCE_VERSION) {

1483 " has incorrect cmdsize");

1484 return;

1485 }

1486 if (SourceLoadCmd) {

1487 Err = malformedError("more than one LC_SOURCE_VERSION command");

1488 return;

1489 }

1490 SourceLoadCmd = Load.Ptr;

1491 } else if (Load.C.cmd == MachO::LC_MAIN) {

1494 " has incorrect cmdsize");

1495 return;

1496 }

1497 if (EntryPointLoadCmd) {

1498 Err = malformedError("more than one LC_MAIN command");

1499 return;

1500 }

1501 EntryPointLoadCmd = Load.Ptr;

1502 } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO) {

1505 " has incorrect cmdsize");

1506 return;

1507 }

1509 getStructMachO::encryption\_info\_command(*this, Load.Ptr);

1511 &EncryptLoadCmd, "LC_ENCRYPTION_INFO")))

1512 return;

1513 } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {

1516 " has incorrect cmdsize");

1517 return;

1518 }

1520 getStructMachO::encryption\_info\_command\_64(*this, Load.Ptr);

1522 &EncryptLoadCmd, "LC_ENCRYPTION_INFO_64")))

1523 return;

1524 } else if (Load.C.cmd == MachO::LC_LINKER_OPTION) {

1526 return;

1527 } else if (Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {

1530 " LC_SUB_FRAMEWORK cmdsize too small");

1531 return;

1532 }

1534 getStructMachO::sub\_framework\_command(*this, Load.Ptr);

1535 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_FRAMEWORK",

1537 "sub_framework_command", S.umbrella,

1538 "umbrella")))

1539 return;

1540 } else if (Load.C.cmd == MachO::LC_SUB_UMBRELLA) {

1543 " LC_SUB_UMBRELLA cmdsize too small");

1544 return;

1545 }

1547 getStructMachO::sub\_umbrella\_command(*this, Load.Ptr);

1548 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_UMBRELLA",

1551 "sub_umbrella")))

1552 return;

1553 } else if (Load.C.cmd == MachO::LC_SUB_LIBRARY) {

1556 " LC_SUB_LIBRARY cmdsize too small");

1557 return;

1558 }

1560 getStructMachO::sub\_library\_command(*this, Load.Ptr);

1561 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_LIBRARY",

1564 "sub_library")))

1565 return;

1566 } else if (Load.C.cmd == MachO::LC_SUB_CLIENT) {

1569 " LC_SUB_CLIENT cmdsize too small");

1570 return;

1571 }

1573 getStructMachO::sub\_client\_command(*this, Load.Ptr);

1576 "sub_client_command", S.client, "client")))

1577 return;

1578 } else if (Load.C.cmd == MachO::LC_ROUTINES) {

1581 " has incorrect cmdsize");

1582 return;

1583 }

1584 if (RoutinesLoadCmd) {

1585 Err = malformedError("more than one LC_ROUTINES and or LC_ROUTINES_64 "

1586 "command");

1587 return;

1588 }

1589 RoutinesLoadCmd = Load.Ptr;

1590 } else if (Load.C.cmd == MachO::LC_ROUTINES_64) {

1593 " has incorrect cmdsize");

1594 return;

1595 }

1596 if (RoutinesLoadCmd) {

1597 Err = malformedError("more than one LC_ROUTINES_64 and or LC_ROUTINES "

1598 "command");

1599 return;

1600 }

1601 RoutinesLoadCmd = Load.Ptr;

1602 } else if (Load.C.cmd == MachO::LC_UNIXTHREAD) {

1604 return;

1605 if (UnixThreadLoadCmd) {

1606 Err = malformedError("more than one LC_UNIXTHREAD command");

1607 return;

1608 }

1609 UnixThreadLoadCmd = Load.Ptr;

1610 } else if (Load.C.cmd == MachO::LC_THREAD) {

1612 return;

1613

1614 } else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {

1616 &TwoLevelHintsLoadCmd, Elements)))

1617 return;

1618 } else if (Load.C.cmd == MachO::LC_IDENT) {

1619

1620 continue;

1623 Twine(Load.C.cmd) + " is obsolete and not "

1624 "supported");

1625 return;

1626 }

1627

1628

1629

1630 if (I < LoadCommandCount - 1) {

1632 Load = *LoadOrErr;

1633 else {

1634 Err = LoadOrErr.takeError();

1635 return;

1636 }

1637 }

1638 }

1639 if (!SymtabLoadCmd) {

1640 if (DysymtabLoadCmd) {

1641 Err = malformedError("contains LC_DYSYMTAB load command without a "

1642 "LC_SYMTAB load command");

1643 return;

1644 }

1645 } else if (DysymtabLoadCmd) {

1647 getStructMachO::symtab\_command(*this, SymtabLoadCmd);

1649 getStructMachO::dysymtab\_command(*this, DysymtabLoadCmd);

1651 Err = malformedError("ilocalsym in LC_DYSYMTAB load command "

1652 "extends past the end of the symbol table");

1653 return;

1654 }

1657 if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.nsyms) {

1658 Err = malformedError("ilocalsym plus nlocalsym in LC_DYSYMTAB load "

1659 "command extends past the end of the symbol table");

1660 return;

1661 }

1663 Err = malformedError("iextdefsym in LC_DYSYMTAB load command "

1664 "extends past the end of the symbol table");

1665 return;

1666 }

1669 if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.nsyms) {

1670 Err = malformedError("iextdefsym plus nextdefsym in LC_DYSYMTAB "

1671 "load command extends past the end of the symbol "

1672 "table");

1673 return;

1674 }

1676 Err = malformedError("iundefsym in LC_DYSYMTAB load command "

1677 "extends past the end of the symbol table");

1678 return;

1679 }

1682 if (Dysymtab.nundefsym != 0 && BigSize > Symtab.nsyms) {

1683 Err = malformedError("iundefsym plus nundefsym in LC_DYSYMTAB load "

1684 " command extends past the end of the symbol table");

1685 return;

1686 }

1687 }

1690 DyldIdLoadCmd == nullptr) {

1691 Err = malformedError("no LC_ID_DYLIB load command in dynamic library "

1692 "filetype");

1693 return;

1694 }

1695 assert(LoadCommands.size() == LoadCommandCount);

1696

1698}

1699

1704 Flags = H_64.flags;

1705 } else {

1707 Flags = H.flags;

1708 }

1717 DataRefImpl SymDRI = Symbol.getRawDataRefImpl();

1720 NType = STE_64.n_type;

1721 NSect = STE_64.n_sect;

1722 NDesc = STE_64.n_desc;

1723 NStrx = STE_64.n_strx;

1724 NValue = STE_64.n_value;

1725 } else {

1732 }

1735 if (NSect == 0 || NSect > Sections.size())

1737 " for symbol at index " + Twine(SymbolIndex));

1738 }

1740 if (NValue >= S.strsize)

1742 "the end of string table, for N_INDR symbol at "

1743 "index " + Twine(SymbolIndex));

1744 }

1749 if (LibraryOrdinal != 0 &&

1752 LibraryOrdinal - 1 >= Libraries.size() ) {

1754 " for symbol at index " + Twine(SymbolIndex));

1755 }

1756 }

1757 }

1760 " past the end of string table, for symbol at "

1761 "index " + Twine(SymbolIndex));

1762 SymbolIndex++;

1763 }

1765}

1766

1772}

1773

1777 if (Entry.n_strx == 0)

1778

1779

1781 const char *Start = &StringTable.data()[Entry.n_strx];

1782 if (Start < getData().begin() || Start >= getData().end()) {

1785 }

1787}

1788

1793}

1794

1798 return Entry.n_value;

1799 }

1801 return Entry.n_value;

1802}

1803

1804

1805

1815 const char *Start = &StringTable.data()[NValue];

1817 return std::error_code();

1818}

1819

1822}

1823

1826}

1827

1833 }

1834 return 0;

1835}

1836

1839}

1840

1844 uint8_t n_type = Entry.n_type;

1845

1846

1849

1855 if (!SecOrError)

1863 }

1865}

1866

1869

1870 uint8_t MachOType = Entry.n_type;

1871 uint16_t MachOFlags = Entry.n_desc;

1872

1874

1877

1880

1886 else

1888 }

1889

1892 else

1894

1897

1900

1903

1906

1907 return Result;

1908}

1909

1913 uint8_t index = Entry.n_sect;

1914

1915 if (index == 0)

1918 DRI.d.a = index - 1;

1919 if (DRI.d.a >= Sections.size()){

1922 }

1924}

1925

1929 return Entry.n_sect - 1;

1930}

1931

1933 Sec.d.a++;

1934}

1935

1939}

1940

1945}

1946

1948 return Sec.d.a;

1949}

1950

1952

1953

1954

1955

1956 uint32_t SectOffset, SectType;

1958

1961 SectOffset = Sect.offset;

1962 SectSize = Sect.size;

1964 } else {

1966 SectOffset = Sect.offset;

1967 SectSize = Sect.size;

1969 }

1971 return SectSize;

1973 if (SectOffset > FileSize)

1974 return 0;

1975 if (FileSize - SectOffset < SectSize)

1976 return FileSize - SectOffset;

1977 return SectSize;

1978}

1979

1983}

1984

1989

1994 } else {

1998 }

1999

2001}

2002

2008 } else {

2011 }

2012

2014}

2015

2017 if (SectionIndex < 1 || SectionIndex > Sections.size())

2018 return malformedError("bad section index: " + Twine((int)SectionIndex));

2019

2021 DRI.d.a = SectionIndex - 1;

2023}

2024

2027 auto NameOrErr = Section.getName();

2028 if (!NameOrErr)

2029 return NameOrErr.takeError();

2031 return Section;

2032 }

2034}

2035

2037 return false;

2038}

2039

2043}

2044

2051}

2052

2059}

2060

2063 if (!SectionNameOrErr) {

2064

2066 return false;

2067 }

2069 return SectionName.starts_with("__debug") ||

2073}

2074

2075namespace {

2076template

2080 auto SegmentOrErr = getStructOrErr(Obj, LoadCmd.Ptr);

2081 if (!SegmentOrErr) {

2083 return {};

2084 }

2085 auto &Segment = SegmentOrErr.get();

2087 return arrayRefFromStringRef(Obj.getData().slice(

2088 Segment.fileoff, Segment.fileoff + Segment.filesize));

2089 return {};

2090}

2091

2092template

2095 auto SegmentOrErr = getStructOrErr(Obj, LoadCmd.Ptr);

2096 if (!SegmentOrErr) {

2098 return {};

2099 }

2100 auto &Segment = SegmentOrErr.get();

2101 return arrayRefFromStringRef(

2102 Obj.getData().substr(Segment.fileoff, Segment.filesize));

2103}

2104}

2105

2110 switch (LoadCmd.C.cmd) {

2111 case MachO::LC_SEGMENT:

2112 Contents = ::getSegmentContentsMachO::segment\_command(*this, LoadCmd,

2113 SegmentName);

2114 break;

2115 case MachO::LC_SEGMENT_64:

2116 Contents = ::getSegmentContentsMachO::segment\_command\_64(*this, LoadCmd,

2117 SegmentName);

2118 break;

2119 default:

2120 continue;

2121 }

2122 if (!Contents.empty())

2123 return Contents;

2124 }

2125 return {};

2126}

2127

2130 size_t Idx = 0;

2132 switch (LoadCmd.C.cmd) {

2133 case MachO::LC_SEGMENT:

2134 if (Idx == SegmentIndex)

2135 return ::getSegmentContentsMachO::segment\_command(*this, LoadCmd);

2137 break;

2138 case MachO::LC_SEGMENT_64:

2139 if (Idx == SegmentIndex)

2140 return ::getSegmentContentsMachO::segment\_command\_64(*this, LoadCmd);

2142 break;

2143 default:

2144 continue;

2145 }

2146 }

2147 return {};

2148}

2149

2152}

2153

2159}

2160

2164 return (SegmentName == "__LLVM" && *NameOrErr == "__bitcode");

2165 return false;

2166}

2167

2172}

2173

2176 Ret.d.a = Sec.d.a;

2177 Ret.d.b = 0;

2179}

2180

2187 } else {

2190 }

2191

2193 Ret.d.a = Sec.d.a;

2194 Ret.d.b = Num;

2196}

2197

2200

2201 Ret.d.a = 0;

2202 Ret.d.b = 0;

2204}

2205

2209

2210 Ret.d.a = 0;

2211 Ret.d.b = DysymtabLoadCmd.nextrel;

2213}

2214

2217

2218 Ret.d.a = 1;

2219 Ret.d.b = 0;

2221}

2222

2226

2227 Ret.d.a = 1;

2228 Ret.d.b = DysymtabLoadCmd.nlocrel;

2230}

2231

2233 ++Rel.d.b;

2234}

2235

2239 "Only implemented for MH_OBJECT && MH_KEXT_BUNDLE");

2242}

2243

2249

2252 if (!isExtern)

2254

2261 Sym.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));

2263}

2264

2268}

2269

2273}

2274

2279

2280 unsigned Arch = this->getArch();

2281

2282 switch (Arch) {

2284 static const char *const Table[] = {

2285 "GENERIC_RELOC_VANILLA",

2286 "GENERIC_RELOC_PAIR",

2287 "GENERIC_RELOC_SECTDIFF",

2288 "GENERIC_RELOC_PB_LA_PTR",

2289 "GENERIC_RELOC_LOCAL_SECTDIFF",

2290 "GENERIC_RELOC_TLV" };

2291

2292 if (RType > 5)

2293 res = "Unknown";

2294 else

2295 res = Table[RType];

2296 break;

2297 }

2299 static const char *const Table[] = {

2300 "X86_64_RELOC_UNSIGNED",

2301 "X86_64_RELOC_SIGNED",

2302 "X86_64_RELOC_BRANCH",

2303 "X86_64_RELOC_GOT_LOAD",

2304 "X86_64_RELOC_GOT",

2305 "X86_64_RELOC_SUBTRACTOR",

2306 "X86_64_RELOC_SIGNED_1",

2307 "X86_64_RELOC_SIGNED_2",

2308 "X86_64_RELOC_SIGNED_4",

2309 "X86_64_RELOC_TLV" };

2310

2311 if (RType > 9)

2312 res = "Unknown";

2313 else

2314 res = Table[RType];

2315 break;

2316 }

2318 static const char *const Table[] = {

2319 "ARM_RELOC_VANILLA",

2320 "ARM_RELOC_PAIR",

2321 "ARM_RELOC_SECTDIFF",

2322 "ARM_RELOC_LOCAL_SECTDIFF",

2323 "ARM_RELOC_PB_LA_PTR",

2324 "ARM_RELOC_BR24",

2325 "ARM_THUMB_RELOC_BR22",

2326 "ARM_THUMB_32BIT_BRANCH",

2327 "ARM_RELOC_HALF",

2328 "ARM_RELOC_HALF_SECTDIFF" };

2329

2330 if (RType > 9)

2331 res = "Unknown";

2332 else

2333 res = Table[RType];

2334 break;

2335 }

2338 static const char *const Table[] = {

2339 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",

2340 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",

2341 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",

2342 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",

2343 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",

2344 "ARM64_RELOC_ADDEND", "ARM64_RELOC_AUTHENTICATED_POINTER"

2345 };

2346

2347 if (RType >= std::size(Table))

2348 res = "Unknown";

2349 else

2350 res = Table[RType];

2351 break;

2352 }

2354 static const char *const Table[] = {

2355 "PPC_RELOC_VANILLA",

2356 "PPC_RELOC_PAIR",

2357 "PPC_RELOC_BR14",

2358 "PPC_RELOC_BR24",

2359 "PPC_RELOC_HI16",

2360 "PPC_RELOC_LO16",

2361 "PPC_RELOC_HA16",

2362 "PPC_RELOC_LO14",

2363 "PPC_RELOC_SECTDIFF",

2364 "PPC_RELOC_PB_LA_PTR",

2365 "PPC_RELOC_HI16_SECTDIFF",

2366 "PPC_RELOC_LO16_SECTDIFF",

2367 "PPC_RELOC_HA16_SECTDIFF",

2368 "PPC_RELOC_JBSR",

2369 "PPC_RELOC_LO14_SECTDIFF",

2370 "PPC_RELOC_LOCAL_SECTDIFF" };

2371

2372 if (RType > 15)

2373 res = "Unknown";

2374 else

2375 res = Table[RType];

2376 break;

2377 }

2379 res = "Unknown";

2380 break;

2381 }

2382 Result.append(res.begin(), res.end());

2383}

2384

2388}

2389

2390

2391

2392

2393

2394

2395

2396

2397

2398

2399

2400

2401

2402

2403

2404

2405

2406

2407

2408

2409

2410

2411

2412

2413

2414

2415

2416

2417

2418

2419

2420

2421

2422

2423

2424

2425

2427 bool &isFramework,

2429 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;

2430 size_t a, b, c, d, Idx;

2431

2432 isFramework = false;

2434

2435

2436 a = Name.rfind('/');

2437 if (a == Name.npos || a == 0)

2438 goto guess_library;

2439 Foo = Name.substr(a + 1);

2440

2441

2443 if (Idx != Foo.npos && Foo.size() >= 2) {

2445 if (Suffix != "_debug" && Suffix != "_profile")

2447 else

2449 }

2450

2451

2452 b = Name.rfind('/', a);

2453 if (b == Name.npos)

2454 Idx = 0;

2455 else

2456 Idx = b+1;

2458 DotFramework = Name.substr(Idx + Foo.size(), sizeof(".framework/") - 1);

2459 if (F == Foo && DotFramework == ".framework/") {

2460 isFramework = true;

2461 return Foo;

2462 }

2463

2464

2465 if (b == Name.npos)

2466 goto guess_library;

2467 c = Name.rfind('/', b);

2468 if (c == Name.npos || c == 0)

2469 goto guess_library;

2470 V = Name.substr(c + 1);

2471 if (!V.starts_with("Versions/"))

2472 goto guess_library;

2473 d = Name.rfind('/', c);

2474 if (d == Name.npos)

2475 Idx = 0;

2476 else

2477 Idx = d+1;

2479 DotFramework = Name.substr(Idx + Foo.size(), sizeof(".framework/") - 1);

2480 if (F == Foo && DotFramework == ".framework/") {

2481 isFramework = true;

2482 return Foo;

2483 }

2484

2485guess_library:

2486

2487 a = Name.rfind('.');

2488 if (a == Name.npos || a == 0)

2490 Dylib = Name.substr(a);

2491 if (Dylib != ".dylib")

2492 goto guess_qtx;

2493

2494

2495 if (a >= 3) {

2496 Dot = Name.substr(a - 2, 1);

2497 if (Dot == ".")

2498 a = a - 2;

2499 }

2500

2501 b = Name.rfind('/', a);

2502 if (b == Name.npos)

2503 b = 0;

2504 else

2505 b = b+1;

2506

2510 Suffix = Name.slice(Idx, a);

2511 if (Suffix != "_debug" && Suffix != "_profile") {

2514 }

2515 }

2516 else

2518

2519

2520 if (Lib.size() >= 3) {

2521 Dot = Lib.substr(Lib.size() - 2, 1);

2522 if (Dot == ".")

2523 Lib = Lib.slice(0, Lib.size()-2);

2524 }

2525 return Lib;

2526

2527guess_qtx:

2528 Qtx = Name.substr(a);

2529 if (Qtx != ".qtx")

2531 b = Name.rfind('/', a);

2532 if (b == Name.npos)

2534 else

2535 Lib = Name.slice(b+1, a);

2536

2537 if (Lib.size() >= 3) {

2538 Dot = Lib.substr(Lib.size() - 2, 1);

2539 if (Dot == ".")

2540 Lib = Lib.slice(0, Lib.size()-2);

2541 }

2542 return Lib;

2543}

2544

2545

2546

2547

2548

2549

2552 if (Index >= Libraries.size())

2554

2555

2556

2557 if (LibrariesShortNames.size() == 0) {

2558 for (unsigned i = 0; i < Libraries.size(); i++) {

2559 auto CommandOrErr =

2560 getStructOrErrMachO::dylib\_command(*this, Libraries[i]);

2561 if (!CommandOrErr)

2564 if (D.dylib.name >= D.cmdsize)

2566 const char *P = (const char *)(Libraries[i]) + D.dylib.name;

2568 if (D.dylib.name+Name.size() >= D.cmdsize)

2571 bool isFramework;

2573 if (shortName.empty())

2575 else

2576 LibrariesShortNames.push_back(shortName);

2577 }

2578 }

2579

2580 Res = LibrariesShortNames[Index];

2581 return std::error_code();

2582}

2583

2585 return Libraries.size();

2586}

2587

2591 Sec.d.a = Rel->getRawDataRefImpl().d.a;

2593}

2594

2598 if (!SymtabLoadCmd || Symtab.nsyms == 0)

2600

2602}

2603

2607 if (!SymtabLoadCmd || Symtab.nsyms == 0)

2609

2615 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));

2617}

2618

2621 if (!SymtabLoadCmd || Index >= Symtab.nsyms)

2626 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));

2629}

2630

2633 if (!SymtabLoadCmd)

2634 report_fatal_error("getSymbolIndex() called with no symbol table symbol");

2638 DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));

2640 return Index;

2641}

2642

2646}

2647

2650 DRI.d.a = Sections.size();

2652}

2653

2655 return is64Bit() ? 8 : 4;

2656}

2657

2659 unsigned CPUType = getCPUType(*this);

2661 switch (CPUType) {

2663 return "Mach-O 32-bit i386";

2665 return "Mach-O arm";

2667 return "Mach-O arm64 (ILP32)";

2669 return "Mach-O 32-bit ppc";

2670 default:

2671 return "Mach-O 32-bit unknown";

2672 }

2673 }

2674

2675 switch (CPUType) {

2677 return "Mach-O 64-bit x86-64";

2679 return "Mach-O arm64";

2681 return "Mach-O 64-bit ppc64";

2682 default:

2683 return "Mach-O 64-bit unknown";

2684 }

2685}

2686

2688 switch (CPUType) {

2703 default:

2705 }

2706}

2707

2709 const char **McpuDefault,

2710 const char **ArchFlag) {

2711 if (McpuDefault)

2712 *McpuDefault = nullptr;

2713 if (ArchFlag)

2714 *ArchFlag = nullptr;

2715

2716 switch (CPUType) {

2720 if (ArchFlag)

2721 *ArchFlag = "i386";

2722 return Triple("i386-apple-darwin");

2723 default:

2725 }

2729 if (ArchFlag)

2730 *ArchFlag = "x86_64";

2731 return Triple("x86_64-apple-darwin");

2733 if (ArchFlag)

2734 *ArchFlag = "x86_64h";

2735 return Triple("x86_64h-apple-darwin");

2736 default:

2738 }

2742 if (ArchFlag)

2743 *ArchFlag = "armv4t";

2744 return Triple("armv4t-apple-darwin");

2746 if (ArchFlag)

2747 *ArchFlag = "armv5e";

2748 return Triple("armv5e-apple-darwin");

2750 if (ArchFlag)

2751 *ArchFlag = "xscale";

2752 return Triple("xscale-apple-darwin");

2754 if (ArchFlag)

2755 *ArchFlag = "armv6";

2756 return Triple("armv6-apple-darwin");

2758 if (McpuDefault)

2759 *McpuDefault = "cortex-m0";

2760 if (ArchFlag)

2761 *ArchFlag = "armv6m";

2762 return Triple("armv6m-apple-darwin");

2764 if (ArchFlag)

2765 *ArchFlag = "armv7";

2766 return Triple("armv7-apple-darwin");

2768 if (McpuDefault)

2769 *McpuDefault = "cortex-m4";

2770 if (ArchFlag)

2771 *ArchFlag = "armv7em";

2772 return Triple("thumbv7em-apple-darwin");

2774 if (McpuDefault)

2775 *McpuDefault = "cortex-a7";

2776 if (ArchFlag)

2777 *ArchFlag = "armv7k";

2778 return Triple("armv7k-apple-darwin");

2780 if (McpuDefault)

2781 *McpuDefault = "cortex-m3";

2782 if (ArchFlag)

2783 *ArchFlag = "armv7m";

2784 return Triple("thumbv7m-apple-darwin");

2786 if (McpuDefault)

2787 *McpuDefault = "cortex-a7";

2788 if (ArchFlag)

2789 *ArchFlag = "armv7s";

2790 return Triple("armv7s-apple-darwin");

2791 default:

2793 }

2797 if (McpuDefault)

2798 *McpuDefault = "cyclone";

2799 if (ArchFlag)

2800 *ArchFlag = "arm64";

2801 return Triple("arm64-apple-darwin");

2803 if (McpuDefault)

2804 *McpuDefault = "apple-a12";

2805 if (ArchFlag)

2806 *ArchFlag = "arm64e";

2807 return Triple("arm64e-apple-darwin");

2808 default:

2810 }

2814 if (McpuDefault)

2815 *McpuDefault = "cyclone";

2816 if (ArchFlag)

2817 *ArchFlag = "arm64_32";

2818 return Triple("arm64_32-apple-darwin");

2819 default:

2821 }

2825 if (ArchFlag)

2826 *ArchFlag = "ppc";

2827 return Triple("ppc-apple-darwin");

2828 default:

2830 }

2834 if (ArchFlag)

2835 *ArchFlag = "ppc64";

2836 return Triple("ppc64-apple-darwin");

2837 default:

2839 }

2840 default:

2842 }

2843}

2844

2847}

2848

2852}

2853

2855 static const std::array<StringRef, 18> ValidArchs = {{

2856 "i386",

2857 "x86_64",

2858 "x86_64h",

2859 "armv4t",

2860 "arm",

2861 "armv5e",

2862 "armv6",

2863 "armv6m",

2864 "armv7",

2865 "armv7em",

2866 "armv7k",

2867 "armv7m",

2868 "armv7s",

2869 "arm64",

2870 "arm64e",

2871 "arm64_32",

2872 "ppc",

2873 "ppc64",

2874 }};

2875

2876 return ValidArchs;

2877}

2878

2881}

2882

2885}

2886

2889 DRI.d.a = Index;

2891}

2892

2895 DRI.d.a = Index;

2897}

2898

2901 if (!DataInCodeLoadCmd)

2903

2905 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, DicLC.dataoff));

2907}

2908

2911 if (!DataInCodeLoadCmd)

2913

2916 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));

2918}

2919

2922

2923void ExportEntry::moveToFirst() {

2925 pushNode(0);

2926 if (*E)

2927 return;

2928 pushDownUntilBottom();

2929}

2930

2931void ExportEntry::moveToEnd() {

2933 Done = true;

2934}

2935

2937

2938 if (Done || Other.Done)

2939 return (Done == Other.Done);

2940

2941 if (Stack.size() != Other.Stack.size())

2942 return false;

2943

2944 if (!CumulativeString.equals(Other.CumulativeString))

2945 return false;

2946

2947 for (unsigned i=0; i < Stack.size(); ++i) {

2948 if (Stack[i].Start != Other.Stack[i].Start)

2949 return false;

2950 }

2951 return true;

2952}

2953

2955 unsigned Count;

2957 Ptr += Count;

2958 if (Ptr > Trie.end())

2960 return Result;

2961}

2962

2964 return CumulativeString;

2965}

2966

2968 return Stack.back().Flags;

2969}

2970

2972 return Stack.back().Address;

2973}

2974

2976 return Stack.back().Other;

2977}

2978

2980 const char* ImportName = Stack.back().ImportName;

2981 if (ImportName)

2984}

2985

2987 return Stack.back().Start - Trie.begin();

2988}

2989

2990ExportEntry::NodeState::NodeState(const uint8_t *Ptr)

2991 : Start(Ptr), Current(Ptr) {}

2992

2993void ExportEntry::pushNode(uint64_t offset) {

2996 NodeState State(Ptr);

2997 const char *error = nullptr;

2998 uint64_t ExportInfoSize = readULEB128(State.Current, &error);

3001 " in export trie data at node: 0x" +

3003 moveToEnd();

3004 return;

3005 }

3006 State.IsExportNode = (ExportInfoSize != 0);

3007 const uint8_t* Children = State.Current + ExportInfoSize;

3008 if (Children > Trie.end()) {

3011 " in export trie data at node: 0x" + Twine::utohexstr(offset) +

3012 " too big and extends past end of trie data");

3013 moveToEnd();

3014 return;

3015 }

3016 if (State.IsExportNode) {

3017 const uint8_t *ExportStart = State.Current;

3018 State.Flags = readULEB128(State.Current, &error);

3021 " in export trie data at node: 0x" +

3023 moveToEnd();

3024 return;

3025 }

3027 if (State.Flags != 0 &&

3032 "unsupported exported symbol kind: " + Twine((int)Kind) +

3034 " in export trie data at node: 0x" + Twine::utohexstr(offset));

3035 moveToEnd();

3036 return;

3037 }

3039 State.Address = 0;

3040 State.Other = readULEB128(State.Current, &error);

3043 " in export trie data at node: 0x" +

3045 moveToEnd();

3046 return;

3047 }

3048 if (O != nullptr) {

3049

3050

3051 if ((int64_t)State.Other > 0 && State.Other > O->getLibraryCount()) {

3053 "bad library ordinal: " + Twine((int)State.Other) + " (max " +

3055 ") in export trie data at node: 0x" + Twine::utohexstr(offset));

3056 moveToEnd();

3057 return;

3058 }

3059 }

3060 State.ImportName = reinterpret_cast<const char*>(State.Current);

3061 if (*State.ImportName == '\0') {

3062 State.Current++;

3063 } else {

3064 const uint8_t *End = State.Current + 1;

3065 if (End >= Trie.end()) {

3066 *E = malformedError("import name of re-export in export trie data at "

3067 "node: 0x" +

3069 " starts past end of trie data");

3070 moveToEnd();

3071 return;

3072 }

3073 while(*End != '\0' && End < Trie.end())

3075 if (*End != '\0') {

3076 *E = malformedError("import name of re-export in export trie data at "

3077 "node: 0x" +

3079 " extends past end of trie data");

3080 moveToEnd();

3081 return;

3082 }

3083 State.Current = End + 1;

3084 }

3085 } else {

3086 State.Address = readULEB128(State.Current, &error);

3089 " in export trie data at node: 0x" +

3091 moveToEnd();

3092 return;

3093 }

3095 State.Other = readULEB128(State.Current, &error);

3098 " in export trie data at node: 0x" +

3100 moveToEnd();

3101 return;

3102 }

3103 }

3104 }

3105 if (ExportStart + ExportInfoSize < State.Current) {

3107 "inconsistent export info size: 0x" +

3108 Twine::utohexstr(ExportInfoSize) + " where actual size was: 0x" +

3110 " in export trie data at node: 0x" + Twine::utohexstr(offset));

3111 moveToEnd();

3112 return;

3113 }

3114 }

3115 State.ChildCount = *Children;

3116 if (State.ChildCount != 0 && Children + 1 >= Trie.end()) {

3117 *E = malformedError("byte for count of childern in export trie data at "

3118 "node: 0x" +

3120 " extends past end of trie data");

3121 moveToEnd();

3122 return;

3123 }

3124 State.Current = Children + 1;

3125 State.NextChildIndex = 0;

3126 State.ParentStringLength = CumulativeString.size();

3128}

3129

3130void ExportEntry::pushDownUntilBottom() {

3132 const char *error = nullptr;

3133 while (Stack.back().NextChildIndex < Stack.back().ChildCount) {

3134 NodeState &Top = Stack.back();

3135 CumulativeString.resize(Top.ParentStringLength);

3136 for (;*Top.Current != 0 && Top.Current < Trie.end(); Top.Current++) {

3137 char C = *Top.Current;

3139 }

3140 if (Top.Current >= Trie.end()) {

3141 *E = malformedError("edge sub-string in export trie data at node: 0x" +

3143 " for child #" + Twine((int)Top.NextChildIndex) +

3144 " extends past end of trie data");

3145 moveToEnd();

3146 return;

3147 }

3148 Top.Current += 1;

3149 uint64_t childNodeIndex = readULEB128(Top.Current, &error);

3152 " in export trie data at node: 0x" +

3154 moveToEnd();

3155 return;

3156 }

3157 for (const NodeState &node : nodes()) {

3158 if (node.Start == Trie.begin() + childNodeIndex){

3159 *E = malformedError("loop in childern in export trie data at node: 0x" +

3161 " back to node: 0x" +

3163 moveToEnd();

3164 return;

3165 }

3166 }

3167 Top.NextChildIndex += 1;

3168 pushNode(childNodeIndex);

3169 if (*E)

3170 return;

3171 }

3172 if (!Stack.back().IsExportNode) {

3173 *E = malformedError("node is not an export node in export trie data at "

3174 "node: 0x" +

3176 moveToEnd();

3177 return;

3178 }

3179}

3180

3181

3182

3183

3184

3185

3186

3187

3188

3189

3190

3191

3192

3193

3194

3195

3197 assert(!Stack.empty() && "ExportEntry::moveNext() with empty node stack");

3198 if (!Stack.back().IsExportNode) {

3199 *E = malformedError("node is not an export node in export trie data at "

3200 "node: 0x" +

3202 moveToEnd();

3203 return;

3204 }

3205

3207 while (!Stack.empty()) {

3208 NodeState &Top = Stack.back();

3209 if (Top.NextChildIndex < Top.ChildCount) {

3210 pushDownUntilBottom();

3211

3212 return;

3213 } else {

3214 if (Top.IsExportNode) {

3215

3216 CumulativeString.resize(Top.ParentStringLength);

3217 return;

3218 }

3220 }

3221 }

3222 Done = true;

3223}

3224

3229 if (Trie.empty())

3230 Start.moveToEnd();

3231 else

3232 Start.moveToFirst();

3233

3235 Finish.moveToEnd();

3236

3238}

3239

3242 if (DyldInfoLoadCmd)

3244 else if (DyldExportsTrieLoadCmd)

3246

3247 return exports(Err, Trie, this);

3248}

3249

3252 : E(E), O(O) {

3253

3255 if (Command.C.cmd == MachO::LC_SEGMENT) {

3257 if (StringRef(SLC.segname) == "__TEXT") {

3258 TextAddress = SLC.vmaddr;

3259 break;

3260 }

3261 } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {

3264 TextAddress = SLC_64.vmaddr;

3265 break;

3266 }

3267 }

3268 }

3269}

3270

3272

3275}

3276

3279}

3280

3283}

3284

3287}

3288

3291}

3292

3294

3296

3298

3300

3302

3309 Done = false;

3310}

3311

3313

3315

3318 bool Parse)

3321 if (!Parse)

3322 return;

3323

3325 FixupTargets = *FixupTargetsOrErr;

3326 } else {

3327 *E = FixupTargetsOrErr.takeError();

3328 return;

3329 }

3330

3332 Segments = std::move(SegmentsOrErr->second);

3333 } else {

3334 *E = SegmentsOrErr.takeError();

3335 return;

3336 }

3337}

3338

3339void MachOChainedFixupEntry::findNextPageWithFixups() {

3340 auto FindInSegment = [this]() {

3342 while (PageIndex < SegInfo.PageStarts.size() &&

3344 ++PageIndex;

3345 return PageIndex < SegInfo.PageStarts.size();

3346 };

3347

3348 while (InfoSegIndex < Segments.size()) {

3349 if (FindInSegment()) {

3350 PageOffset = Segments[InfoSegIndex].PageStarts[PageIndex];

3352 return;

3353 }

3354

3355 InfoSegIndex++;

3356 PageIndex = 0;

3357 }

3358}

3359

3362 if (Segments.empty()) {

3363 Done = true;

3364 return;

3365 }

3366

3367 InfoSegIndex = 0;

3368 PageIndex = 0;

3369

3370 findNextPageWithFixups();

3372}

3373

3376}

3377

3380

3381 if (InfoSegIndex == Segments.size()) {

3382 Done = true;

3383 return;

3384 }

3385

3389

3390

3395 " has unsupported chained fixup pointer_format " +

3396 Twine(PointerFormat));

3398 return;

3399 }

3400

3406

3410 " extends past segment's end");

3412 return;

3413 }

3414

3419

3420

3422 "by getDyldChainedFixupTargets()");

3424 return (RawValue >> Right) & ((1ULL << Count) - 1);

3425 };

3426

3427

3428

3429 bool IsBind = Field(63, 1);

3432 if (IsBind) {

3435

3436 if (ImportOrdinal >= FixupTargets.size()) {

3439 " has out-of range import ordinal " +

3440 Twine(ImportOrdinal));

3442 return;

3443 }

3444

3447 Addend = InlineAddend ? InlineAddend : Target.addend();

3450 } else {

3453

3457 }

3458

3459

3460 if (Next != 0) {

3461 PageOffset += 4 * Next;

3462 } else {

3463 ++PageIndex;

3464 findNextPageWithFixups();

3465 }

3466}

3467

3471 return true;

3473 return false;

3474 return InfoSegIndex == Other.InfoSegIndex && PageIndex == Other.PageIndex &&

3475 PageOffset == Other.PageOffset;

3476}

3477

3480 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),

3481 PointerSize(is64Bit ? 8 : 4) {}

3482

3483void MachORebaseEntry::moveToFirst() {

3486}

3487

3488void MachORebaseEntry::moveToEnd() {

3489 Ptr = Opcodes.end();

3490 RemainingLoopCount = 0;

3491 Done = true;

3492}

3493

3496

3497 SegmentOffset += AdvanceAmount;

3498 if (RemainingLoopCount) {

3499 --RemainingLoopCount;

3500 return;

3501 }

3502

3503 bool More = true;

3504 while (More) {

3505

3506

3507

3508 if (Ptr == Opcodes.end()) {

3509 Done = true;

3510 return;

3511 }

3512

3513

3519 const char *error = nullptr;

3520 switch (Opcode) {

3522 More = false;

3523 Done = true;

3524 moveToEnd();

3526 break;

3528 RebaseType = ImmValue;

3530 *E = malformedError("for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " +

3531 Twine((int)RebaseType) + " for opcode at: 0x" +

3533 moveToEnd();

3534 return;

3535 }

3537 "mach-o-rebase",

3538 dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "

3539 << "RebaseType=" << (int) RebaseType << "\n");

3540 break;

3542 SegmentIndex = ImmValue;

3543 SegmentOffset = readULEB128(&error);

3545 *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +

3546 Twine(error) + " for opcode at: 0x" +

3548 moveToEnd();

3549 return;

3550 }

3552 PointerSize);

3554 *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +

3555 Twine(error) + " for opcode at: 0x" +

3557 moveToEnd();

3558 return;

3559 }

3561 "mach-o-rebase",

3562 dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "

3563 << "SegmentIndex=" << SegmentIndex << ", "

3564 << format("SegmentOffset=0x%06X", SegmentOffset)

3565 << "\n");

3566 break;

3568 SegmentOffset += readULEB128(&error);

3571 " for opcode at: 0x" +

3573 moveToEnd();

3574 return;

3575 }

3577 PointerSize);

3580 " for opcode at: 0x" +

3582 moveToEnd();

3583 return;

3584 }

3586 dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "

3587 << format("SegmentOffset=0x%06X",

3588 SegmentOffset) << "\n");

3589 break;

3591 SegmentOffset += ImmValue * PointerSize;

3593 PointerSize);

3595 *E = malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED " +

3596 Twine(error) + " for opcode at: 0x" +

3598 moveToEnd();

3599 return;

3600 }

3602 dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "

3603 << format("SegmentOffset=0x%06X",

3604 SegmentOffset) << "\n");

3605 break;

3607 AdvanceAmount = PointerSize;

3608 Skip = 0;

3609 Count = ImmValue;

3610 if (ImmValue != 0)

3611 RemainingLoopCount = ImmValue - 1;

3612 else

3613 RemainingLoopCount = 0;

3615 PointerSize, Count, Skip);

3617 *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " +

3618 Twine(error) + " for opcode at: 0x" +

3620 moveToEnd();

3621 return;

3622 }

3624 "mach-o-rebase",

3625 dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "

3626 << format("SegmentOffset=0x%06X", SegmentOffset)

3627 << ", AdvanceAmount=" << AdvanceAmount

3628 << ", RemainingLoopCount=" << RemainingLoopCount

3629 << "\n");

3630 return;

3632 AdvanceAmount = PointerSize;

3633 Skip = 0;

3634 Count = readULEB128(&error);

3636 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +

3637 Twine(error) + " for opcode at: 0x" +

3639 moveToEnd();

3640 return;

3641 }

3642 if (Count != 0)

3643 RemainingLoopCount = Count - 1;

3644 else

3645 RemainingLoopCount = 0;

3647 PointerSize, Count, Skip);

3649 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +

3650 Twine(error) + " for opcode at: 0x" +

3652 moveToEnd();

3653 return;

3654 }

3656 "mach-o-rebase",

3657 dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "

3658 << format("SegmentOffset=0x%06X", SegmentOffset)

3659 << ", AdvanceAmount=" << AdvanceAmount

3660 << ", RemainingLoopCount=" << RemainingLoopCount

3661 << "\n");

3662 return;

3664 Skip = readULEB128(&error);

3666 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +

3667 Twine(error) + " for opcode at: 0x" +

3669 moveToEnd();

3670 return;

3671 }

3672 AdvanceAmount = Skip + PointerSize;

3673 Count = 1;

3674 RemainingLoopCount = 0;

3676 PointerSize, Count, Skip);

3678 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +

3679 Twine(error) + " for opcode at: 0x" +

3681 moveToEnd();

3682 return;

3683 }

3685 "mach-o-rebase",

3686 dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "

3687 << format("SegmentOffset=0x%06X", SegmentOffset)

3688 << ", AdvanceAmount=" << AdvanceAmount

3689 << ", RemainingLoopCount=" << RemainingLoopCount

3690 << "\n");

3691 return;

3693 Count = readULEB128(&error);

3695 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"

3696 "ULEB " +

3697 Twine(error) + " for opcode at: 0x" +

3699 moveToEnd();

3700 return;

3701 }

3702 if (Count != 0)

3703 RemainingLoopCount = Count - 1;

3704 else

3705 RemainingLoopCount = 0;

3706 Skip = readULEB128(&error);

3708 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"

3709 "ULEB " +

3710 Twine(error) + " for opcode at: 0x" +

3712 moveToEnd();

3713 return;

3714 }

3715 AdvanceAmount = Skip + PointerSize;

3716

3718 PointerSize, Count, Skip);

3720 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"

3721 "ULEB " +

3722 Twine(error) + " for opcode at: 0x" +

3724 moveToEnd();

3725 return;

3726 }

3728 "mach-o-rebase",

3729 dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "

3730 << format("SegmentOffset=0x%06X", SegmentOffset)

3731 << ", AdvanceAmount=" << AdvanceAmount

3732 << ", RemainingLoopCount=" << RemainingLoopCount

3733 << "\n");

3734 return;

3735 default:

3736 *E = malformedError("bad rebase info (bad opcode value 0x" +

3739 moveToEnd();

3740 return;

3741 }

3742 }

3743}

3744

3745uint64_t MachORebaseEntry::readULEB128(const char **error) {

3746 unsigned Count;

3748 Ptr += Count;

3749 if (Ptr > Opcodes.end())

3750 Ptr = Opcodes.end();

3751 return Result;

3752}

3753

3755

3757

3759 switch (RebaseType) {

3761 return "pointer";

3763 return "text abs32";

3765 return "text rel32";

3766 }

3767 return "unknown";

3768}

3769

3770

3771

3774}

3775

3776

3777

3780}

3781

3782

3783

3786}

3787

3789#ifdef EXPENSIVE_CHECKS

3790 assert(Opcodes == Other.Opcodes && "compare iterators of different files");

3791#else

3792 assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");

3793#endif

3794 return (Ptr == Other.Ptr) &&

3795 (RemainingLoopCount == Other.RemainingLoopCount) &&

3796 (Done == Other.Done);

3797}

3798

3802 if (O->BindRebaseSectionTable == nullptr)

3803 O->BindRebaseSectionTable = std::make_unique(O);

3805 Start.moveToFirst();

3806

3808 Finish.moveToEnd();

3809

3811}

3812

3815}

3816

3819 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),

3820 PointerSize(is64Bit ? 8 : 4), TableKind(BK) {}

3821

3822void MachOBindEntry::moveToFirst() {

3825}

3826

3827void MachOBindEntry::moveToEnd() {

3828 Ptr = Opcodes.end();

3829 RemainingLoopCount = 0;

3830 Done = true;

3831}

3832

3835

3836 SegmentOffset += AdvanceAmount;

3837 if (RemainingLoopCount) {

3838 --RemainingLoopCount;

3839 return;

3840 }

3841

3842 bool More = true;

3843 while (More) {

3844

3845

3846

3847 if (Ptr == Opcodes.end()) {

3848 Done = true;

3849 return;

3850 }

3851

3852

3857 int8_t SignExtended;

3858 const uint8_t *SymStart;

3860 const char *error = nullptr;

3861 switch (Opcode) {

3864

3865

3866 bool NotLastEntry = false;

3868 if (*P) {

3869 NotLastEntry = true;

3870 }

3871 }

3872 if (NotLastEntry)

3873 break;

3874 }

3875 More = false;

3876 moveToEnd();

3878 break;

3881 *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in "

3882 "weak bind table for opcode at: 0x" +

3884 moveToEnd();

3885 return;

3886 }

3887 Ordinal = ImmValue;

3888 LibraryOrdinalSet = true;

3890 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "

3891 "library ordinal: " +

3892 Twine((int)ImmValue) + " (max " +

3894 ") for opcode at: 0x" +

3896 moveToEnd();

3897 return;

3898 }

3900 "mach-o-bind",

3901 dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "

3902 << "Ordinal=" << Ordinal << "\n");

3903 break;

3906 *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in "

3907 "weak bind table for opcode at: 0x" +

3909 moveToEnd();

3910 return;

3911 }

3912 Ordinal = readULEB128(&error);

3913 LibraryOrdinalSet = true;

3915 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB " +

3916 Twine(error) + " for opcode at: 0x" +

3918 moveToEnd();

3919 return;

3920 }

3922 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "

3923 "library ordinal: " +

3924 Twine((int)Ordinal) + " (max " +

3926 ") for opcode at: 0x" +

3928 moveToEnd();

3929 return;

3930 }

3932 "mach-o-bind",

3933 dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "

3934 << "Ordinal=" << Ordinal << "\n");

3935 break;

3938 *E = malformedError("BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in "

3939 "weak bind table for opcode at: 0x" +

3941 moveToEnd();

3942 return;

3943 }

3944 if (ImmValue) {

3946 Ordinal = SignExtended;

3948 *E = malformedError("for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown "

3949 "special ordinal: " +

3950 Twine((int)Ordinal) + " for opcode at: 0x" +

3952 moveToEnd();

3953 return;

3954 }

3955 } else

3956 Ordinal = 0;

3957 LibraryOrdinalSet = true;

3959 "mach-o-bind",

3960 dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "

3961 << "Ordinal=" << Ordinal << "\n");

3962 break;

3964 Flags = ImmValue;

3965 SymStart = Ptr;

3966 while (*Ptr && (Ptr < Opcodes.end())) {

3968 }

3969 if (Ptr == Opcodes.end()) {

3971 "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM "

3972 "symbol name extends past opcodes for opcode at: 0x" +

3974 moveToEnd();

3975 return;

3976 }

3977 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),

3978 Ptr-SymStart);

3981 "mach-o-bind",

3982 dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "

3983 << "SymbolName=" << SymbolName << "\n");

3986 return;

3987 }

3988 break;

3990 BindType = ImmValue;

3992 *E = malformedError("for BIND_OPCODE_SET_TYPE_IMM bad bind type: " +

3993 Twine((int)ImmValue) + " for opcode at: 0x" +

3995 moveToEnd();

3996 return;

3997 }

3999 "mach-o-bind",

4000 dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "

4001 << "BindType=" << (int)BindType << "\n");

4002 break;

4004 Addend = readSLEB128(&error);

4007 " for opcode at: 0x" +

4009 moveToEnd();

4010 return;

4011 }

4013 "mach-o-bind",

4014 dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "

4015 << "Addend=" << Addend << "\n");

4016 break;

4018 SegmentIndex = ImmValue;

4019 SegmentOffset = readULEB128(&error);

4021 *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +

4022 Twine(error) + " for opcode at: 0x" +

4024 moveToEnd();

4025 return;

4026 }

4028 PointerSize);

4030 *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +

4031 Twine(error) + " for opcode at: 0x" +

4033 moveToEnd();

4034 return;

4035 }

4037 "mach-o-bind",

4038 dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "

4039 << "SegmentIndex=" << SegmentIndex << ", "

4040 << format("SegmentOffset=0x%06X", SegmentOffset)

4041 << "\n");

4042 break;

4044 SegmentOffset += readULEB128(&error);

4047 " for opcode at: 0x" +

4049 moveToEnd();

4050 return;

4051 }

4053 PointerSize);

4056 " for opcode at: 0x" +

4058 moveToEnd();

4059 return;

4060 }

4062 dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "

4063 << format("SegmentOffset=0x%06X",

4064 SegmentOffset) << "\n");

4065 break;

4067 AdvanceAmount = PointerSize;

4068 RemainingLoopCount = 0;

4070 PointerSize);

4073 " for opcode at: 0x" +

4075 moveToEnd();

4076 return;

4077 }

4078 if (SymbolName == StringRef()) {

4080 "for BIND_OPCODE_DO_BIND missing preceding "

4081 "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +

4083 moveToEnd();

4084 return;

4085 }

4086 if (!LibraryOrdinalSet && TableKind != Kind::Weak) {

4087 *E =

4088 malformedError("for BIND_OPCODE_DO_BIND missing preceding "

4089 "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +

4091 moveToEnd();

4092 return;

4093 }

4095 dbgs() << "BIND_OPCODE_DO_BIND: "

4096 << format("SegmentOffset=0x%06X",

4097 SegmentOffset) << "\n");

4098 return;

4101 *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in "

4102 "lazy bind table for opcode at: 0x" +

4104 moveToEnd();

4105 return;

4106 }

4108 PointerSize);

4110 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +

4111 Twine(error) + " for opcode at: 0x" +

4113 moveToEnd();

4114 return;

4115 }

4116 if (SymbolName == StringRef()) {

4118 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "

4119 "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode "

4120 "at: 0x" +

4122 moveToEnd();

4123 return;

4124 }

4125 if (!LibraryOrdinalSet && TableKind != Kind::Weak) {

4127 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "

4128 "preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +

4130 moveToEnd();

4131 return;

4132 }

4133 AdvanceAmount = readULEB128(&error) + PointerSize;

4135 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +

4136 Twine(error) + " for opcode at: 0x" +

4138 moveToEnd();

4139 return;

4140 }

4141

4142

4143

4145 AdvanceAmount, PointerSize);

4147 *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB (after adding "

4148 "ULEB) " +

4149 Twine(error) + " for opcode at: 0x" +

4151 moveToEnd();

4152 return;

4153 }

4154 RemainingLoopCount = 0;

4156 "mach-o-bind",

4157 dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "

4158 << format("SegmentOffset=0x%06X", SegmentOffset)

4159 << ", AdvanceAmount=" << AdvanceAmount

4160 << ", RemainingLoopCount=" << RemainingLoopCount

4161 << "\n");

4162 return;

4165 *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not "

4166 "allowed in lazy bind table for opcode at: 0x" +

4168 moveToEnd();

4169 return;

4170 }

4171 if (SymbolName == StringRef()) {

4173 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "

4174 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "

4175 "opcode at: 0x" +

4177 moveToEnd();

4178 return;

4179 }

4180 if (!LibraryOrdinalSet && TableKind != Kind::Weak) {

4182 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "

4183 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "

4184 "at: 0x" +

4186 moveToEnd();

4187 return;

4188 }

4189 AdvanceAmount = ImmValue * PointerSize + PointerSize;

4190 RemainingLoopCount = 0;

4192 AdvanceAmount, PointerSize);

4194 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +

4195 Twine(error) + " for opcode at: 0x" +

4197 moveToEnd();

4198 return;

4199 }

4202 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "

4203 << format("SegmentOffset=0x%06X", SegmentOffset) << "\n");

4204 return;

4207 *E = malformedError("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not "

4208 "allowed in lazy bind table for opcode at: 0x" +

4210 moveToEnd();

4211 return;

4212 }

4213 Count = readULEB128(&error);

4214 if (Count != 0)

4215 RemainingLoopCount = Count - 1;

4216 else

4217 RemainingLoopCount = 0;

4219 *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "

4220 " (count value) " +

4221 Twine(error) + " for opcode at: 0x" +

4223 moveToEnd();

4224 return;

4225 }

4226 Skip = readULEB128(&error);

4227 AdvanceAmount = Skip + PointerSize;

4229 *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "

4230 " (skip value) " +

4231 Twine(error) + " for opcode at: 0x" +

4233 moveToEnd();

4234 return;

4235 }

4236 if (SymbolName == StringRef()) {

4238 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "

4239 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "

4240 "opcode at: 0x" +

4242 moveToEnd();

4243 return;

4244 }

4245 if (!LibraryOrdinalSet && TableKind != Kind::Weak) {

4247 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "

4248 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "

4249 "at: 0x" +

4251 moveToEnd();

4252 return;

4253 }

4255 PointerSize, Count, Skip);

4257 *E =

4258 malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +

4259 Twine(error) + " for opcode at: 0x" +

4261 moveToEnd();

4262 return;

4263 }

4265 "mach-o-bind",

4266 dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "

4267 << format("SegmentOffset=0x%06X", SegmentOffset)

4268 << ", AdvanceAmount=" << AdvanceAmount

4269 << ", RemainingLoopCount=" << RemainingLoopCount

4270 << "\n");

4271 return;

4272 default:

4273 *E = malformedError("bad bind info (bad opcode value 0x" +

4276 moveToEnd();

4277 return;

4278 }

4279 }

4280}

4281

4282uint64_t MachOBindEntry::readULEB128(const char **error) {

4283 unsigned Count;

4285 Ptr += Count;

4286 if (Ptr > Opcodes.end())

4287 Ptr = Opcodes.end();

4288 return Result;

4289}

4290

4291int64_t MachOBindEntry::readSLEB128(const char **error) {

4292 unsigned Count;

4294 Ptr += Count;

4295 if (Ptr > Opcodes.end())

4296 Ptr = Opcodes.end();

4297 return Result;

4298}

4299

4301

4303

4305 switch (BindType) {

4307 return "pointer";

4309 return "text abs32";

4311 return "text rel32";

4312 }

4313 return "unknown";

4314}

4315

4317

4319

4321

4323

4324

4325

4328}

4329

4330

4331

4334}

4335

4336

4337

4340}

4341

4343#ifdef EXPENSIVE_CHECKS

4344 assert(Opcodes == Other.Opcodes && "compare iterators of different files");

4345#else

4346 assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");

4347#endif

4348 return (Ptr == Other.Ptr) &&

4349 (RemainingLoopCount == Other.RemainingLoopCount) &&

4350 (Done == Other.Done);

4351}

4352

4353

4359 SectionInfo Info;

4361 if (!NameOrErr)

4363 else

4364 Info.SectionName = *NameOrErr;

4365 Info.Address = Section.getAddress();

4366 Info.Size = Section.getSize();

4367 Info.SegmentName =

4369 if (Info.SegmentName != CurSegName) {

4370 ++CurSegIndex;

4371 CurSegName = Info.SegmentName;

4372 CurSegAddress = Info.Address;

4373 }

4374 Info.SegmentIndex = CurSegIndex - 1;

4375 Info.OffsetInSegment = Info.Address - CurSegAddress;

4376 Info.SegmentStartAddress = CurSegAddress;

4378 }

4379 MaxSegIndex = CurSegIndex;

4380}

4381

4382

4383

4384

4385

4386

4387

4388

4394 if (SegIndex == -1)

4395 return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";

4396 if (SegIndex >= MaxSegIndex)

4397 return "bad segIndex (too large)";

4398 for (uint64_t i = 0; i < Count; ++i) {

4399 uint64_t Start = SegOffset + i * (PointerSize + Skip);

4401 bool Found = false;

4402 for (const SectionInfo &SI : Sections) {

4403 if (SI.SegmentIndex != SegIndex)

4404 continue;

4405 if ((SI.OffsetInSegment<=Start) && (Start<(SI.OffsetInSegment+SI.Size))) {

4406 if (End <= SI.OffsetInSegment + SI.Size) {

4407 Found = true;

4408 break;

4409 }

4410 else

4411 return "bad offset, extends beyond section boundary";

4412 }

4413 }

4414 if (!Found)

4415 return "bad offset, not in section";

4416 }

4417 return nullptr;

4418}

4419

4420

4421

4423 for (const SectionInfo &SI : Sections) {

4424 if (SI.SegmentIndex == SegIndex)

4425 return SI.SegmentName;

4426 }

4428}

4429

4430

4431

4432const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(

4433 int32_t SegIndex, uint64_t SegOffset) {

4434 for (const SectionInfo &SI : Sections) {

4435 if (SI.SegmentIndex != SegIndex)

4436 continue;

4437 if (SI.OffsetInSegment > SegOffset)

4438 continue;

4439 if (SegOffset >= (SI.OffsetInSegment + SI.Size))

4440 continue;

4441 return SI;

4442 }

4443 llvm_unreachable("SegIndex and SegOffset not in any section");

4444}

4445

4446

4447

4450 return findSection(SegIndex, SegOffset).SectionName;

4451}

4452

4453

4454

4456 const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);

4457 return SI.SegmentStartAddress + OffsetInSeg;

4458}

4459

4464 if (O->BindRebaseSectionTable == nullptr)

4465 O->BindRebaseSectionTable = std::make_unique(O);

4466 MachOBindEntry Start(&Err, O, Opcodes, is64, BKind);

4467 Start.moveToFirst();

4468

4469 MachOBindEntry Finish(&Err, O, Opcodes, is64, BKind);

4470 Finish.moveToEnd();

4471

4473}

4474

4478}

4479

4483}

4484

4488}

4489

4491 if (BindRebaseSectionTable == nullptr)

4492 BindRebaseSectionTable = std::make_unique(this);

4493

4495 Start.moveToFirst();

4496

4499

4501}

4502

4505 return LoadCommands.begin();

4506}

4507

4510 return LoadCommands.end();

4511}

4512

4516}

4517

4522}

4523

4526 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");

4527 const section_base *Base =

4528 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);

4530}

4531

4534 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");

4535 const section_base *Base =

4536 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);

4538}

4539

4540bool

4542 const {

4544 return false;

4546}

4547

4551 return RE.r_word1 & 0xffffff;

4553}

4554

4558 return (RE.r_word1 >> 27) & 1;

4559 return (RE.r_word1 >> 4) & 1;

4560}

4561

4564 return RE.r_word0 >> 31;

4565}

4566

4570}

4571

4574 return (RE.r_word0 >> 24) & 0xf;

4575}

4576

4582}

4583

4589}

4590

4596}

4597

4598unsigned

4604}

4605

4612 if (SecNum == MachO::R_ABS || SecNum > Sections.size())

4615 DRI.d.a = SecNum - 1;

4617}

4618

4620 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");

4621 return getStructMachO::section(*this, Sections[DRI.d.a]);

4622}

4623

4625 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");

4626 return getStructMachO::section\_64(*this, Sections[DRI.d.a]);

4627}

4628

4630 unsigned Index) const {

4631 const char *Sec = getSectionPtr(*this, L, Index);

4632 return getStructMachO::section(*this, Sec);

4633}

4634

4636 unsigned Index) const {

4637 const char *Sec = getSectionPtr(*this, L, Index);

4638 return getStructMachO::section\_64(*this, Sec);

4639}

4640

4643 const char *P = reinterpret_cast<const char *>(DRI.p);

4644 return getStructMachO::nlist(*this, P);

4645}

4646

4649 const char *P = reinterpret_cast<const char *>(DRI.p);

4650 return getStructMachO::nlist\_64(*this, P);

4651}

4652

4655 return getStructMachO::linkedit\_data\_command(*this, L.Ptr);

4656}

4657

4660 return getStructMachO::segment\_command(*this, L.Ptr);

4661}

4662

4665 return getStructMachO::segment\_command\_64(*this, L.Ptr);

4666}

4667

4670 return getStructMachO::linker\_option\_command(*this, L.Ptr);

4671}

4672

4675 return getStructMachO::version\_min\_command(*this, L.Ptr);

4676}

4677

4680 return getStructMachO::note\_command(*this, L.Ptr);

4681}

4682

4685 return getStructMachO::build\_version\_command(*this, L.Ptr);

4686}

4687

4690 return getStructMachO::build\_tool\_version(*this, BuildTools[index]);

4691}

4692

4695 return getStructMachO::dylib\_command(*this, L.Ptr);

4696}

4697

4700 return getStructMachO::dyld\_info\_command(*this, L.Ptr);

4701}

4702

4705 return getStructMachO::dylinker\_command(*this, L.Ptr);

4706}

4707

4710 return getStructMachO::uuid\_command(*this, L.Ptr);

4711}

4712

4715 return getStructMachO::rpath\_command(*this, L.Ptr);

4716}

4717

4720 return getStructMachO::source\_version\_command(*this, L.Ptr);

4721}

4722

4725 return getStructMachO::entry\_point\_command(*this, L.Ptr);

4726}

4727

4730 return getStructMachO::encryption\_info\_command(*this, L.Ptr);

4731}

4732

4735 return getStructMachO::encryption\_info\_command\_64(*this, L.Ptr);

4736}

4737

4740 return getStructMachO::sub\_framework\_command(*this, L.Ptr);

4741}

4742

4745 return getStructMachO::sub\_umbrella\_command(*this, L.Ptr);

4746}

4747

4750 return getStructMachO::sub\_library\_command(*this, L.Ptr);

4751}

4752

4755 return getStructMachO::sub\_client\_command(*this, L.Ptr);

4756}

4757

4760 return getStructMachO::routines\_command(*this, L.Ptr);

4761}

4762

4765 return getStructMachO::routines\_command\_64(*this, L.Ptr);

4766}

4767

4770 return getStructMachO::thread\_command(*this, L.Ptr);

4771}

4772

4775 return getStructMachO::fileset\_entry\_command(*this, L.Ptr);

4776}

4777

4783 Sec.d.a = Rel.d.a;

4787 } else {

4790 }

4791 } else {

4793 if (Rel.d.a == 0)

4794 Offset = DysymtabLoadCmd.extreloff;

4795 else

4796 Offset = DysymtabLoadCmd.locreloff;

4797 }

4798

4801 return getStructMachO::any\_relocation\_info(

4802 *this, reinterpret_cast<const char *>(P));

4803}

4804

4807 const char *P = reinterpret_cast<const char *>(Rel.p);

4808 return getStructMachO::data\_in\_code\_entry(*this, P);

4809}

4810

4813}

4814

4818}

4819

4822 unsigned Index) const {

4824 return getStruct<uint32_t>(*this, getPtr(*this, Offset));

4825}

4826

4829 unsigned Index) const {

4831 return getStructMachO::data\_in\_code\_entry(*this, getPtr(*this, Offset));

4832}

4833

4835 if (SymtabLoadCmd)

4836 return getStructMachO::symtab\_command(*this, SymtabLoadCmd);

4837

4838

4840 Cmd.cmd = MachO::LC_SYMTAB;

4846 return Cmd;

4847}

4848

4850 if (DysymtabLoadCmd)

4851 return getStructMachO::dysymtab\_command(*this, DysymtabLoadCmd);

4852

4853

4855 Cmd.cmd = MachO::LC_DYSYMTAB;

4864 Cmd.ntoc = 0;

4875 return Cmd;

4876}

4877

4880 if (DataInCodeLoadCmd)

4881 return getStructMachO::linkedit\_data\_command(*this, DataInCodeLoadCmd);

4882

4883

4885 Cmd.cmd = MachO::LC_DATA_IN_CODE;

4889 return Cmd;

4890}

4891

4894 if (LinkOptHintsLoadCmd)

4895 return getStructMachO::linkedit\_data\_command(*this, LinkOptHintsLoadCmd);

4896

4897

4898

4900 Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;

4904 return Cmd;

4905}

4906

4908 if (!DyldInfoLoadCmd)

4909 return {};

4910

4911 auto DyldInfoOrErr =

4912 getStructOrErrMachO::dyld\_info\_command(*this, DyldInfoLoadCmd);

4913 if (!DyldInfoOrErr)

4914 return {};

4919}

4920

4922 if (!DyldInfoLoadCmd)

4923 return {};

4924

4925 auto DyldInfoOrErr =

4926 getStructOrErrMachO::dyld\_info\_command(*this, DyldInfoLoadCmd);

4927 if (!DyldInfoOrErr)

4928 return {};

4933}

4934

4936 if (!DyldInfoLoadCmd)

4937 return {};

4938

4939 auto DyldInfoOrErr =

4940 getStructOrErrMachO::dyld\_info\_command(*this, DyldInfoLoadCmd);

4941 if (!DyldInfoOrErr)

4942 return {};

4947}

4948

4950 if (!DyldInfoLoadCmd)

4951 return {};

4952

4953 auto DyldInfoOrErr =

4954 getStructOrErrMachO::dyld\_info\_command(*this, DyldInfoLoadCmd);

4955 if (!DyldInfoOrErr)

4956 return {};

4961}

4962

4964 if (!DyldInfoLoadCmd)

4965 return {};

4966

4967 auto DyldInfoOrErr =

4968 getStructOrErrMachO::dyld\_info\_command(*this, DyldInfoLoadCmd);

4969 if (!DyldInfoOrErr)

4970 return {};

4975}

4976

4979

4980 if (!DyldChainedFixupsLoadCmd)

4981 return std::nullopt;

4982 auto DyldChainedFixupsOrErr = getStructOrErrMachO::linkedit\_data\_command(

4983 *this, DyldChainedFixupsLoadCmd);

4984 if (!DyldChainedFixupsOrErr)

4985 return DyldChainedFixupsOrErr.takeError();

4987 *DyldChainedFixupsOrErr;

4988

4989

4990

4991 if (!DyldChainedFixups.dataoff)

4992 return std::nullopt;

4993 return DyldChainedFixups;

4994}

4995

4999 if (!CFOrErr)

5000 return CFOrErr.takeError();

5001 if (!CFOrErr->has_value())

5002 return std::nullopt;

5003

5005

5008

5009

5010 const char *CFHeaderPtr = getPtr(*this, CFHeaderOffset);

5011 auto CFHeaderOrErr =

5012 getStructOrErrMachO::dyld\_chained\_fixups\_header(*this, CFHeaderPtr);

5013 if (!CFHeaderOrErr)

5014 return CFHeaderOrErr.takeError();

5016

5017

5023 Twine("bad chained fixups: unknown imports format: ") +

5025

5026

5027

5028

5031 return malformedError(Twine("bad chained fixups: image starts offset ") +

5033 " overlaps with chained fixups header");

5034 }

5035 uint32_t EndOffset = CFHeaderOffset + CFSize;

5037 EndOffset) {

5039 Twine(CFImageStartsOffset +

5041 " extends past end " + Twine(EndOffset));

5042 }

5043

5044 return CFHeader;

5045}

5046

5050 if (!CFOrErr)

5051 return CFOrErr.takeError();

5052

5053 std::vector Segments;

5054 if (!CFOrErr->has_value())

5055 return std::make_pair(0, Segments);

5056

5058

5060 if (!HeaderOrErr)

5061 return HeaderOrErr.takeError();

5062 if (!HeaderOrErr->has_value())

5063 return std::make_pair(0, Segments);

5065

5066 const char *Contents = getPtr(*this, DyldChainedFixups.dataoff);

5067

5068 auto ImageStartsOrErr = getStructOrErrMachO::dyld\_chained\_starts\_in\_image(

5069 *this, Contents + Header.starts_offset);

5070 if (!ImageStartsOrErr)

5071 return ImageStartsOrErr.takeError();

5073

5074 const char *SegOffsPtr =

5075 Contents + Header.starts_offset +

5077 const char *SegOffsEnd =

5079 if (SegOffsEnd > Contents + DyldChainedFixups.datasize)

5081 "bad chained fixups: seg_info_offset extends past end");

5082

5083 const char *LastSegEnd = nullptr;

5084 for (size_t I = 0, N = ImageStarts.seg_count; I < N; ++I) {

5085 auto OffOrErr =

5086 getStructOrErr<uint32_t>(*this, SegOffsPtr + I * sizeof(uint32_t));

5087 if (!OffOrErr)

5088 return OffOrErr.takeError();

5089

5090

5091 if (!*OffOrErr)

5092 continue;

5093

5094 auto Fail = [&](Twine Message) {

5096 " at offset " + Twine(*OffOrErr) + Message);

5097 };

5098

5099 const char *SegPtr = Contents + Header.starts_offset + *OffOrErr;

5100 if (LastSegEnd && SegPtr < LastSegEnd)

5101 return Fail(" overlaps with previous segment info");

5102

5103 auto SegOrErr =

5104 getStructOrErrMachO::dyld\_chained\_starts\_in\_segment(*this, SegPtr);

5105 if (!SegOrErr)

5106 return SegOrErr.takeError();

5108

5109 LastSegEnd = SegPtr + Seg.size;

5112

5113 const char *PageStart =

5115 const char *PageEnd = PageStart + Seg.page_count * sizeof(uint16_t);

5116 if (PageEnd > SegPtr + Seg.size)

5117 return Fail(" : page_starts extend past seg_info size");

5118

5119

5120

5121 std::vector<uint16_t> PageStarts;

5122 for (size_t PageIdx = 0; PageIdx < Seg.page_count; ++PageIdx) {

5124 memcpy(&Start, PageStart + PageIdx * sizeof(uint16_t), sizeof(uint16_t));

5127 PageStarts.push_back(Start);

5128 }

5129

5130 Segments.emplace_back(I, *OffOrErr, Seg, std::move(PageStarts));

5131 }

5132

5133 return std::make_pair(ImageStarts.seg_count, Segments);

5134}

5135

5136

5137

5142 return SignExtend32<sizeof(T) * CHAR_BIT>(Value);

5144}

5145

5146template <typename T, unsigned N>

5148 std::array<T, N> RawValue;

5149 memcpy(RawValue.data(), Ptr, N * sizeof(T));

5151 for (auto &Element : RawValue)

5153 return RawValue;

5154}

5155

5159 if (!CFOrErr)

5160 return CFOrErr.takeError();

5161

5162 std::vector Targets;

5163 if (!CFOrErr->has_value())

5164 return Targets;

5165

5167

5169 if (!CFHeaderOrErr)

5170 return CFHeaderOrErr.takeError();

5171 if (!(*CFHeaderOrErr))

5172 return Targets;

5174

5175 size_t ImportSize = 0;

5182 else

5183 return malformedError("bad chained fixups: unknown imports format: " +

5185

5186 const char *Contents = getPtr(*this, DyldChainedFixups.dataoff);

5187 const char *Imports = Contents + Header.imports_offset;

5188 size_t ImportsEndOffset =

5189 Header.imports_offset + ImportSize * Header.imports_count;

5190 const char *ImportsEnd = Contents + ImportsEndOffset;

5191 const char *Symbols = Contents + Header.symbols_offset;

5192 const char *SymbolsEnd = Contents + DyldChainedFixups.datasize;

5193

5194 if (ImportsEnd > Symbols)

5195 return malformedError("bad chained fixups: imports end " +

5196 Twine(ImportsEndOffset) + " overlaps with symbols");

5197

5198

5199

5201 return createError("parsing big-endian chained fixups is not implemented");

5202 for (const char *ImportPtr = Imports; ImportPtr < ImportsEnd;

5203 ImportPtr += ImportSize) {

5204 int LibOrdinal;

5205 bool WeakImport;

5210 auto RawValue = getArray<uint32_t, 1>(*this, ImportPtr);

5211

5212 LibOrdinal = getEncodedOrdinal<uint8_t>(RawValue[0] & 0xFF);

5213 WeakImport = (RawValue[0] >> 8) & 1;

5214 NameOffset = RawValue[0] >> 9;

5215 Addend = 0;

5217 static_assert(sizeof(uint64_t) ==

5219 auto RawValue = getArray<uint32_t, 2>(*this, ImportPtr);

5220

5221 LibOrdinal = getEncodedOrdinal<uint8_t>(RawValue[0] & 0xFF);

5222 WeakImport = (RawValue[0] >> 8) & 1;

5223 NameOffset = RawValue[0] >> 9;

5224 Addend = bit_cast<int32_t>(RawValue[1]);

5226 static_assert(2 * sizeof(uint64_t) ==

5228 auto RawValue = getArray<uint64_t, 2>(*this, ImportPtr);

5229

5230 LibOrdinal = getEncodedOrdinal<uint16_t>(RawValue[0] & 0xFFFF);

5231 NameOffset = (RawValue[0] >> 16) & 1;

5232 WeakImport = RawValue[0] >> 17;

5233 Addend = RawValue[1];

5234 } else {

5236 }

5237

5238 const char *Str = Symbols + NameOffset;

5239 if (Str >= SymbolsEnd)

5240 return malformedError("bad chained fixups: symbol offset " +

5241 Twine(NameOffset) + " extends past end " +

5243 Targets.emplace_back(LibOrdinal, NameOffset, Str, Addend, WeakImport);

5244 }

5245

5246 return std::move(Targets);

5247}

5248

5250 if (!DyldExportsTrieLoadCmd)

5251 return {};

5252

5253 auto DyldExportsTrieOrError = getStructOrErrMachO::linkedit\_data\_command(

5254 *this, DyldExportsTrieLoadCmd);

5255 if (!DyldExportsTrieOrError)

5256 return {};

5261}

5262

5264 if (!FuncStartsLoadCmd)

5265 return {};

5266

5267 auto InfoOrErr =

5268 getStructOrErrMachO::linkedit\_data\_command(*this, FuncStartsLoadCmd);

5269 if (!InfoOrErr)

5270 return {};

5271

5275 return std::move(FunctionStarts);

5276}

5277

5279 if (!UuidLoadCmd)

5280 return {};

5281

5284}

5285

5289}

5290

5294}

5295

5299

5303 data += delta;

5305 }

5306}

5307

5310}

5311

5312

5313

5314

5315

5316

5317

5318

5321 size_t MachOFilesetEntryOffset) {

5323 if (Magic == "\xFE\xED\xFA\xCE")

5325 UniversalIndex, MachOFilesetEntryOffset);

5326 if (Magic == "\xCE\xFA\xED\xFE")

5328 UniversalIndex, MachOFilesetEntryOffset);

5329 if (Magic == "\xFE\xED\xFA\xCF")

5331 UniversalIndex, MachOFilesetEntryOffset);

5332 if (Magic == "\xCF\xFA\xED\xFE")

5334 UniversalIndex, MachOFilesetEntryOffset);

5335 return make_error("Unrecognized MachO magic number",

5337}

5338

5341 .Case("debug_str_offs", "debug_str_offsets")

5343}

5344

5348

5352 return std::vectorstd::string();

5353 sys::path::append(BundlePath, "Contents", "Resources", "DWARF");

5354 bool IsDir;

5358 EC, "%s: expected directory 'Contents/Resources/DWARF' in dSYM bundle",

5359 Path.str().c_str());

5360 if (EC)

5362

5363 std::vectorstd::string ObjectPaths;

5365 Dir != DirEnd && !EC; Dir.increment(EC)) {

5366 StringRef ObjectPath = Dir->path();

5370 switch (Status.type()) {

5374 ObjectPaths.push_back(ObjectPath.str());

5375 break;

5376 default: ;

5377 }

5378 }

5379 if (EC)

5381 if (ObjectPaths.empty())

5383 "%s: no objects found in dSYM bundle",

5384 Path.str().c_str());

5385 return ObjectPaths;

5386}

5387

5391#define HANDLE_SWIFT_SECTION(KIND, MACHO, ELF, COFF) \

5392 .Case(MACHO, llvm::binaryformat::Swift5ReflectionSectionKind::KIND)

5395#include "llvm/BinaryFormat/Swift.def"

5397#undef HANDLE_SWIFT_SECTION

5398}

5399

5401 switch (Arch) {

5415 default:

5416 return false;

5417 }

5418}

for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))

#define offsetof(TYPE, MEMBER)

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

Analysis containing CSE Info

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

#define DEBUG_WITH_TYPE(TYPE,...)

DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.

static MachO::nlist_base getSymbolTableEntryBase(const MachOObjectFile &O, DataRefImpl DRI)

static Error checkVersCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName)

static Error checkSymtabCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **SymtabLoadCmd, std::list< MachOElement > &Elements)

static Error checkTwoLevelHintsCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, std::list< MachOElement > &Elements)

static Error parseBuildVersionCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, SmallVectorImpl< const char * > &BuildTools, uint32_t LoadCommandIndex)

static unsigned getPlainRelocationType(const MachOObjectFile &O, const MachO::any_relocation_info &RE)

static Error checkDysymtabCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **DysymtabLoadCmd, std::list< MachOElement > &Elements)

static Error checkDylibCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)

static Expected< T > getStructOrErr(const MachOObjectFile &O, const char *P)

static Expected< MachOObjectFile::LoadCommandInfo > getFirstLoadCommandInfo(const MachOObjectFile &Obj)

static const char * getPtr(const MachOObjectFile &O, size_t Offset, size_t MachOFilesetEntryOffset=0)

static Error parseSegmentLoadCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, SmallVectorImpl< const char * > &Sections, bool &IsPageZeroSegment, uint32_t LoadCommandIndex, const char *CmdName, uint64_t SizeOfHeaders, std::list< MachOElement > &Elements)

static Error checkDyldInfoCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName, std::list< MachOElement > &Elements)

static unsigned getScatteredRelocationLength(const MachO::any_relocation_info &RE)

static unsigned getPlainRelocationLength(const MachOObjectFile &O, const MachO::any_relocation_info &RE)

static Error checkSubCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName, size_t SizeOfCmd, const char *CmdStructName, uint32_t PathOffset, const char *PathFieldName)

static Error checkRpathCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex)

static T getStruct(const MachOObjectFile &O, const char *P)

static uint32_t getPlainRelocationAddress(const MachO::any_relocation_info &RE)

static const char * getSectionPtr(const MachOObjectFile &O, MachOObjectFile::LoadCommandInfo L, unsigned Sec)

static Error checkLinkerOptCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex)

static bool getPlainRelocationPCRel(const MachOObjectFile &O, const MachO::any_relocation_info &RE)

static std::array< T, N > getArray(const MachOObjectFile &O, const void *Ptr)

static unsigned getScatteredRelocationAddress(const MachO::any_relocation_info &RE)

static Error checkThreadCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)

static Error checkLinkeditDataCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName, std::list< MachOElement > &Elements, const char *ElementName)

static Error malformedError(const Twine &Msg)

static bool isLoadCommandObsolete(uint32_t cmd)

static uint32_t getSectionFlags(const MachOObjectFile &O, DataRefImpl Sec)

static int getEncodedOrdinal(T Value)

static bool getScatteredRelocationPCRel(const MachO::any_relocation_info &RE)

static Error checkOverlappingElement(std::list< MachOElement > &Elements, uint64_t Offset, uint64_t Size, const char *Name)

static StringRef parseSegmentOrSectionName(const char *P)

static Expected< MachOObjectFile::LoadCommandInfo > getLoadCommandInfo(const MachOObjectFile &Obj, const char *Ptr, uint32_t LoadCommandIndex)

static void parseHeader(const MachOObjectFile &Obj, T &Header, Error &Err)

static unsigned getCPUType(const MachOObjectFile &O)

static Error checkDyldCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)

static Error checkNoteCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, std::list< MachOElement > &Elements)

static Error checkDylibIdCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd)

static unsigned getCPUSubType(const MachOObjectFile &O)

static Error checkEncryptCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, uint64_t cryptoff, uint64_t cryptsize, const char **LoadCmd, const char *CmdName)

static Expected< MachOObjectFile::LoadCommandInfo > getNextLoadCommandInfo(const MachOObjectFile &Obj, uint32_t LoadCommandIndex, const MachOObjectFile::LoadCommandInfo &L)

static Error malformedError(Twine Msg)

OptimizedStructLayoutField Field

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

static StringRef substr(StringRef Str, uint64_t Len)

This file defines the SmallVector class.

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

static bool is64Bit(const char *name)

This file implements the C++20 header.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

bool empty() const

empty - Check if the array is empty.

Helper for Errors used as out-parameters.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

reference get()

Returns a reference to the stored T value.

StringRef getBuffer() const

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

bool equals(StringRef RHS) const

Check for string equality.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

std::string str() const

str - Get the contents as an std::string.

constexpr StringRef substr(size_t Start, size_t N=npos) const

Return a reference to the substring from [Start, Start + N).

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr bool empty() const

empty - Check if the string is empty.

StringRef slice(size_t Start, size_t End) const

Return a reference to the substring from [Start, End).

constexpr size_t size() const

size - Get the string size.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

size_t rfind(char C, size_t From=npos) const

Search for the last character C in the string.

size_t find(char C, size_t From=0) const

Search for the first character C in the string.

static constexpr size_t npos

A switch()-like statement whose cases are string literals.

StringSwitch & Case(StringLiteral S, T Value)

A table of densely packed, null-terminated strings indexed by offset.

constexpr size_t size() const

Returns the byte size of the table.

Target - Wrapper for Target specific information.

Triple - Helper class for working with autoconf configuration names.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

static Twine utohexstr(const uint64_t &Val)

LLVM Value Representation.

A range adaptor for a pair of iterators.

StringRef getData() const

unsigned int getType() const

bool isLittleEndian() const

static unsigned int getMachOType(bool isLE, bool is64Bits)

StringRef segmentName(int32_t SegIndex)

StringRef sectionName(int32_t SegIndex, uint64_t SegOffset)

BindRebaseSegInfo(const MachOObjectFile *Obj)

const char * checkSegAndOffsets(int32_t SegIndex, uint64_t SegOffset, uint8_t PointerSize, uint64_t Count=1, uint64_t Skip=0)

uint64_t address(uint32_t SegIndex, uint64_t SegOffset)

DiceRef - This is a value type class that represents a single data in code entry in the table in a Ma...

ExportEntry encapsulates the current-state-of-the-walk used when doing a non-recursive walk of the tr...

ExportEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > Trie)

bool operator==(const ExportEntry &) const

StringRef otherName() const

uint32_t nodeOffset() const

MachOAbstractFixupEntry is an abstract class representing a fixup in a MH_DYLDLINK file.

StringRef sectionName() const

uint64_t segmentAddress() const

int32_t segmentIndex() const

StringRef typeName() const

MachOAbstractFixupEntry(Error *Err, const MachOObjectFile *O)

uint64_t textAddress() const

StringRef symbolName() const

StringRef segmentName() const

const MachOObjectFile * O

uint64_t segmentOffset() const

MachOBindEntry encapsulates the current state in the decompression of binding opcodes.

bool operator==(const MachOBindEntry &) const

StringRef symbolName() const

StringRef sectionName() const

MachOBindEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > Opcodes, bool is64Bit, MachOBindEntry::Kind)

StringRef segmentName() const

uint64_t segmentOffset() const

int32_t segmentIndex() const

StringRef typeName() const

bool operator==(const MachOChainedFixupEntry &) const

MachOChainedFixupEntry(Error *Err, const MachOObjectFile *O, bool Parse)

MachO::sub_client_command getSubClientCommand(const LoadCommandInfo &L) const

void moveSectionNext(DataRefImpl &Sec) const override

ArrayRef< char > getSectionRawFinalSegmentName(DataRefImpl Sec) const

uint8_t getBytesInAddress() const override

The number of bytes used to represent an address in this object file format.

Triple::ArchType getArch() const override

MachO::mach_header_64 Header64

bool isSectionData(DataRefImpl Sec) const override

const MachO::mach_header_64 & getHeader64() const

Expected< std::vector< ChainedFixupTarget > > getDyldChainedFixupTargets() const

uint64_t getSectionAlignment(DataRefImpl Sec) const override

uint32_t getScatteredRelocationType(const MachO::any_relocation_info &RE) const

symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override

Expected< SectionRef > getSection(unsigned SectionIndex) const

iterator_range< rebase_iterator > rebaseTable(Error &Err)

For use iterating over all rebase table entries.

std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const

load_command_iterator begin_load_commands() const

MachO::encryption_info_command_64 getEncryptionInfoCommand64(const LoadCommandInfo &L) const

StringRef getFileFormatName() const override

dice_iterator begin_dices() const

basic_symbol_iterator symbol_begin() const override

Expected< std::optional< MachO::linkedit_data_command > > getChainedFixupsLoadCommand() const

iterator_range< export_iterator > exports(Error &Err) const

For use iterating over all exported symbols.

uint64_t getSymbolIndex(DataRefImpl Symb) const

MachO::build_version_command getBuildVersionLoadCommand(const LoadCommandInfo &L) const

section_iterator section_end() const override

MachO::build_tool_version getBuildToolVersion(unsigned index) const

MachO::linkedit_data_command getDataInCodeLoadCommand() const

MachO::routines_command getRoutinesCommand(const LoadCommandInfo &L) const

MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const

unsigned getSymbolSectionID(SymbolRef Symb) const

static Expected< std::vector< std::string > > findDsymObjectMembers(StringRef Path)

If the input path is a .dSYM bundle (as created by the dsymutil tool), return the paths to the object...

uint32_t getScatteredRelocationValue(const MachO::any_relocation_info &RE) const

MachO::linker_option_command getLinkerOptionLoadCommand(const LoadCommandInfo &L) const

uint32_t getLibraryCount() const

MachO::entry_point_command getEntryPointCommand(const LoadCommandInfo &L) const

Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override

const char * RebaseEntryCheckSegAndOffsets(int32_t SegIndex, uint64_t SegOffset, uint8_t PointerSize, uint64_t Count=1, uint64_t Skip=0) const

uint64_t getRelocationOffset(DataRefImpl Rel) const override

ArrayRef< uint8_t > getDyldInfoLazyBindOpcodes() const

void moveSymbolNext(DataRefImpl &Symb) const override

SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const

MachO::dysymtab_command getDysymtabLoadCommand() const

iterator_range< bind_iterator > bindTable(Error &Err)

For use iterating over all bind table entries.

MachO::mach_header Header

uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override

relocation_iterator section_rel_begin(DataRefImpl Sec) const override

MachO::section_64 getSection64(DataRefImpl DRI) const

MachO::fileset_entry_command getFilesetEntryLoadCommand(const LoadCommandInfo &L) const

MachO::note_command getNoteLoadCommand(const LoadCommandInfo &L) const

MachO::thread_command getThreadCommand(const LoadCommandInfo &L) const

ArrayRef< uint8_t > getSectionContents(uint32_t Offset, uint64_t Size) const

const char * BindEntryCheckSegAndOffsets(int32_t SegIndex, uint64_t SegOffset, uint8_t PointerSize, uint64_t Count=1, uint64_t Skip=0) const

section_iterator section_begin() const override

Error checkSymbolTable() const

bool isRelocatableObject() const override

True if this is a relocatable object (.o/.obj).

MachO::segment_command_64 getSegment64LoadCommand(const LoadCommandInfo &L) const

relocation_iterator section_rel_end(DataRefImpl Sec) const override

ArrayRef< uint8_t > getDyldInfoExportsTrie() const

bool isDebugSection(DataRefImpl Sec) const override

MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const

unsigned getSectionType(SectionRef Sec) const

MachO::segment_command getSegmentLoadCommand(const LoadCommandInfo &L) const

static Expected< std::unique_ptr< MachOObjectFile > > create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, uint32_t UniversalCputype=0, uint32_t UniversalIndex=0, size_t MachOFilesetEntryOffset=0)

StringRef getSectionFinalSegmentName(DataRefImpl Sec) const

MachO::linkedit_data_command getLinkOptHintsLoadCommand() const

unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const

MachO::rpath_command getRpathCommand(const LoadCommandInfo &L) const

dice_iterator end_dices() const

MachO::routines_command_64 getRoutinesCommand64(const LoadCommandInfo &L) const

MachO::sub_framework_command getSubFrameworkCommand(const LoadCommandInfo &L) const

SmallVector< uint64_t > getFunctionStarts() const

MachO::sub_library_command getSubLibraryCommand(const LoadCommandInfo &L) const

MachO::dyld_info_command getDyldInfoLoadCommand(const LoadCommandInfo &L) const

MachO::sub_umbrella_command getSubUmbrellaCommand(const LoadCommandInfo &L) const

ArrayRef< uint8_t > getDyldExportsTrie() const

Expected< uint32_t > getSymbolFlags(DataRefImpl Symb) const override

section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const

bool isSectionBSS(DataRefImpl Sec) const override

Expected< std::pair< size_t, std::vector< ChainedFixupsSegment > > > getChainedFixupsSegments() const

bool isSectionVirtual(DataRefImpl Sec) const override

bool getScatteredRelocationScattered(const MachO::any_relocation_info &RE) const

Expected< StringRef > getSymbolName(DataRefImpl Symb) const override

bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const

symbol_iterator getSymbolByIndex(unsigned Index) const

static Triple getHostArch()

MachO::encryption_info_command getEncryptionInfoCommand(const LoadCommandInfo &L) const

const MachO::mach_header & getHeader() const

unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const

iterator_range< bind_iterator > weakBindTable(Error &Err)

For use iterating over all weak bind table entries.

static bool isMachOPairedReloc(uint64_t RelocType, uint64_t Arch)

ArrayRef< uint8_t > getDyldInfoRebaseOpcodes() const

iterator_range< load_command_iterator > load_commands() const

unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const

MachO::symtab_command getSymtabLoadCommand() const

Triple getArchTriple(const char **McpuDefault=nullptr) const

MachO::uuid_command getUuidCommand(const LoadCommandInfo &L) const

unsigned getPlainRelocationSymbolNum(const MachO::any_relocation_info &RE) const

ArrayRef< uint8_t > getUuid() const

uint64_t BindRebaseAddress(uint32_t SegIndex, uint64_t SegOffset) const

For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase entry to get the address.

bool is64Bit() const override

MachO::version_min_command getVersionMinLoadCommand(const LoadCommandInfo &L) const

StringRef mapDebugSectionName(StringRef Name) const override

Maps a debug section name to a standard DWARF section name.

MachO::dylinker_command getDylinkerCommand(const LoadCommandInfo &L) const

uint64_t getRelocationType(DataRefImpl Rel) const override

StringRef BindRebaseSegmentName(int32_t SegIndex) const

For use with the SegIndex of a checked Mach-O Bind or Rebase entry to get the segment name.

relocation_iterator extrel_begin() const

void moveRelocationNext(DataRefImpl &Rel) const override

MachO::any_relocation_info getRelocation(DataRefImpl Rel) const

basic_symbol_iterator symbol_end() const override

MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset, unsigned Index) const

MachO::data_in_code_entry getDice(DataRefImpl Rel) const

bool isSectionStripped(DataRefImpl Sec) const override

When dsymutil generates the companion file, it strips all unnecessary sections (e....

uint64_t getSectionIndex(DataRefImpl Sec) const override

iterator_range< fixup_iterator > fixupTable(Error &Err)

For iterating over all chained fixups.

void ReadULEB128s(uint64_t Index, SmallVectorImpl< uint64_t > &Out) const

StringRef BindRebaseSectionName(uint32_t SegIndex, uint64_t SegOffset) const

For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase entry to get the section ...

iterator_range< bind_iterator > lazyBindTable(Error &Err)

For use iterating over all lazy bind table entries.

load_command_iterator end_load_commands() const

ArrayRef< uint8_t > getDyldInfoBindOpcodes() const

Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override

uint64_t getSectionAddress(DataRefImpl Sec) const override

bool hasPageZeroSegment() const

Expected< StringRef > getSectionName(DataRefImpl Sec) const override

uint8_t getRelocationLength(DataRefImpl Rel) const

llvm::binaryformat::Swift5ReflectionSectionKind mapReflectionSectionNameToEnumValue(StringRef SectionName) const override

ArrayRef< uint8_t > getDyldInfoWeakBindOpcodes() const

static bool isValidArch(StringRef ArchFlag)

bool isSectionText(DataRefImpl Sec) const override

bool isSectionCompressed(DataRefImpl Sec) const override

static ArrayRef< StringRef > getValidArchs()

bool isSectionBitcode(DataRefImpl Sec) const override

bool isRelocationScattered(const MachO::any_relocation_info &RE) const

relocation_iterator locrel_begin() const

Expected< std::optional< MachO::dyld_chained_fixups_header > > getChainedFixupsHeader() const

If the optional is std::nullopt, no header was found, but the object was well-formed.

uint32_t getSymbolAlignment(DataRefImpl Symb) const override

MachO::source_version_command getSourceVersionCommand(const LoadCommandInfo &L) const

unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const

StringRef getStringTableData() const

void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override

ArrayRef< char > getSectionRawName(DataRefImpl Sec) const

uint64_t getNValue(DataRefImpl Sym) const

ArrayRef< uint8_t > getSegmentContents(StringRef SegmentName) const

Return the raw contents of an entire segment.

section_iterator getRelocationSection(DataRefImpl Rel) const

unsigned getSectionID(SectionRef Sec) const

MachO::linkedit_data_command getLinkeditDataLoadCommand(const LoadCommandInfo &L) const

Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override

MachO::dylib_command getDylibIDLoadCommand(const LoadCommandInfo &L) const

size_t getMachOFilesetEntryOffset() const

uint32_t getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, unsigned Index) const

uint64_t getSectionSize(DataRefImpl Sec) const override

relocation_iterator extrel_end() const

static StringRef guessLibraryShortName(StringRef Name, bool &isFramework, StringRef &Suffix)

relocation_iterator locrel_end() const

std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const

MachORebaseEntry encapsulates the current state in the decompression of rebasing opcodes.

int32_t segmentIndex() const

StringRef segmentName() const

MachORebaseEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > opcodes, bool is64Bit)

bool operator==(const MachORebaseEntry &) const

StringRef sectionName() const

uint64_t segmentOffset() const

StringRef typeName() const

This class is the base class for all object file types.

friend class RelocationRef

static Expected< std::unique_ptr< MachOObjectFile > > createMachOObjectFile(MemoryBufferRef Object, uint32_t UniversalCputype=0, uint32_t UniversalIndex=0, size_t MachOFilesetEntryOffset=0)

Create a MachOObjectFile instance from a given buffer.

section_iterator_range sections() const

symbol_iterator_range symbols() const

Expected< uint64_t > getSymbolValue(DataRefImpl Symb) const

This is a value type class that represents a single section in the list of sections in the object fil...

DataRefImpl getRawDataRefImpl() const

bool isData() const

Whether this section contains data, not instructions.

bool isBSS() const

Whether this section contains BSS uninitialized data.

This is a value type class that represents a single symbol in the list of symbols in the object file.

directory_iterator - Iterates through the entries in path.

Represents the result of a call to sys::fs::status().

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ C

The default llvm calling convention, compatible with C.

const uint32_t x86_FLOAT_STATE_COUNT

@ DYLD_CHAINED_IMPORT_ADDEND

@ DYLD_CHAINED_IMPORT_ADDEND64

const uint32_t ARM_THREAD_STATE64_COUNT

@ EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE

@ EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL

@ EXPORT_SYMBOL_FLAGS_KIND_REGULAR

@ BIND_TYPE_TEXT_ABSOLUTE32

@ S_ATTR_PURE_INSTRUCTIONS

S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine instructions.

const uint32_t x86_EXCEPTION_STATE_COUNT

@ REBASE_TYPE_TEXT_ABSOLUTE32

@ REBASE_TYPE_TEXT_PCREL32

@ S_GB_ZEROFILL

S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4 gigabytes).

@ S_THREAD_LOCAL_ZEROFILL

S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section.

@ S_ZEROFILL

S_ZEROFILL - Zero fill on demand section.

@ BIND_SPECIAL_DYLIB_WEAK_LOOKUP

@ BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE

@ BIND_SPECIAL_DYLIB_FLAT_LOOKUP

@ DYLD_CHAINED_PTR_START_NONE

uint8_t GET_COMM_ALIGN(uint16_t n_desc)

void swapStruct(fat_header &mh)

const uint32_t x86_THREAD_STATE32_COUNT

@ EXPORT_SYMBOL_FLAGS_REEXPORT

@ EXPORT_SYMBOL_FLAGS_KIND_MASK

@ EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER

@ CPU_SUBTYPE_POWERPC_ALL

@ BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB

@ BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB

@ BIND_OPCODE_SET_ADDEND_SLEB

@ BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB

@ BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM

@ BIND_OPCODE_ADD_ADDR_ULEB

@ BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED

@ BIND_OPCODE_SET_DYLIB_SPECIAL_IMM

@ BIND_OPCODE_SET_TYPE_IMM

@ BIND_OPCODE_SET_DYLIB_ORDINAL_IMM

@ BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB

const uint32_t PPC_THREAD_STATE_COUNT

const uint32_t ARM_THREAD_STATE_COUNT

@ REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB

@ REBASE_OPCODE_DO_REBASE_IMM_TIMES

@ REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB

@ REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB

@ REBASE_OPCODE_DO_REBASE_ULEB_TIMES

@ REBASE_OPCODE_ADD_ADDR_ULEB

@ REBASE_OPCODE_SET_TYPE_IMM

@ REBASE_OPCODE_ADD_ADDR_IMM_SCALED

const uint32_t x86_THREAD_STATE_COUNT

@ CPU_SUBTYPE_ARM64_32_V8

@ GENERIC_RELOC_LOCAL_SECTDIFF

@ ARM_RELOC_LOCAL_SECTDIFF

@ ARM_RELOC_HALF_SECTDIFF

@ X86_64_RELOC_SUBTRACTOR

uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc)

@ DYLD_CHAINED_PTR_64_OFFSET

const uint32_t x86_EXCEPTION_STATE64_COUNT

const uint32_t x86_THREAD_STATE64_COUNT

@ BIND_SYMBOL_FLAGS_WEAK_IMPORT

@ BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION

constexpr size_t SymbolTableEntrySize

Swift5ReflectionSectionKind

Error createError(const Twine &Err)

content_iterator< ExportEntry > export_iterator

content_iterator< MachOChainedFixupEntry > fixup_iterator

content_iterator< DiceRef > dice_iterator

content_iterator< SectionRef > section_iterator

content_iterator< MachOBindEntry > bind_iterator

content_iterator< RelocationRef > relocation_iterator

content_iterator< BasicSymbolRef > basic_symbol_iterator

content_iterator< MachORebaseEntry > rebase_iterator

std::error_code status(const Twine &path, file_status &result, bool follow=true)

Get file status as if by POSIX stat().

bool is_directory(const basic_file_status &status)

Does status represent a directory?

bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)

In-place remove any '.

void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")

Append to path.

StringRef extension(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get extension.

static const bool IsLittleEndianHost

void swapByteOrder(T &Value)

std::string getDefaultTargetTriple()

getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...

This is an optimization pass for GlobalISel generic memory operations.

Error createFileError(const Twine &F, Error E)

Concatenate a source file path and/or name with an Error.

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)

Utility function to decode a ULEB128 value.

int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)

Utility function to decode a SLEB128 value.

Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)

Create formatted StringError object.

@ no_such_file_or_directory

raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

void cantFail(Error Err, const char *Msg=nullptr)

Report a fatal error if Err is a failure value.

auto count(R &&Range, const E &Element)

Wrapper function around std::count to count the number of times an element Element occurs in the give...

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

Error errorCodeToError(std::error_code EC)

Helper for converting an std::error_code to a Error.

void consumeError(Error Err)

Consume a Error without doing anything.

This struct is a compact representation of a valid (non-zero power of two) alignment.

dyld_chained_starts_in_image is embedded in LC_DYLD_CHAINED_FIXUPS payload.

uint16_t page_count

Length of the page_start array.

uint16_t page_size

Page size in bytes (0x1000 or 0x4000)

uint16_t pointer_format

DYLD_CHAINED_PTR*.

uint32_t size

Size of this, including chain_starts entries.

ChainedFixupTarget holds all the information about an external symbol necessary to bind this binary t...

MachO::dyld_chained_starts_in_segment Header

std::vector< uint16_t > PageStarts

struct llvm::object::DataRefImpl::@370 d