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

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);

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

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

195 assert(Ptr <= Obj.getData().end() && "Start must be before end");

196 if (CmdOrErr->cmdsize > (uintptr_t)(Obj.getData().end() - Ptr))

198 " extends past end of file");

199 if (CmdOrErr->cmdsize < 8)

201 " with size less than 8 bytes");

203 } else

205}

206

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

213 "commands in the file");

215 Obj, getPtr(Obj, HeaderSize, Obj.getMachOFilesetEntryOffset()), 0);

216}

217

224 Obj.getData().data() + Obj.getMachOFilesetEntryOffset() + HeaderSize +

225 Obj.getHeader().sizeofcmds)

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

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

229}

230

231template

234 if (sizeof(T) > Obj.getData().size()) {

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

236 "file");

237 return;

238 }

240 Obj, getPtr(Obj, 0, Obj.getMachOFilesetEntryOffset())))

241 Header = *HeaderOrErr;

242 else

243 Err = HeaderOrErr.takeError();

244}

245

246

252

255 const char *Name) {

256 if (Size == 0)

258

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

260 const auto &E = *it;

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

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

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

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

268 auto nt = it;

269 nt++;

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

271 const auto &N = *nt;

273 Elements.insert(nt, {Offset, Size, Name});

275 }

276 }

277 }

278 Elements.push_back({Offset, Size, Name});

280}

281

282

283

284

285template <typename Segment, typename Section>

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

290 std::list &Elements) {

291 const unsigned SegmentLoadSize = sizeof(Segment);

292 if (Load.C.cmdsize < SegmentLoadSize)

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

296 Segment S = SegOrErr.get();

297 const unsigned SectionSize = sizeof(Section);

298 uint64_t FileSize = Obj.getData().size();

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

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

302 " inconsistent cmdsize in " + CmdName +

303 " for the number of sections");

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

308 if (!SectionOrErr)

309 return SectionOrErr.takeError();

310 Section s = SectionOrErr.get();

315 s.offset > FileSize)

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

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

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

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

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

328 BigSize += s.size;

333 BigSize > FileSize)

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

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

336 Twine(LoadCommandIndex) +

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

342 s.size > S.filesize)

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

345 Twine(LoadCommandIndex) +

346 " greater than the segment");

348 Obj.getHeader().filetype != MachO::MH_DSYM && s.size != 0 &&

349 s.addr < S.vmaddr)

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

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

353 BigSize = s.addr;

354 BigSize += s.size;

356 BigEnd += S.vmsize;

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

359 " in " + CmdName + " command " +

360 Twine(LoadCommandIndex) +

361 " greater than than "

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

368 "section contents"))

369 return Err;

370 if (s.reloff > FileSize)

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

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

374 BigSize = s.nreloc;

376 BigSize += s.reloff;

377 if (BigSize > FileSize)

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

379 "struct relocation_info) of section " +

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

381 Twine(LoadCommandIndex) +

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

384 sizeof(struct

386 "section relocation entries"))

387 return Err;

388 }

389 if (S.fileoff > FileSize)

391 " fileoff field in " + CmdName +

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

393 uint64_t BigSize = S.fileoff;

394 BigSize += S.filesize;

395 if (BigSize > FileSize)

397 " fileoff field plus filesize field in " +

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

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

401 " filesize field in " + CmdName +

402 " greater than vmsize field");

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

404 } else

405 return SegOrErr.takeError();

406

408}

409

413 const char **SymtabLoadCmd,

414 std::list &Elements) {

417 " LC_SYMTAB cmdsize too small");

418 if (*SymtabLoadCmd != nullptr)

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

421 if (!SymtabOrErr)

422 return SymtabOrErr.takeError();

426 " has incorrect cmdsize");

427 uint64_t FileSize = Obj.getData().size();

428 if (Symtab.symoff > FileSize)

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

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

431 "of the file");

433 const char *struct_nlist_name;

434 if (Obj.is64Bit()) {

436 struct_nlist_name = "struct nlist_64";

437 } else {

439 struct_nlist_name = "struct nlist";

440 }

441 uint64_t BigSize = SymtabSize;

442 BigSize += Symtab.symoff;

443 if (BigSize > FileSize)

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

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

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

447 "of the file");

449 "symbol table"))

450 return Err;

451 if (Symtab.stroff > FileSize)

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

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

454 "of the file");

455 BigSize = Symtab.stroff;

456 BigSize += Symtab.strsize;

457 if (BigSize > FileSize)

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

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

460 "past the end of the file");

462 Symtab.strsize, "string table"))

463 return Err;

464 *SymtabLoadCmd = Load.Ptr;

466}

467

471 const char **DysymtabLoadCmd,

472 std::list &Elements) {

475 " LC_DYSYMTAB cmdsize too small");

476 if (*DysymtabLoadCmd != nullptr)

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

478 auto DysymtabOrErr =

480 if (!DysymtabOrErr)

481 return DysymtabOrErr.takeError();

485 " has incorrect cmdsize");

486 uint64_t FileSize = Obj.getData().size();

487 if (Dysymtab.tocoff > FileSize)

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

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

490 "the file");

493 BigSize += Dysymtab.tocoff;

494 if (BigSize > FileSize)

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

496 "dylib_table_of_contents) of LC_DYSYMTAB command " +

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

498 "the file");

500 Dysymtab.ntoc * sizeof(struct

502 "table of contents"))

503 return Err;

504 if (Dysymtab.modtaboff > FileSize)

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

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

507 "the file");

508 BigSize = Dysymtab.nmodtab;

509 const char *struct_dylib_module_name;

511 if (Obj.is64Bit()) {

513 struct_dylib_module_name = "struct dylib_module_64";

514 } else {

516 struct_dylib_module_name = "struct dylib_module";

517 }

518 BigSize *= sizeof_modtab;

520 if (BigSize > FileSize)

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

522 Twine(struct_dylib_module_name) + ") of LC_DYSYMTAB "

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

524 "past the end of the file");

526 Dysymtab.nmodtab * sizeof_modtab,

527 "module table"))

528 return Err;

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

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

532 "the file");

536 if (BigSize > FileSize)

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

538 "sizeof(struct dylib_reference) of LC_DYSYMTAB "

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

540 "past the end of the file");

544 "reference table"))

545 return Err;

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

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

549 "the file");

553 if (BigSize > FileSize)

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

555 "sizeof(uint32_t) of LC_DYSYMTAB command " +

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

557 "the file");

561 "indirect table"))

562 return Err;

563 if (Dysymtab.extreloff > FileSize)

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

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

566 "the file");

567 BigSize = Dysymtab.nextrel;

570 if (BigSize > FileSize)

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

572 "(struct relocation_info) of LC_DYSYMTAB command " +

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

574 "the file");

578 "external relocation table"))

579 return Err;

580 if (Dysymtab.locreloff > FileSize)

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

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

583 "the file");

584 BigSize = Dysymtab.nlocrel;

587 if (BigSize > FileSize)

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

589 "(struct relocation_info) of LC_DYSYMTAB command " +

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

591 "the file");

595 "local relocation table"))

596 return Err;

597 *DysymtabLoadCmd = Load.Ptr;

599}

600

604 const char **LoadCmd, const char *CmdName,

605 std::list &Elements,

606 const char *ElementName) {

609 CmdName + " cmdsize too small");

610 if (*LoadCmd != nullptr)

612 auto LinkDataOrError =

614 if (!LinkDataOrError)

615 return LinkDataOrError.takeError();

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

620 uint64_t FileSize = Obj.getData().size();

621 if (LinkData.dataoff > FileSize)

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

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

624 "the file");

626 BigSize += LinkData.datasize;

627 if (BigSize > FileSize)

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

629 Twine(CmdName) + " command " +

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

631 "the file");

633 LinkData.datasize, ElementName))

634 return Err;

635 *LoadCmd = Load.Ptr;

637}

638

642 const char **LoadCmd, const char *CmdName,

643 std::list &Elements) {

646 CmdName + " cmdsize too small");

647 if (*LoadCmd != nullptr)

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

649 "command");

650 auto DyldInfoOrErr =

652 if (!DyldInfoOrErr)

653 return DyldInfoOrErr.takeError();

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

658 uint64_t FileSize = Obj.getData().size();

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

662 "past the end of the file");

665 if (BigSize > FileSize)

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

667 Twine(CmdName) + " command " +

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

669 "the file");

672 "dyld rebase info"))

673 return Err;

674 if (DyldInfo.bind_off > FileSize)

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

677 "past the end of the file");

680 if (BigSize > FileSize)

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

682 Twine(CmdName) + " command " +

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

684 "the file");

687 "dyld bind info"))

688 return Err;

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

692 "past the end of the file");

695 if (BigSize > FileSize)

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

697 Twine(CmdName) + " command " +

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

699 "the file");

702 "dyld weak bind info"))

703 return Err;

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

707 "past the end of the file");

710 if (BigSize > FileSize)

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

712 Twine(CmdName) + " command " +

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

714 "the file");

717 "dyld lazy bind info"))

718 return Err;

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

722 "past the end of the file");

725 if (BigSize > FileSize)

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

727 Twine(CmdName) + " command " +

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

729 "the file");

732 "dyld export info"))

733 return Err;

734 *LoadCmd = Load.Ptr;

736}

737

740 uint32_t LoadCommandIndex, const char *CmdName) {

743 CmdName + " cmdsize too small");

745 if (!CommandOrErr)

746 return CommandOrErr.takeError();

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

751 "the end of the dylib_command struct");

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

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

755 "of the load command");

756

757

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

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

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

762 break;

763 if (i >= D.cmdsize)

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

766 "load command");

768}

769

773 const char **LoadCmd) {

775 "LC_ID_DYLIB"))

776 return Err;

777 if (*LoadCmd != nullptr)

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

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

782 "file type");

783 *LoadCmd = Load.Ptr;

785}

786

789 uint32_t LoadCommandIndex, const char *CmdName) {

792 CmdName + " cmdsize too small");

794 if (!CommandOrErr)

795 return CommandOrErr.takeError();

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

800 "the end of the dylinker_command struct");

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

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

804 "of the load command");

805

806

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

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

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

811 break;

812 if (i >= D.cmdsize)

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

815 "load command");

817}

818

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

825 CmdName + " has incorrect cmdsize");

826 if (*LoadCmd != nullptr)

827 return malformedError("more than one LC_VERSION_MIN_MACOSX, "

828 "LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS or "

829 "LC_VERSION_MIN_WATCHOS command");

830 *LoadCmd = Load.Ptr;

832}

833

837 std::list &Elements) {

840 " LC_NOTE has incorrect cmdsize");

842 if (!NoteCmdOrErr)

843 return NoteCmdOrErr.takeError();

845 uint64_t FileSize = Obj.getData().size();

846 if (Nt.offset > FileSize)

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

848 Twine(LoadCommandIndex) + " extends "

849 "past the end of the file");

851 BigSize += Nt.size;

852 if (BigSize > FileSize)

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

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

855 "the file");

857 "LC_NOTE data"))

858 return Err;

860}

861

867 auto BVCOrErr =

869 if (!BVCOrErr)

870 return BVCOrErr.takeError();

872 if (Load.C.cmdsize !=

876 " LC_BUILD_VERSION_COMMAND has incorrect cmdsize");

877

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

882

884}

885

891 " LC_RPATH cmdsize too small");

893 if (!ROrErr)

894 return ROrErr.takeError();

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

899 "the end of the rpath_command struct");

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

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

903 "of the load command");

904

905

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

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

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

910 break;

911 if (i >= R.cmdsize)

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

914 "load command");

916}

917

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

923 if (*LoadCmd != nullptr)

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

925 "LC_ENCRYPTION_INFO_64 command");

926 uint64_t FileSize = Obj.getData().size();

927 if (cryptoff > FileSize)

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

930 "past the end of the file");

932 BigSize += cryptsize;

933 if (BigSize > FileSize)

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

935 Twine(CmdName) + " command " +

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

937 "the file");

938 *LoadCmd = Load.Ptr;

940}

941

947 " LC_LINKER_OPTION cmdsize too small");

948 auto LinkOptionOrErr =

950 if (!LinkOptionOrErr)

951 return LinkOptionOrErr.takeError();

953

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

958 while (left > 0) {

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

960 string++;

961 left--;

962 }

963 if (left > 0) {

964 i++;

966 if (0xffffffff == NullPos)

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

969 " is not NULL terminated");

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

971 string += len;

972 left -= len;

973 }

974 }

975 if (L.count != i)

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

978 " does not match number of strings");

980}

981

984 uint32_t LoadCommandIndex, const char *CmdName,

985 size_t SizeOfCmd, const char *CmdStructName,

986 uint32_t PathOffset, const char *PathFieldName) {

987 if (PathOffset < SizeOfCmd)

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

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

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

993 CmdName + " " + PathFieldName + ".offset field "

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

995

996

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

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

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

1001 break;

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

1004 CmdName + " " + PathFieldName + " name extends past "

1005 "the end of the load command");

1007}

1008

1012 const char *CmdName) {

1015 CmdName + " cmdsize too small");

1016 auto ThreadCommandOrErr =

1018 if (!ThreadCommandOrErr)

1019 return ThreadCommandOrErr.takeError();

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

1025 while (state < end) {

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

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

1029 "command");

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

1035

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

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

1039 "command");

1045

1050 " count not x86_THREAD_STATE32_COUNT for "

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

1052 "a x86_THREAD_STATE32 flavor in " + CmdName +

1053 " command");

1056 " x86_THREAD_STATE32 extends past end of "

1057 "command in " + CmdName + " command");

1059 } else {

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

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

1063 CmdName + " command");

1064 }

1069 " count not x86_THREAD_STATE_COUNT for "

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

1071 "a x86_THREAD_STATE flavor in " + CmdName +

1072 " command");

1075 " x86_THREAD_STATE extends past end of "

1076 "command in " + CmdName + " command");

1081 " count not x86_FLOAT_STATE_COUNT for "

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

1083 "a x86_FLOAT_STATE flavor in " + CmdName +

1084 " command");

1087 " x86_FLOAT_STATE extends past end of "

1088 "command in " + CmdName + " command");

1093 " count not x86_EXCEPTION_STATE_COUNT for "

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

1095 "a x86_EXCEPTION_STATE flavor in " + CmdName +

1096 " command");

1099 " x86_EXCEPTION_STATE extends past end of "

1100 "command in " + CmdName + " command");

1105 " count not x86_THREAD_STATE64_COUNT for "

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

1107 "a x86_THREAD_STATE64 flavor in " + CmdName +

1108 " command");

1111 " x86_THREAD_STATE64 extends past end of "

1112 "command in " + CmdName + " command");

1117 " count not x86_EXCEPTION_STATE64_COUNT for "

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

1119 "a x86_EXCEPTION_STATE64 flavor in " + CmdName +

1120 " command");

1123 " x86_EXCEPTION_STATE64 extends past end of "

1124 "command in " + CmdName + " command");

1126 } else {

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

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

1130 CmdName + " command");

1131 }

1136 " count not ARM_THREAD_STATE_COUNT for "

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

1138 "a ARM_THREAD_STATE flavor in " + CmdName +

1139 " command");

1142 " ARM_THREAD_STATE extends past end of "

1143 "command in " + CmdName + " command");

1145 } else {

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

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

1149 CmdName + " command");

1150 }

1156 " count not ARM_THREAD_STATE64_COUNT for "

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

1158 "a ARM_THREAD_STATE64 flavor in " + CmdName +

1159 " command");

1162 " ARM_THREAD_STATE64 extends past end of "

1163 "command in " + CmdName + " command");

1165 } else {

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

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

1169 CmdName + " command");

1170 }

1175 " count not PPC_THREAD_STATE_COUNT for "

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

1177 "a PPC_THREAD_STATE flavor in " + CmdName +

1178 " command");

1181 " PPC_THREAD_STATE extends past end of "

1182 "command in " + CmdName + " command");

1184 } else {

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

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

1188 CmdName + " command");

1189 }

1190 } else {

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

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

1194 }

1195 nflavor++;

1196 }

1198}

1199

1202 &Load,

1204 const char **LoadCmd,

1205 std::list &Elements) {

1208 " LC_TWOLEVEL_HINTS has incorrect cmdsize");

1209 if (*LoadCmd != nullptr)

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

1212 if(!HintsOrErr)

1213 return HintsOrErr.takeError();

1215 uint64_t FileSize = Obj.getData().size();

1216 if (Hints.offset > FileSize)

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

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

1219 "the file");

1222 BigSize += Hints.offset;

1223 if (BigSize > FileSize)

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

1225 "twolevel_hint) field of LC_TWOLEVEL_HINTS command " +

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

1227 "the file");

1230 "two level hints"))

1231 return Err;

1232 *LoadCmd = Load.Ptr;

1234}

1235

1236

1237

1238

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

1241 cmd == MachO::LC_LOADFVMLIB ||

1242 cmd == MachO::LC_IDFVMLIB ||

1243 cmd == MachO::LC_IDENT ||

1244 cmd == MachO::LC_FVMFILE ||

1245 cmd == MachO::LC_PREPAGE ||

1246 cmd == MachO::LC_PREBOUND_DYLIB ||

1247 cmd == MachO::LC_TWOLEVEL_HINTS ||

1248 cmd == MachO::LC_PREBIND_CKSUM)

1249 return true;

1250 return false;

1251}

1252

1255 bool Is64Bits, uint32_t UniversalCputype,

1257 size_t MachOFilesetEntryOffset) {

1259 std::unique_ptr Obj(new MachOObjectFile(

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

1261 UniversalIndex, MachOFilesetEntryOffset));

1262 if (Err)

1263 return std::move(Err);

1264 return std::move(Obj);

1265}

1266

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

1268 bool Is64bits, Error &Err,

1271 size_t MachOFilesetEntryOffset)

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

1273 MachOFilesetEntryOffset(MachOFilesetEntryOffset) {

1281 } else {

1284 cputype = Header.cputype;

1285 }

1286 if (Err)

1287 return;

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

1291 return;

1292 }

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

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

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

1296 "object file's mach header");

1297 return;

1298 }

1299 std::list Elements;

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

1301

1304 if (LoadCommandCount != 0) {

1306 Load = *LoadOrErr;

1307 else {

1308 Err = LoadOrErr.takeError();

1309 return;

1310 }

1311 }

1312

1313 const char *DyldIdLoadCmd = nullptr;

1314 const char *SplitInfoLoadCmd = nullptr;

1315 const char *CodeSignDrsLoadCmd = nullptr;

1316 const char *CodeSignLoadCmd = nullptr;

1317 const char *VersLoadCmd = nullptr;

1318 const char *SourceLoadCmd = nullptr;

1319 const char *EntryPointLoadCmd = nullptr;

1320 const char *EncryptLoadCmd = nullptr;

1321 const char *RoutinesLoadCmd = nullptr;

1322 const char *UnixThreadLoadCmd = nullptr;

1323 const char *TwoLevelHintsLoadCmd = nullptr;

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

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

1327

1328

1329

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

1332 Err = malformedError("load command " + Twine(I) + " cmdsize not a "

1333 "multiple of 8");

1334 return;

1335 }

1336 }

1337 } else {

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

1339 Err = malformedError("load command " + Twine(I) + " cmdsize not a "

1340 "multiple of 4");

1341 return;

1342 }

1343 }

1344 LoadCommands.push_back(Load);

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

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

1347 return;

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

1350 Elements)))

1351 return;

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

1354 "LC_DATA_IN_CODE", Elements,

1355 "data in code info")))

1356 return;

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

1359 "LC_LINKER_OPTIMIZATION_HINT",

1360 Elements, "linker optimization "

1361 "hints")))

1362 return;

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

1365 "LC_FUNCTION_STARTS", Elements,

1366 "function starts data")))

1367 return;

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

1370 "LC_SEGMENT_SPLIT_INFO", Elements,

1371 "split info data")))

1372 return;

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

1375 "LC_DYLIB_CODE_SIGN_DRS", Elements,

1376 "code signing RDs data")))

1377 return;

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

1380 "LC_CODE_SIGNATURE", Elements,

1381 "code signature data")))

1382 return;

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

1385 "LC_DYLD_INFO", Elements)))

1386 return;

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

1389 "LC_DYLD_INFO_ONLY", Elements)))

1390 return;

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

1393 *this, Load, I, &DyldChainedFixupsLoadCmd,

1394 "LC_DYLD_CHAINED_FIXUPS", Elements, "chained fixups")))

1395 return;

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

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

1399 Elements, "exports trie")))

1400 return;

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

1402 if (Load.C.cmdsize != sizeof(MachO::uuid_command)) {

1403 Err = malformedError("LC_UUID command " + Twine(I) + " has incorrect "

1404 "cmdsize");

1405 return;

1406 }

1407 if (UuidLoadCmd) {

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

1409 return;

1410 }

1411 UuidLoadCmd = Load.Ptr;

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

1414 MachO::section_64>(

1415 *this, Load, Sections, HasPageZeroSegment, I,

1416 "LC_SEGMENT_64", SizeOfHeaders, Elements)))

1417 return;

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

1420 MachO::section>(

1421 *this, Load, Sections, HasPageZeroSegment, I,

1422 "LC_SEGMENT", SizeOfHeaders, Elements)))

1423 return;

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

1426 return;

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

1429 return;

1430 Libraries.push_back(Load.Ptr);

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

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

1433 return;

1434 Libraries.push_back(Load.Ptr);

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

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

1437 return;

1438 Libraries.push_back(Load.Ptr);

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

1441 return;

1442 Libraries.push_back(Load.Ptr);

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

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

1445 return;

1446 Libraries.push_back(Load.Ptr);

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

1449 return;

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

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

1452 return;

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

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

1455 return;

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

1458 "LC_VERSION_MIN_MACOSX")))

1459 return;

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

1462 "LC_VERSION_MIN_IPHONEOS")))

1463 return;

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

1466 "LC_VERSION_MIN_TVOS")))

1467 return;

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

1470 "LC_VERSION_MIN_WATCHOS")))

1471 return;

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

1474 return;

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

1477 return;

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

1480 return;

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

1482 if (Load.C.cmdsize != sizeof(MachO::source_version_command)) {

1483 Err = malformedError("LC_SOURCE_VERSION command " + Twine(I) +

1484 " has incorrect cmdsize");

1485 return;

1486 }

1487 if (SourceLoadCmd) {

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

1489 return;

1490 }

1491 SourceLoadCmd = Load.Ptr;

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

1493 if (Load.C.cmdsize != sizeof(MachO::entry_point_command)) {

1495 " has incorrect cmdsize");

1496 return;

1497 }

1498 if (EntryPointLoadCmd) {

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

1500 return;

1501 }

1502 EntryPointLoadCmd = Load.Ptr;

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

1504 if (Load.C.cmdsize != sizeof(MachO::encryption_info_command)) {

1505 Err = malformedError("LC_ENCRYPTION_INFO command " + Twine(I) +

1506 " has incorrect cmdsize");

1507 return;

1508 }

1509 MachO::encryption_info_command E =

1512 &EncryptLoadCmd, "LC_ENCRYPTION_INFO")))

1513 return;

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

1515 if (Load.C.cmdsize != sizeof(MachO::encryption_info_command_64)) {

1516 Err = malformedError("LC_ENCRYPTION_INFO_64 command " + Twine(I) +

1517 " has incorrect cmdsize");

1518 return;

1519 }

1520 MachO::encryption_info_command_64 E =

1523 &EncryptLoadCmd, "LC_ENCRYPTION_INFO_64")))

1524 return;

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

1527 return;

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

1529 if (Load.C.cmdsize < sizeof(MachO::sub_framework_command)) {

1531 " LC_SUB_FRAMEWORK cmdsize too small");

1532 return;

1533 }

1534 MachO::sub_framework_command S =

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

1537 sizeof(MachO::sub_framework_command),

1538 "sub_framework_command", S.umbrella,

1539 "umbrella")))

1540 return;

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

1542 if (Load.C.cmdsize < sizeof(MachO::sub_umbrella_command)) {

1544 " LC_SUB_UMBRELLA cmdsize too small");

1545 return;

1546 }

1547 MachO::sub_umbrella_command S =

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

1550 sizeof(MachO::sub_umbrella_command),

1552 "sub_umbrella")))

1553 return;

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

1555 if (Load.C.cmdsize < sizeof(MachO::sub_library_command)) {

1557 " LC_SUB_LIBRARY cmdsize too small");

1558 return;

1559 }

1560 MachO::sub_library_command S =

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

1563 sizeof(MachO::sub_library_command),

1565 "sub_library")))

1566 return;

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

1568 if (Load.C.cmdsize < sizeof(MachO::sub_client_command)) {

1570 " LC_SUB_CLIENT cmdsize too small");

1571 return;

1572 }

1573 MachO::sub_client_command S =

1576 sizeof(MachO::sub_client_command),

1577 "sub_client_command", S.client, "client")))

1578 return;

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

1580 if (Load.C.cmdsize != sizeof(MachO::routines_command)) {

1581 Err = malformedError("LC_ROUTINES command " + Twine(I) +

1582 " has incorrect cmdsize");

1583 return;

1584 }

1585 if (RoutinesLoadCmd) {

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

1587 "command");

1588 return;

1589 }

1590 RoutinesLoadCmd = Load.Ptr;

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

1592 if (Load.C.cmdsize != sizeof(MachO::routines_command_64)) {

1593 Err = malformedError("LC_ROUTINES_64 command " + Twine(I) +

1594 " has incorrect cmdsize");

1595 return;

1596 }

1597 if (RoutinesLoadCmd) {

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

1599 "command");

1600 return;

1601 }

1602 RoutinesLoadCmd = Load.Ptr;

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

1605 return;

1606 if (UnixThreadLoadCmd) {

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

1608 return;

1609 }

1610 UnixThreadLoadCmd = Load.Ptr;

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

1613 return;

1614

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

1617 &TwoLevelHintsLoadCmd, Elements)))

1618 return;

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

1620

1621 continue;

1623 Err = malformedError("load command " + Twine(I) + " for cmd value of: " +

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

1625 "supported");

1626 return;

1627 }

1628

1629

1630

1631 if (I < LoadCommandCount - 1) {

1633 Load = *LoadOrErr;

1634 else {

1635 Err = LoadOrErr.takeError();

1636 return;

1637 }

1638 }

1639 }

1640 if (!SymtabLoadCmd) {

1641 if (DysymtabLoadCmd) {

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

1643 "LC_SYMTAB load command");

1644 return;

1645 }

1646 } else if (DysymtabLoadCmd) {

1647 MachO::symtab_command Symtab =

1649 MachO::dysymtab_command Dysymtab =

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

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

1654 return;

1655 }

1656 uint64_t BigSize = Dysymtab.ilocalsym;

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

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

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

1661 return;

1662 }

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

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

1666 return;

1667 }

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

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

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

1673 "table");

1674 return;

1675 }

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

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

1679 return;

1680 }

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

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

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

1686 return;

1687 }

1688 }

1691 DyldIdLoadCmd == nullptr) {

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

1693 "filetype");

1694 return;

1695 }

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

1697

1699}

1700

1705 Flags = H_64.flags;

1706 } else {

1708 Flags = H.flags;

1709 }

1718 DataRefImpl SymDRI = Symbol.getRawDataRefImpl();

1721 NType = STE_64.n_type;

1722 NSect = STE_64.n_sect;

1723 NDesc = STE_64.n_desc;

1724 NStrx = STE_64.n_strx;

1725 NValue = STE_64.n_value;

1726 } else {

1733 }

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

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

1739 }

1741 if (NValue >= S.strsize)

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

1744 "index " + Twine(SymbolIndex));

1745 }

1750 if (LibraryOrdinal != 0 &&

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

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

1756 }

1757 }

1758 }

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

1762 "index " + Twine(SymbolIndex));

1763 SymbolIndex++;

1764 }

1766}

1767

1774

1778 if (Entry.n_strx == 0)

1779

1780

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

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

1786 }

1788}

1789

1795

1799 return Entry.n_value;

1800 }

1802 return Entry.n_value;

1803}

1804

1805

1806

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

1818 return std::error_code();

1819}

1820

1823}

1824

1828

1834 }

1835 return 0;

1836}

1837

1841

1845 uint8_t n_type = Entry.n_type;

1846

1847

1850

1856 if (!SecOrError)

1864 }

1866}

1867

1870

1871 uint8_t MachOType = Entry.n_type;

1872 uint16_t MachOFlags = Entry.n_desc;

1873

1875

1878

1881

1887 else

1889 }

1890

1893 else

1895

1898

1901

1904

1907

1908 return Result;

1909}

1910

1914 uint8_t index = Entry.n_sect;

1915

1916 if (index == 0)

1919 DRI.d.a = index - 1;

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

1923 }

1925}

1926

1930 return Entry.n_sect - 1;

1931}

1932

1936

1941

1947

1949 return Sec.d.a;

1950}

1951

1953

1954

1955

1956

1957 uint32_t SectOffset, SectType;

1959

1962 SectOffset = Sect.offset;

1963 SectSize = Sect.size;

1965 } else {

1967 SectOffset = Sect.offset;

1968 SectSize = Sect.size;

1970 }

1972 return SectSize;

1974 if (SectOffset > FileSize)

1975 return 0;

1976 if (FileSize - SectOffset < SectSize)

1977 return FileSize - SectOffset;

1978 return SectSize;

1979}

1980

1985

1990

1995

1996

1997

1998

1999

2000

2001 uint64_t PrevTrueOffset = 0;

2002 uint64_t SectOffsetAdjust = 0;

2003 for (uint32_t SectIdx = 0; SectIdx < Sec.d.a; ++SectIdx) {

2007 if ((SectOffsetAdjust > 0) && (PrevTrueOffset > CurrTrueOffset))

2008 return malformedError("section data exceeds 4GB and section file "

2009 "offsets are not ordered");

2010 const uint64_t EndSectFileOffset =

2012 if (EndSectFileOffset > UINT32_MAX)

2013 SectOffsetAdjust += EndSectFileOffset & 0xFFFFFFFF00000000ull;

2014 PrevTrueOffset = CurrTrueOffset;

2015 }

2016 Offset += SectOffsetAdjust;

2017 } else {

2021 }

2022

2024}

2025

2031 } else {

2034 }

2035

2037}

2038

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

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

2042

2044 DRI.d.a = SectionIndex - 1;

2046}

2047

2050 auto NameOrErr = Section.getName();

2051 if (!NameOrErr)

2052 return NameOrErr.takeError();

2054 return Section;

2055 }

2057}

2058

2062

2067

2075

2083

2086 if (!SectionNameOrErr) {

2087

2089 return false;

2090 }

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

2096}

2097

2098namespace {

2099template

2104 if (!SegmentOrErr) {

2106 return {};

2107 }

2108 auto &Segment = SegmentOrErr.get();

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

2112 return {};

2113}

2114

2115template

2116ArrayRef<uint8_t> getSegmentContents(const MachOObjectFile &Obj,

2117 MachOObjectFile::LoadCommandInfo LoadCmd) {

2119 if (!SegmentOrErr) {

2121 return {};

2122 }

2123 auto &Segment = SegmentOrErr.get();

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

2126}

2127}

2128

2129ArrayRef<uint8_t>

2133 switch (LoadCmd.C.cmd) {

2134 case MachO::LC_SEGMENT:

2136 SegmentName);

2137 break;

2138 case MachO::LC_SEGMENT_64:

2140 SegmentName);

2141 break;

2142 default:

2143 continue;

2144 }

2145 if (!Contents.empty())

2146 return Contents;

2147 }

2148 return {};

2149}

2150

2153 size_t Idx = 0;

2155 switch (LoadCmd.C.cmd) {

2156 case MachO::LC_SEGMENT:

2157 if (Idx == SegmentIndex)

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

2159 ++Idx;

2160 break;

2161 case MachO::LC_SEGMENT_64:

2162 if (Idx == SegmentIndex)

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

2164 ++Idx;

2165 break;

2166 default:

2167 continue;

2168 }

2169 }

2170 return {};

2171}

2172

2176

2183

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

2188 return false;

2189}

2190

2196

2199 Ret.d.a = Sec.d.a;

2200 Ret.d.b = 0;

2202}

2203

2210 } else {

2213 }

2214

2216 Ret.d.a = Sec.d.a;

2217 Ret.d.b = Num;

2219}

2220

2223

2224 Ret.d.a = 0;

2225 Ret.d.b = 0;

2227}

2228

2232

2233 Ret.d.a = 0;

2234 Ret.d.b = DysymtabLoadCmd.nextrel;

2236}

2237

2240

2241 Ret.d.a = 1;

2242 Ret.d.b = 0;

2244}

2245

2249

2250 Ret.d.a = 1;

2251 Ret.d.b = DysymtabLoadCmd.nlocrel;

2253}

2254

2258

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

2265}

2266

2272

2275 if (!isExtern)

2277

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

2286}

2287

2292

2297

2302

2303 unsigned Arch = this->getArch();

2304

2305 switch (Arch) {

2307 static const char *const Table[] = {

2308 "GENERIC_RELOC_VANILLA",

2309 "GENERIC_RELOC_PAIR",

2310 "GENERIC_RELOC_SECTDIFF",

2311 "GENERIC_RELOC_PB_LA_PTR",

2312 "GENERIC_RELOC_LOCAL_SECTDIFF",

2313 "GENERIC_RELOC_TLV" };

2314

2315 if (RType > 5)

2316 res = "Unknown";

2317 else

2318 res = Table[RType];

2319 break;

2320 }

2322 static const char *const Table[] = {

2323 "X86_64_RELOC_UNSIGNED",

2324 "X86_64_RELOC_SIGNED",

2325 "X86_64_RELOC_BRANCH",

2326 "X86_64_RELOC_GOT_LOAD",

2327 "X86_64_RELOC_GOT",

2328 "X86_64_RELOC_SUBTRACTOR",

2329 "X86_64_RELOC_SIGNED_1",

2330 "X86_64_RELOC_SIGNED_2",

2331 "X86_64_RELOC_SIGNED_4",

2332 "X86_64_RELOC_TLV" };

2333

2334 if (RType > 9)

2335 res = "Unknown";

2336 else

2337 res = Table[RType];

2338 break;

2339 }

2341 static const char *const Table[] = {

2342 "ARM_RELOC_VANILLA",

2343 "ARM_RELOC_PAIR",

2344 "ARM_RELOC_SECTDIFF",

2345 "ARM_RELOC_LOCAL_SECTDIFF",

2346 "ARM_RELOC_PB_LA_PTR",

2347 "ARM_RELOC_BR24",

2348 "ARM_THUMB_RELOC_BR22",

2349 "ARM_THUMB_32BIT_BRANCH",

2350 "ARM_RELOC_HALF",

2351 "ARM_RELOC_HALF_SECTDIFF" };

2352

2353 if (RType > 9)

2354 res = "Unknown";

2355 else

2356 res = Table[RType];

2357 break;

2358 }

2361 static const char *const Table[] = {

2362 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",

2363 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",

2364 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",

2365 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",

2366 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",

2367 "ARM64_RELOC_ADDEND", "ARM64_RELOC_AUTHENTICATED_POINTER"

2368 };

2369

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

2371 res = "Unknown";

2372 else

2373 res = Table[RType];

2374 break;

2375 }

2377 static const char *const Table[] = {

2378 "PPC_RELOC_VANILLA",

2379 "PPC_RELOC_PAIR",

2380 "PPC_RELOC_BR14",

2381 "PPC_RELOC_BR24",

2382 "PPC_RELOC_HI16",

2383 "PPC_RELOC_LO16",

2384 "PPC_RELOC_HA16",

2385 "PPC_RELOC_LO14",

2386 "PPC_RELOC_SECTDIFF",

2387 "PPC_RELOC_PB_LA_PTR",

2388 "PPC_RELOC_HI16_SECTDIFF",

2389 "PPC_RELOC_LO16_SECTDIFF",

2390 "PPC_RELOC_HA16_SECTDIFF",

2391 "PPC_RELOC_JBSR",

2392 "PPC_RELOC_LO14_SECTDIFF",

2393 "PPC_RELOC_LOCAL_SECTDIFF" };

2394

2395 if (RType > 15)

2396 res = "Unknown";

2397 else

2398 res = Table[RType];

2399 break;

2400 }

2402 res = "Unknown";

2403 break;

2404 }

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

2406}

2407

2412

2413

2414

2415

2416

2417

2418

2419

2420

2421

2422

2423

2424

2425

2426

2427

2428

2429

2430

2431

2432

2433

2434

2435

2436

2437

2438

2439

2440

2441

2442

2443

2444

2445

2446

2447

2448

2450 bool &isFramework,

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

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

2454

2455 isFramework = false;

2457

2458

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

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

2461 goto guess_library;

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

2463

2464

2465 Idx = Foo.rfind('_');

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

2467 Suffix = Foo.substr(Idx);

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

2470 else

2471 Foo = Foo.slice(0, Idx);

2472 }

2473

2474

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

2476 if (b == Name.npos)

2477 Idx = 0;

2478 else

2479 Idx = b+1;

2480 F = Name.substr(Idx, Foo.size());

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

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

2483 isFramework = true;

2484 return Foo;

2485 }

2486

2487

2488 if (b == Name.npos)

2489 goto guess_library;

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

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

2492 goto guess_library;

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

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

2495 goto guess_library;

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

2497 if (d == Name.npos)

2498 Idx = 0;

2499 else

2500 Idx = d+1;

2501 F = Name.substr(Idx, Foo.size());

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

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

2504 isFramework = true;

2505 return Foo;

2506 }

2507

2508guess_library:

2509

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

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

2513 Dylib = Name.substr(a);

2514 if (Dylib != ".dylib")

2515 goto guess_qtx;

2516

2517

2518 if (a >= 3) {

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

2520 if (Dot == ".")

2521 a = a - 2;

2522 }

2523

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

2525 if (b == Name.npos)

2526 b = 0;

2527 else

2528 b = b+1;

2529

2530 Idx = Name.rfind('_');

2531 if (Idx != Name.npos && Idx != b) {

2532 Lib = Name.slice(b, Idx);

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

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

2536 Lib = Name.slice(b, a);

2537 }

2538 }

2539 else

2540 Lib = Name.slice(b, a);

2541

2542

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

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

2545 if (Dot == ".")

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

2547 }

2548 return Lib;

2549

2550guess_qtx:

2551 Qtx = Name.substr(a);

2552 if (Qtx != ".qtx")

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

2555 if (b == Name.npos)

2556 Lib = Name.slice(0, a);

2557 else

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

2559

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

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

2562 if (Dot == ".")

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

2564 }

2565 return Lib;

2566}

2567

2568

2569

2570

2571

2572

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

2577

2578

2579

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

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

2582 auto CommandOrErr =

2584 if (!CommandOrErr)

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

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

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

2594 bool isFramework;

2596 if (shortName.empty())

2597 LibrariesShortNames.push_back(Name);

2598 else

2599 LibrariesShortNames.push_back(shortName);

2600 }

2601 }

2602

2603 Res = LibrariesShortNames[Index];

2604 return std::error_code();

2605}

2606

2608 return Libraries.size();

2609}

2610

2617

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

2623

2625}

2626

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

2632

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

2640}

2641

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

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

2652}

2653

2656 if (!SymtabLoadCmd)

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

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

2663 return Index;

2664}

2665

2670

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

2675}

2676

2678 return is64Bit() ? 8 : 4;

2679}

2680

2682 unsigned CPUType = getCPUType(*this);

2684 switch (CPUType) {

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

2688 return "Mach-O arm";

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

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

2693 default:

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

2695 }

2696 }

2697

2698 switch (CPUType) {

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

2702 return "Mach-O arm64";

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

2705 default:

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

2707 }

2708}

2709

2711 switch (CPUType) {

2726 default:

2728 }

2729}

2730

2732 const char **McpuDefault,

2733 const char **ArchFlag) {

2734 if (McpuDefault)

2735 *McpuDefault = nullptr;

2736 if (ArchFlag)

2737 *ArchFlag = nullptr;

2738

2739 switch (CPUType) {

2743 if (ArchFlag)

2744 *ArchFlag = "i386";

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

2746 default:

2748 }

2752 if (ArchFlag)

2753 *ArchFlag = "x86_64";

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

2756 if (ArchFlag)

2757 *ArchFlag = "x86_64h";

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

2759 default:

2761 }

2765 if (ArchFlag)

2766 *ArchFlag = "armv4t";

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

2769 if (ArchFlag)

2770 *ArchFlag = "armv5e";

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

2773 if (ArchFlag)

2774 *ArchFlag = "xscale";

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

2777 if (ArchFlag)

2778 *ArchFlag = "armv6";

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

2781 if (McpuDefault)

2782 *McpuDefault = "cortex-m0";

2783 if (ArchFlag)

2784 *ArchFlag = "armv6m";

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

2787 if (ArchFlag)

2788 *ArchFlag = "armv7";

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

2791 if (McpuDefault)

2792 *McpuDefault = "cortex-m4";

2793 if (ArchFlag)

2794 *ArchFlag = "armv7em";

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

2797 if (McpuDefault)

2798 *McpuDefault = "cortex-a7";

2799 if (ArchFlag)

2800 *ArchFlag = "armv7k";

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

2803 if (McpuDefault)

2804 *McpuDefault = "cortex-m3";

2805 if (ArchFlag)

2806 *ArchFlag = "armv7m";

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

2809 if (McpuDefault)

2810 *McpuDefault = "cortex-a7";

2811 if (ArchFlag)

2812 *ArchFlag = "armv7s";

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

2814 default:

2816 }

2820 if (McpuDefault)

2821 *McpuDefault = "cyclone";

2822 if (ArchFlag)

2823 *ArchFlag = "arm64";

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

2826 if (McpuDefault)

2827 *McpuDefault = "apple-a12";

2828 if (ArchFlag)

2829 *ArchFlag = "arm64e";

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

2831 default:

2833 }

2837 if (McpuDefault)

2838 *McpuDefault = "cyclone";

2839 if (ArchFlag)

2840 *ArchFlag = "arm64_32";

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

2842 default:

2844 }

2848 if (ArchFlag)

2849 *ArchFlag = "ppc";

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

2851 default:

2853 }

2857 if (ArchFlag)

2858 *ArchFlag = "ppc64";

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

2860 default:

2862 }

2863 default:

2865 }

2866}

2867

2871

2876

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

2879 "i386",

2880 "x86_64",

2881 "x86_64h",

2882 "armv4t",

2883 "arm",

2884 "armv5e",

2885 "armv6",

2886 "armv6m",

2887 "armv7",

2888 "armv7em",

2889 "armv7k",

2890 "armv7m",

2891 "armv7s",

2892 "arm64",

2893 "arm64e",

2894 "arm64_32",

2895 "ppc",

2896 "ppc64",

2897 }};

2898

2899 return ValidArchs;

2900}

2901

2905

2909

2912 DRI.d.a = Index;

2914}

2915

2918 DRI.d.a = Index;

2920}

2921

2924 if (!DataInCodeLoadCmd)

2926

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

2930}

2931

2934 if (!DataInCodeLoadCmd)

2936

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

2941}

2942

2945

2946void ExportEntry::moveToFirst() {

2948 pushNode(0);

2949 if (*E)

2950 return;

2951 pushDownUntilBottom();

2952}

2953

2954void ExportEntry::moveToEnd() {

2956 Done = true;

2957}

2958

2960

2961 if (Done || Other.Done)

2962 return (Done == Other.Done);

2963

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

2965 return false;

2966

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

2968 return false;

2969

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

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

2972 return false;

2973 }

2974 return true;

2975}

2976

2981 if (Ptr > Trie.end())

2982 Ptr = Trie.end();

2983 return Result;

2984}

2985

2987 return CumulativeString;

2988}

2989

2991 return Stack.back().Flags;

2992}

2993

2995 return Stack.back().Address;

2996}

2997

2999 return Stack.back().Other;

3000}

3001

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

3004 if (ImportName)

3007}

3008

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

3011}

3012

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

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

3015

3016void ExportEntry::pushNode(uint64_t offset) {

3019 NodeState State(Ptr);

3020 const char *error = nullptr;

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

3026 moveToEnd();

3027 return;

3028 }

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

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

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

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

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

3036 moveToEnd();

3037 return;

3038 }

3039 if (State.IsExportNode) {

3040 const uint8_t *ExportStart = State.Current;

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

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

3046 moveToEnd();

3047 return;

3048 }

3050 if (State.Flags != 0 &&

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

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

3058 moveToEnd();

3059 return;

3060 }

3062 State.Address = 0;

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

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

3068 moveToEnd();

3069 return;

3070 }

3071 if (O != nullptr) {

3072

3073

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

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

3077 Twine((int)O->getLibraryCount()) +

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

3079 moveToEnd();

3080 return;

3081 }

3082 }

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

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

3085 State.Current++;

3086 } else {

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

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

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

3090 "node: 0x" +

3092 " starts past end of trie data");

3093 moveToEnd();

3094 return;

3095 }

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

3097 End++;

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

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

3100 "node: 0x" +

3102 " extends past end of trie data");

3103 moveToEnd();

3104 return;

3105 }

3106 State.Current = End + 1;

3107 }

3108 } else {

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

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

3114 moveToEnd();

3115 return;

3116 }

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

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

3123 moveToEnd();

3124 return;

3125 }

3126 }

3127 }

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

3130 "inconsistent export info size: 0x" +

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

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

3134 moveToEnd();

3135 return;

3136 }

3137 }

3138 State.ChildCount = *Children;

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

3140 *E = malformedError("byte for count of children in export trie data at "

3141 "node: 0x" +

3143 " extends past end of trie data");

3144 moveToEnd();

3145 return;

3146 }

3147 State.Current = Children + 1;

3148 State.NextChildIndex = 0;

3149 State.ParentStringLength = CumulativeString.size();

3150 Stack.push_back(State);

3151}

3152

3153void ExportEntry::pushDownUntilBottom() {

3154 ErrorAsOutParameter ErrAsOutParam(E);

3155 const char *error = nullptr;

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

3157 NodeState &Top = Stack.back();

3158 CumulativeString.resize(Top.ParentStringLength);

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

3160 char C = *Top.Current;

3161 CumulativeString.push_back(C);

3162 }

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

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

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

3167 " extends past end of trie data");

3168 moveToEnd();

3169 return;

3170 }

3171 Top.Current += 1;

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

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

3177 moveToEnd();

3178 return;

3179 }

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

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

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

3184 " back to node: 0x" +

3186 moveToEnd();

3187 return;

3188 }

3189 }

3190 Top.NextChildIndex += 1;

3191 pushNode(childNodeIndex);

3192 if (*E)

3193 return;

3194 }

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

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

3197 "node: 0x" +

3199 moveToEnd();

3200 return;

3201 }

3202}

3203

3204

3205

3206

3207

3208

3209

3210

3211

3212

3213

3214

3215

3216

3217

3218

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

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

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

3223 "node: 0x" +

3225 moveToEnd();

3226 return;

3227 }

3228

3229 Stack.pop_back();

3230 while (!Stack.empty()) {

3231 NodeState &Top = Stack.back();

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

3233 pushDownUntilBottom();

3234

3235 return;

3236 } else {

3237 if (Top.IsExportNode) {

3238

3239 CumulativeString.resize(Top.ParentStringLength);

3240 return;

3241 }

3242 Stack.pop_back();

3243 }

3244 }

3245 Done = true;

3246}

3247

3250 const MachOObjectFile *O) {

3252 if (Trie.empty())

3253 Start.moveToEnd();

3254 else

3255 Start.moveToFirst();

3256

3258 Finish.moveToEnd();

3259

3261}

3262

3265 if (DyldInfoLoadCmd)

3267 else if (DyldExportsTrieLoadCmd)

3269

3270 return exports(Err, Trie, this);

3271}

3272

3275 : E(E), O(O) {

3276

3277 for (const auto &Command : O->load_commands()) {

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

3279 MachO::segment_command SLC = O->getSegmentLoadCommand(Command);

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

3281 TextAddress = SLC.vmaddr;

3282 break;

3283 }

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

3285 MachO::segment_command_64 SLC_64 = O->getSegment64LoadCommand(Command);

3286 if (StringRef(SLC_64.segname) == "__TEXT") {

3287 TextAddress = SLC_64.vmaddr;

3288 break;

3289 }

3290 }

3291 }

3292}

3293

3295

3299

3303

3307

3311

3315

3317

3319

3321

3323

3325

3334

3336

3338

3341 bool Parse)

3344 if (!Parse)

3345 return;

3346

3347 if (auto FixupTargetsOrErr = O->getDyldChainedFixupTargets()) {

3348 FixupTargets = *FixupTargetsOrErr;

3349 } else {

3350 *E = FixupTargetsOrErr.takeError();

3351 return;

3352 }

3353

3354 if (auto SegmentsOrErr = O->getChainedFixupsSegments()) {

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

3356 } else {

3357 *E = SegmentsOrErr.takeError();

3358 return;

3359 }

3360}

3361

3362void MachOChainedFixupEntry::findNextPageWithFixups() {

3363 auto FindInSegment = [this]() {

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

3367 ++PageIndex;

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

3369 };

3370

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

3372 if (FindInSegment()) {

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

3375 return;

3376 }

3377

3378 InfoSegIndex++;

3379 PageIndex = 0;

3380 }

3381}

3382

3385 if (Segments.empty()) {

3386 Done = true;

3387 return;

3388 }

3389

3390 InfoSegIndex = 0;

3391 PageIndex = 0;

3392

3393 findNextPageWithFixups();

3395}

3396

3400

3403

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

3405 Done = true;

3406 return;

3407 }

3408

3412

3413

3418 " has unsupported chained fixup pointer_format " +

3419 Twine(PointerFormat));

3421 return;

3422 }

3423

3429

3433 " extends past segment's end");

3435 return;

3436 }

3437

3442

3443

3444 assert(O->isLittleEndian() && "big-endian object should have been rejected "

3445 "by getDyldChainedFixupTargets()");

3448 };

3449

3450

3451

3452 bool IsBind = Field(63, 1);

3455 if (IsBind) {

3458

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

3462 " has out-of range import ordinal " +

3463 Twine(ImportOrdinal));

3465 return;

3466 }

3467

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

3473 } else {

3476

3480 }

3481

3482

3483 if (Next != 0) {

3484 PageOffset += 4 * Next;

3485 } else {

3486 ++PageIndex;

3487 findNextPageWithFixups();

3488 }

3489}

3490

3494 return true;

3496 return false;

3497 return InfoSegIndex == Other.InfoSegIndex && PageIndex == Other.PageIndex &&

3498 PageOffset == Other.PageOffset;

3499}

3500

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

3504 PointerSize(is64Bit ? 8 : 4) {}

3505

3506void MachORebaseEntry::moveToFirst() {

3507 Ptr = Opcodes.begin();

3509}

3510

3511void MachORebaseEntry::moveToEnd() {

3512 Ptr = Opcodes.end();

3513 RemainingLoopCount = 0;

3514 Done = true;

3515}

3516

3519

3520 SegmentOffset += AdvanceAmount;

3521 if (RemainingLoopCount) {

3522 --RemainingLoopCount;

3523 return;

3524 }

3525

3526 bool More = true;

3527 while (More) {

3528

3529

3530

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

3532 Done = true;

3533 return;

3534 }

3535

3536

3537 const uint8_t *OpcodeStart = Ptr;

3542 const char *error = nullptr;

3543 switch (Opcode) {

3545 More = false;

3546 Done = true;

3547 moveToEnd();

3549 break;

3551 RebaseType = ImmValue;

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

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

3556 moveToEnd();

3557 return;

3558 }

3560 "mach-o-rebase",

3561 dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "

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

3563 break;

3565 SegmentIndex = ImmValue;

3566 SegmentOffset = readULEB128(&error);

3568 *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +

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

3571 moveToEnd();

3572 return;

3573 }

3574 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,

3575 PointerSize);

3577 *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +

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

3580 moveToEnd();

3581 return;

3582 }

3584 "mach-o-rebase",

3585 dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "

3586 << "SegmentIndex=" << SegmentIndex << ", "

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

3588 << "\n");

3589 break;

3591 SegmentOffset += readULEB128(&error);

3594 " for opcode at: 0x" +

3596 moveToEnd();

3597 return;

3598 }

3599 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,

3600 PointerSize);

3603 " for opcode at: 0x" +

3605 moveToEnd();

3606 return;

3607 }

3609 dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "

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

3611 SegmentOffset) << "\n");

3612 break;

3614 SegmentOffset += ImmValue * PointerSize;

3615 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,

3616 PointerSize);

3618 *E = malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED " +

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

3621 moveToEnd();

3622 return;

3623 }

3625 dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "

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

3627 SegmentOffset) << "\n");

3628 break;

3630 AdvanceAmount = PointerSize;

3631 Skip = 0;

3632 Count = ImmValue;

3633 if (ImmValue != 0)

3634 RemainingLoopCount = ImmValue - 1;

3635 else

3636 RemainingLoopCount = 0;

3637 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,

3638 PointerSize, Count, Skip);

3640 *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " +

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

3643 moveToEnd();

3644 return;

3645 }

3647 "mach-o-rebase",

3648 dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "

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

3650 << ", AdvanceAmount=" << AdvanceAmount

3651 << ", RemainingLoopCount=" << RemainingLoopCount

3652 << "\n");

3653 return;

3655 AdvanceAmount = PointerSize;

3656 Skip = 0;

3659 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +

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

3662 moveToEnd();

3663 return;

3664 }

3666 RemainingLoopCount = Count - 1;

3667 else

3668 RemainingLoopCount = 0;

3669 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,

3670 PointerSize, Count, Skip);

3672 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +

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

3675 moveToEnd();

3676 return;

3677 }

3679 "mach-o-rebase",

3680 dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "

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

3682 << ", AdvanceAmount=" << AdvanceAmount

3683 << ", RemainingLoopCount=" << RemainingLoopCount

3684 << "\n");

3685 return;

3687 Skip = readULEB128(&error);

3689 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +

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

3692 moveToEnd();

3693 return;

3694 }

3695 AdvanceAmount = Skip + PointerSize;

3697 RemainingLoopCount = 0;

3698 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,

3699 PointerSize, Count, Skip);

3701 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +

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

3704 moveToEnd();

3705 return;

3706 }

3708 "mach-o-rebase",

3709 dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "

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

3711 << ", AdvanceAmount=" << AdvanceAmount

3712 << ", RemainingLoopCount=" << RemainingLoopCount

3713 << "\n");

3714 return;

3718 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"

3719 "ULEB " +

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

3722 moveToEnd();

3723 return;

3724 }

3726 RemainingLoopCount = Count - 1;

3727 else

3728 RemainingLoopCount = 0;

3729 Skip = readULEB128(&error);

3731 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"

3732 "ULEB " +

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

3735 moveToEnd();

3736 return;

3737 }

3738 AdvanceAmount = Skip + PointerSize;

3739

3740 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,

3741 PointerSize, Count, Skip);

3743 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"

3744 "ULEB " +

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

3747 moveToEnd();

3748 return;

3749 }

3751 "mach-o-rebase",

3752 dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "

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

3754 << ", AdvanceAmount=" << AdvanceAmount

3755 << ", RemainingLoopCount=" << RemainingLoopCount

3756 << "\n");

3757 return;

3758 default:

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

3762 moveToEnd();

3763 return;

3764 }

3765 }

3766}

3767

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

3772 if (Ptr > Opcodes.end())

3773 Ptr = Opcodes.end();

3774 return Result;

3775}

3776

3778

3780

3782 switch (RebaseType) {

3784 return "pointer";

3786 return "text abs32";

3788 return "text rel32";

3789 }

3790 return "unknown";

3791}

3792

3793

3794

3796 return O->BindRebaseSegmentName(SegmentIndex);

3797}

3798

3799

3800

3802 return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);

3803}

3804

3805

3806

3808 return O->BindRebaseAddress(SegmentIndex, SegmentOffset);

3809}

3810

3812#ifdef EXPENSIVE_CHECKS

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

3814#else

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

3816#endif

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

3818 (RemainingLoopCount == Other.RemainingLoopCount) &&

3819 (Done == Other.Done);

3820}

3821

3825 if (O->BindRebaseSectionTable == nullptr)

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

3828 Start.moveToFirst();

3829

3831 Finish.moveToEnd();

3832

3834}

3835

3839

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

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

3844

3845void MachOBindEntry::moveToFirst() {

3846 Ptr = Opcodes.begin();

3848}

3849

3850void MachOBindEntry::moveToEnd() {

3851 Ptr = Opcodes.end();

3852 RemainingLoopCount = 0;

3853 Done = true;

3854}

3855

3858

3859 SegmentOffset += AdvanceAmount;

3860 if (RemainingLoopCount) {

3861 --RemainingLoopCount;

3862 return;

3863 }

3864

3865 bool More = true;

3866 while (More) {

3867

3868

3869

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

3871 Done = true;

3872 return;

3873 }

3874

3875

3876 const uint8_t *OpcodeStart = Ptr;

3880 int8_t SignExtended;

3881 const uint8_t *SymStart;

3883 const char *error = nullptr;

3884 switch (Opcode) {

3887

3888

3889 bool NotLastEntry = false;

3890 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {

3891 if (*P) {

3892 NotLastEntry = true;

3893 }

3894 }

3895 if (NotLastEntry)

3896 break;

3897 }

3898 More = false;

3899 moveToEnd();

3901 break;

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

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

3907 moveToEnd();

3908 return;

3909 }

3910 Ordinal = ImmValue;

3911 LibraryOrdinalSet = true;

3912 if (ImmValue > O->getLibraryCount()) {

3913 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "

3914 "library ordinal: " +

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

3916 Twine((int)O->getLibraryCount()) +

3917 ") for opcode at: 0x" +

3919 moveToEnd();

3920 return;

3921 }

3923 "mach-o-bind",

3924 dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "

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

3926 break;

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

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

3932 moveToEnd();

3933 return;

3934 }

3935 Ordinal = readULEB128(&error);

3936 LibraryOrdinalSet = true;

3938 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB " +

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

3941 moveToEnd();

3942 return;

3943 }

3944 if (Ordinal > (int)O->getLibraryCount()) {

3945 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "

3946 "library ordinal: " +

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

3948 Twine((int)O->getLibraryCount()) +

3949 ") for opcode at: 0x" +

3951 moveToEnd();

3952 return;

3953 }

3955 "mach-o-bind",

3956 dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "

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

3958 break;

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

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

3964 moveToEnd();

3965 return;

3966 }

3967 if (ImmValue) {

3969 Ordinal = SignExtended;

3971 *E = malformedError("for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown "

3972 "special ordinal: " +

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

3975 moveToEnd();

3976 return;

3977 }

3978 } else

3979 Ordinal = 0;

3980 LibraryOrdinalSet = true;

3982 "mach-o-bind",

3983 dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "

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

3985 break;

3987 Flags = ImmValue;

3988 SymStart = Ptr;

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

3990 ++Ptr;

3991 }

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

3994 "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM "

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

3997 moveToEnd();

3998 return;

3999 }

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

4001 Ptr-SymStart);

4002 ++Ptr;

4004 "mach-o-bind",

4005 dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "

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

4009 return;

4010 }

4011 break;

4013 BindType = ImmValue;

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

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

4018 moveToEnd();

4019 return;

4020 }

4022 "mach-o-bind",

4023 dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "

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

4025 break;

4027 Addend = readSLEB128(&error);

4030 " for opcode at: 0x" +

4032 moveToEnd();

4033 return;

4034 }

4036 "mach-o-bind",

4037 dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "

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

4039 break;

4041 SegmentIndex = ImmValue;

4042 SegmentOffset = readULEB128(&error);

4044 *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +

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

4047 moveToEnd();

4048 return;

4049 }

4050 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,

4051 PointerSize);

4053 *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +

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

4056 moveToEnd();

4057 return;

4058 }

4060 "mach-o-bind",

4061 dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "

4062 << "SegmentIndex=" << SegmentIndex << ", "

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

4064 << "\n");

4065 break;

4067 SegmentOffset += readULEB128(&error);

4070 " for opcode at: 0x" +

4072 moveToEnd();

4073 return;

4074 }

4075 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,

4076 PointerSize);

4079 " for opcode at: 0x" +

4081 moveToEnd();

4082 return;

4083 }

4085 dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "

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

4087 SegmentOffset) << "\n");

4088 break;

4090 AdvanceAmount = PointerSize;

4091 RemainingLoopCount = 0;

4092 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,

4093 PointerSize);

4096 " for opcode at: 0x" +

4098 moveToEnd();

4099 return;

4100 }

4101 if (SymbolName == StringRef()) {

4103 "for BIND_OPCODE_DO_BIND missing preceding "

4104 "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +

4106 moveToEnd();

4107 return;

4108 }

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

4110 *E =

4111 malformedError("for BIND_OPCODE_DO_BIND missing preceding "

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

4114 moveToEnd();

4115 return;

4116 }

4118 dbgs() << "BIND_OPCODE_DO_BIND: "

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

4120 SegmentOffset) << "\n");

4121 return;

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

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

4127 moveToEnd();

4128 return;

4129 }

4130 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,

4131 PointerSize);

4133 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +

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

4136 moveToEnd();

4137 return;

4138 }

4139 if (SymbolName == StringRef()) {

4141 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "

4142 "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode "

4143 "at: 0x" +

4145 moveToEnd();

4146 return;

4147 }

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

4150 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "

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

4153 moveToEnd();

4154 return;

4155 }

4156 AdvanceAmount = readULEB128(&error) + PointerSize;

4158 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +

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

4161 moveToEnd();

4162 return;

4163 }

4164

4165

4166

4167 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +

4168 AdvanceAmount, PointerSize);

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

4171 "ULEB) " +

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

4174 moveToEnd();

4175 return;

4176 }

4177 RemainingLoopCount = 0;

4179 "mach-o-bind",

4180 dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "

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

4182 << ", AdvanceAmount=" << AdvanceAmount

4183 << ", RemainingLoopCount=" << RemainingLoopCount

4184 << "\n");

4185 return;

4188 *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not "

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

4191 moveToEnd();

4192 return;

4193 }

4194 if (SymbolName == StringRef()) {

4196 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "

4197 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "

4198 "opcode at: 0x" +

4200 moveToEnd();

4201 return;

4202 }

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

4205 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "

4206 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "

4207 "at: 0x" +

4209 moveToEnd();

4210 return;

4211 }

4212 AdvanceAmount = ImmValue * PointerSize + PointerSize;

4213 RemainingLoopCount = 0;

4214 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +

4215 AdvanceAmount, PointerSize);

4217 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +

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

4220 moveToEnd();

4221 return;

4222 }

4225 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "

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

4227 return;

4230 *E = malformedError("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not "

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

4233 moveToEnd();

4234 return;

4235 }

4238 RemainingLoopCount = Count - 1;

4239 else

4240 RemainingLoopCount = 0;

4242 *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "

4243 " (count value) " +

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

4246 moveToEnd();

4247 return;

4248 }

4249 Skip = readULEB128(&error);

4250 AdvanceAmount = Skip + PointerSize;

4252 *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "

4253 " (skip value) " +

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

4256 moveToEnd();

4257 return;

4258 }

4259 if (SymbolName == StringRef()) {

4261 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "

4262 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "

4263 "opcode at: 0x" +

4265 moveToEnd();

4266 return;

4267 }

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

4270 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "

4271 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "

4272 "at: 0x" +

4274 moveToEnd();

4275 return;

4276 }

4277 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,

4278 PointerSize, Count, Skip);

4280 *E =

4281 malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +

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

4284 moveToEnd();

4285 return;

4286 }

4288 "mach-o-bind",

4289 dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "

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

4291 << ", AdvanceAmount=" << AdvanceAmount

4292 << ", RemainingLoopCount=" << RemainingLoopCount

4293 << "\n");

4294 return;

4295 default:

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

4299 moveToEnd();

4300 return;

4301 }

4302 }

4303}

4304

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

4309 if (Ptr > Opcodes.end())

4310 Ptr = Opcodes.end();

4311 return Result;

4312}

4313

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

4318 if (Ptr > Opcodes.end())

4319 Ptr = Opcodes.end();

4320 return Result;

4321}

4322

4324

4326

4328 switch (BindType) {

4330 return "pointer";

4332 return "text abs32";

4334 return "text rel32";

4335 }

4336 return "unknown";

4337}

4338

4340

4342

4344

4346

4347

4348

4350 return O->BindRebaseSegmentName(SegmentIndex);

4351}

4352

4353

4354

4356 return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);

4357}

4358

4359

4360

4362 return O->BindRebaseAddress(SegmentIndex, SegmentOffset);

4363}

4364

4366#ifdef EXPENSIVE_CHECKS

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

4368#else

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

4370#endif

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

4372 (RemainingLoopCount == Other.RemainingLoopCount) &&

4373 (Done == Other.Done);

4374}

4375

4376

4378 uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;

4381 for (const SectionRef &Section : Obj->sections()) {

4382 SectionInfo Info;

4384 if (!NameOrErr)

4386 else

4387 Info.SectionName = *NameOrErr;

4388 Info.Address = Section.getAddress();

4389 Info.Size = Section.getSize();

4390 Info.SegmentName =

4391 Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());

4392 if (Info.SegmentName != CurSegName) {

4393 ++CurSegIndex;

4394 CurSegName = Info.SegmentName;

4395 CurSegAddress = Info.Address;

4396 }

4397 Info.SegmentIndex = CurSegIndex - 1;

4398 Info.OffsetInSegment = Info.Address - CurSegAddress;

4399 Info.SegmentStartAddress = CurSegAddress;

4400 Sections.push_back(Info);

4401 }

4402 MaxSegIndex = CurSegIndex;

4403}

4404

4405

4406

4407

4408

4409

4410

4411

4417 if (SegIndex == -1)

4418 return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";

4419 if (SegIndex >= MaxSegIndex)

4420 return "bad segIndex (too large)";

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

4423 uint64_t End = Start + PointerSize;

4424 bool Found = false;

4425 for (const SectionInfo &SI : Sections) {

4426 if (SI.SegmentIndex != SegIndex)

4427 continue;

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

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

4430 Found = true;

4431 break;

4432 }

4433 else

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

4435 }

4436 }

4437 if (!Found)

4438 return "bad offset, not in section";

4439 }

4440 return nullptr;

4441}

4442

4443

4444

4446 for (const SectionInfo &SI : Sections) {

4447 if (SI.SegmentIndex == SegIndex)

4448 return SI.SegmentName;

4449 }

4451}

4452

4453

4454

4455const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(

4456 int32_t SegIndex, uint64_t SegOffset) {

4457 for (const SectionInfo &SI : Sections) {

4458 if (SI.SegmentIndex != SegIndex)

4459 continue;

4460 if (SI.OffsetInSegment > SegOffset)

4461 continue;

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

4463 continue;

4464 return SI;

4465 }

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

4467}

4468

4469

4470

4473 return findSection(SegIndex, SegOffset).SectionName;

4474}

4475

4476

4477

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

4480 return SI.SegmentStartAddress + OffsetInSeg;

4481}

4482

4487 if (O->BindRebaseSectionTable == nullptr)

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

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

4490 Start.moveToFirst();

4491

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

4493 Finish.moveToEnd();

4494

4496}

4497

4502

4507

4512

4514 if (BindRebaseSectionTable == nullptr)

4515 BindRebaseSectionTable = std::make_unique(this);

4516

4518 Start.moveToFirst();

4519

4522

4524}

4525

4528 return LoadCommands.begin();

4529}

4530

4533 return LoadCommands.end();

4534}

4535

4540

4546

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

4550 const section_base *Base =

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

4553}

4554

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

4558 const section_base *Base =

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

4561}

4562

4563bool

4565 const {

4567 return false;

4569}

4570

4574 return RE.r_word1 & 0xffffff;

4576}

4577

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

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

4583}

4584

4587 return RE.r_word0 >> 31;

4588}

4589

4594

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

4598}

4599

4606

4613

4620

4621unsigned

4628

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

4638 DRI.d.a = SecNum - 1;

4640}

4641

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

4645}

4646

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

4650}

4651

4653 unsigned Index) const {

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

4656}

4657

4659 unsigned Index) const {

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

4662}

4663

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

4668}

4669

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

4674}

4675

4680

4685

4690

4695

4700

4705

4710

4715

4720

4725

4730

4735

4740

4745

4750

4755

4760

4765

4770

4775

4780

4785

4790

4795

4800

4806 Sec.d.a = Rel.d.a;

4810 } else {

4813 }

4814 } else {

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

4817 Offset = DysymtabLoadCmd.extreloff;

4818 else

4819 Offset = DysymtabLoadCmd.locreloff;

4820 }

4821

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

4826}

4827

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

4832}

4833

4837

4842

4845 unsigned Index) const {

4848}

4849

4852 unsigned Index) const {

4855}

4856

4858 if (SymtabLoadCmd)

4860

4861

4863 Cmd.cmd = MachO::LC_SYMTAB;

4869 return Cmd;

4870}

4871

4873 if (DysymtabLoadCmd)

4875

4876

4878 Cmd.cmd = MachO::LC_DYSYMTAB;

4887 Cmd.ntoc = 0;

4898 return Cmd;

4899}

4900

4903 if (DataInCodeLoadCmd)

4905

4906

4908 Cmd.cmd = MachO::LC_DATA_IN_CODE;

4912 return Cmd;

4913}

4914

4917 if (LinkOptHintsLoadCmd)

4919

4920

4921

4923 Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;

4927 return Cmd;

4928}

4929

4931 if (!DyldInfoLoadCmd)

4932 return {};

4933

4934 auto DyldInfoOrErr =

4936 if (!DyldInfoOrErr)

4937 return {};

4942}

4943

4945 if (!DyldInfoLoadCmd)

4946 return {};

4947

4948 auto DyldInfoOrErr =

4950 if (!DyldInfoOrErr)

4951 return {};

4956}

4957

4959 if (!DyldInfoLoadCmd)

4960 return {};

4961

4962 auto DyldInfoOrErr =

4964 if (!DyldInfoOrErr)

4965 return {};

4970}

4971

4973 if (!DyldInfoLoadCmd)

4974 return {};

4975

4976 auto DyldInfoOrErr =

4978 if (!DyldInfoOrErr)

4979 return {};

4984}

4985

4987 if (!DyldInfoLoadCmd)

4988 return {};

4989

4990 auto DyldInfoOrErr =

4992 if (!DyldInfoOrErr)

4993 return {};

4998}

4999

5002

5003 if (!DyldChainedFixupsLoadCmd)

5004 return std::nullopt;

5006 *this, DyldChainedFixupsLoadCmd);

5007 if (!DyldChainedFixupsOrErr)

5008 return DyldChainedFixupsOrErr.takeError();

5010 *DyldChainedFixupsOrErr;

5011

5012

5013

5014 if (!DyldChainedFixups.dataoff)

5015 return std::nullopt;

5016 return DyldChainedFixups;

5017}

5018

5022 if (!CFOrErr)

5023 return CFOrErr.takeError();

5024 if (!CFOrErr->has_value())

5025 return std::nullopt;

5026

5028

5031

5032

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

5034 auto CFHeaderOrErr =

5036 if (!CFHeaderOrErr)

5037 return CFHeaderOrErr.takeError();

5039

5040

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

5048

5049

5050

5051

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

5056 " overlaps with chained fixups header");

5057 }

5058 uint32_t EndOffset = CFHeaderOffset + CFSize;

5060 EndOffset) {

5062 Twine(CFImageStartsOffset +

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

5065 }

5066

5067 return CFHeader;

5068}

5069

5073 if (!CFOrErr)

5074 return CFOrErr.takeError();

5075

5076 std::vector Segments;

5077 if (!CFOrErr->has_value())

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

5079

5081

5083 if (!HeaderOrErr)

5084 return HeaderOrErr.takeError();

5085 if (!HeaderOrErr->has_value())

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

5088

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

5090

5092 *this, Contents + Header.starts_offset);

5093 if (!ImageStartsOrErr)

5094 return ImageStartsOrErr.takeError();

5096

5097 const char *SegOffsPtr =

5098 Contents + Header.starts_offset +

5100 const char *SegOffsEnd =

5102 if (SegOffsEnd > Contents + DyldChainedFixups.datasize)

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

5105

5106 const char *LastSegEnd = nullptr;

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

5108 auto OffOrErr =

5110 if (!OffOrErr)

5111 return OffOrErr.takeError();

5112

5113

5114 if (!*OffOrErr)

5115 continue;

5116

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

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

5120 };

5121

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

5123 if (LastSegEnd && SegPtr < LastSegEnd)

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

5125

5126 auto SegOrErr =

5128 if (!SegOrErr)

5129 return SegOrErr.takeError();

5131

5132 LastSegEnd = SegPtr + Seg.size;

5135

5136 const char *PageStart =

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

5139 if (PageEnd > SegPtr + Seg.size)

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

5141

5142

5143

5144 std::vector<uint16_t> PageStarts;

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

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

5150 PageStarts.push_back(Start);

5151 }

5152

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

5154 }

5155

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

5157}

5158

5159

5160

5168

5169template <typename T, unsigned N>

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

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

5174 for (auto &Element : RawValue)

5176 return RawValue;

5177}

5178

5179Expected<std::vector>

5182 if (!CFOrErr)

5183 return CFOrErr.takeError();

5184

5185 std::vector Targets;

5186 if (!CFOrErr->has_value())

5187 return Targets;

5188

5190

5192 if (!CFHeaderOrErr)

5193 return CFHeaderOrErr.takeError();

5194 if (!(*CFHeaderOrErr))

5195 return Targets;

5197

5198 size_t ImportSize = 0;

5205 else

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

5208

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

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

5211 size_t ImportsEndOffset =

5212 Header.imports_offset + ImportSize * Header.imports_count;

5213 const char *ImportsEnd = Contents + ImportsEndOffset;

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

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

5216

5217 if (ImportsEnd > Symbols)

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

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

5220

5221

5222

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

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

5226 ImportPtr += ImportSize) {

5227 int LibOrdinal;

5228 bool WeakImport;

5234

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

5237 NameOffset = RawValue[0] >> 9;

5238 Addend = 0;

5240 static_assert(sizeof(uint64_t) ==

5243

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

5246 NameOffset = RawValue[0] >> 9;

5249 static_assert(2 * sizeof(uint64_t) ==

5252

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

5255 WeakImport = RawValue[0] >> 17;

5256 Addend = RawValue[1];

5257 } else {

5259 }

5260

5261 const char *Str = Symbols + NameOffset;

5262 if (Str >= SymbolsEnd)

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

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

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

5267 }

5268

5269 return std::move(Targets);

5270}

5271

5273 if (!DyldExportsTrieLoadCmd)

5274 return {};

5275

5277 *this, DyldExportsTrieLoadCmd);

5278 if (!DyldExportsTrieOrError)

5279 return {};

5284}

5285

5287 if (!FuncStartsLoadCmd)

5288 return {};

5289

5290 auto InfoOrErr =

5292 if (!InfoOrErr)

5293 return {};

5294

5298 return std::move(FunctionStarts);

5299}

5300

5302 if (!UuidLoadCmd)

5303 return {};

5304

5306 return ArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);

5307}

5308

5313

5318

5322

5326 data += delta;

5328 }

5329}

5330

5334

5335

5336

5337

5338

5339

5340

5341

5344 size_t MachOFilesetEntryOffset) {

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

5348 UniversalIndex, MachOFilesetEntryOffset);

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

5351 UniversalIndex, MachOFilesetEntryOffset);

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

5354 UniversalIndex, MachOFilesetEntryOffset);

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

5357 UniversalIndex, MachOFilesetEntryOffset);

5360}

5361

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

5366}

5367

5371

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

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

5377 bool IsDir;

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

5382 Path.str().c_str());

5383 if (EC)

5385

5386 std::vectorstd::string ObjectPaths;

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

5389 StringRef ObjectPath = Dir->path();

5393 switch (Status.type()) {

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

5398 break;

5399 default: ;

5400 }

5401 }

5402 if (EC)

5404 if (ObjectPaths.empty())

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

5407 Path.str().c_str());

5408 return ObjectPaths;

5409}

5410

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

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

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

5420#undef HANDLE_SWIFT_SECTION

5421}

5422

5424 switch (Arch) {

5438 default:

5439 return false;

5440 }

5441}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

Unify divergent function exit nodes

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

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

#define offsetof(TYPE, MEMBER)

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

Definition MachOObjectFile.cpp:119

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

Definition MachOObjectFile.cpp:819

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

Definition MachOObjectFile.cpp:410

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

Definition MachOObjectFile.cpp:1200

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

Definition MachOObjectFile.cpp:863

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

Definition MachOObjectFile.cpp:174

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

Definition MachOObjectFile.cpp:468

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

Definition MachOObjectFile.cpp:738

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

Definition MachOObjectFile.cpp:84

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

Definition MachOObjectFile.cpp:208

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

Definition MachOObjectFile.cpp:111

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)

Definition MachOObjectFile.cpp:286

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

Definition MachOObjectFile.cpp:639

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

Definition MachOObjectFile.cpp:170

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

Definition MachOObjectFile.cpp:162

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)

Definition MachOObjectFile.cpp:982

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

Definition MachOObjectFile.cpp:886

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

Definition MachOObjectFile.cpp:71

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

Definition MachOObjectFile.cpp:141

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

Definition MachOObjectFile.cpp:97

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

Definition MachOObjectFile.cpp:942

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

Definition MachOObjectFile.cpp:150

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

Definition MachOObjectFile.cpp:5170

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

Definition MachOObjectFile.cpp:146

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

Definition MachOObjectFile.cpp:1009

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)

Definition MachOObjectFile.cpp:601

static Error malformedError(const Twine &Msg)

Definition MachOObjectFile.cpp:63

static bool isLoadCommandObsolete(uint32_t cmd)

Definition MachOObjectFile.cpp:1239

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

Definition MachOObjectFile.cpp:181

static int getEncodedOrdinal(T Value)

Definition MachOObjectFile.cpp:5161

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

Definition MachOObjectFile.cpp:158

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

Definition MachOObjectFile.cpp:253

static StringRef parseSegmentOrSectionName(const char *P)

Definition MachOObjectFile.cpp:124

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

Definition MachOObjectFile.cpp:192

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

Definition MachOObjectFile.cpp:232

static unsigned getCPUType(const MachOObjectFile &O)

Definition MachOObjectFile.cpp:132

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

Definition MachOObjectFile.cpp:787

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

Definition MachOObjectFile.cpp:834

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

Definition MachOObjectFile.cpp:770

static unsigned getCPUSubType(const MachOObjectFile &O)

Definition MachOObjectFile.cpp:136

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)

Definition MachOObjectFile.cpp:918

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

Definition MachOObjectFile.cpp:219

static Error malformedError(Twine Msg)

OptimizedStructLayoutField Field

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...

#define DEBUG_WITH_TYPE(TYPE,...)

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

static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx)

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),...

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...

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.

static constexpr size_t npos

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.

char back() const

back - Get the last character in the string.

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.

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.

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(uint64_t Val)

LLVM Value Representation.

A range adaptor for a pair of iterators.

DataRefImpl getRawDataRefImpl() const

StringRef getData() const

unsigned int getType() const

bool isLittleEndian() const

static unsigned int getMachOType(bool isLE, bool is64Bits)

LLVM_ABI StringRef segmentName(int32_t SegIndex)

Definition MachOObjectFile.cpp:4445

LLVM_ABI StringRef sectionName(int32_t SegIndex, uint64_t SegOffset)

Definition MachOObjectFile.cpp:4471

LLVM_ABI BindRebaseSegInfo(const MachOObjectFile *Obj)

Definition MachOObjectFile.cpp:4377

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

Definition MachOObjectFile.cpp:4412

LLVM_ABI uint64_t address(uint32_t SegIndex, uint64_t SegOffset)

Definition MachOObjectFile.cpp:4478

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...

LLVM_ABI void moveNext()

Definition MachOObjectFile.cpp:3219

LLVM_ABI StringRef name() const

Definition MachOObjectFile.cpp:2986

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

Definition MachOObjectFile.cpp:2943

LLVM_ABI bool operator==(const ExportEntry &) const

Definition MachOObjectFile.cpp:2959

LLVM_ABI StringRef otherName() const

Definition MachOObjectFile.cpp:3002

LLVM_ABI uint64_t address() const

Definition MachOObjectFile.cpp:2994

LLVM_ABI uint64_t flags() const

Definition MachOObjectFile.cpp:2990

LLVM_ABI uint32_t nodeOffset() const

Definition MachOObjectFile.cpp:3009

friend class MachOObjectFile

LLVM_ABI uint64_t other() const

Definition MachOObjectFile.cpp:2998

LLVM_ABI StringRef sectionName() const

Definition MachOObjectFile.cpp:3308

LLVM_ABI uint64_t segmentAddress() const

Definition MachOObjectFile.cpp:3300

LLVM_ABI int32_t segmentIndex() const

Definition MachOObjectFile.cpp:3294

LLVM_ABI uint64_t address() const

Definition MachOObjectFile.cpp:3312

LLVM_ABI void moveNext()

Definition MachOObjectFile.cpp:3337

LLVM_ABI StringRef typeName() const

Definition MachOObjectFile.cpp:3324

LLVM_ABI int64_t addend() const

Definition MachOObjectFile.cpp:3318

LLVM_ABI MachOAbstractFixupEntry(Error *Err, const MachOObjectFile *O)

Definition MachOObjectFile.cpp:3273

uint64_t textAddress() const

LLVM_ABI uint32_t flags() const

Definition MachOObjectFile.cpp:3320

LLVM_ABI StringRef symbolName() const

Definition MachOObjectFile.cpp:3316

LLVM_ABI void moveToFirst()

Definition MachOObjectFile.cpp:3326

LLVM_ABI int ordinal() const

Definition MachOObjectFile.cpp:3322

LLVM_ABI StringRef segmentName() const

Definition MachOObjectFile.cpp:3304

LLVM_ABI void moveToEnd()

Definition MachOObjectFile.cpp:3335

const MachOObjectFile * O

LLVM_ABI uint64_t segmentOffset() const

Definition MachOObjectFile.cpp:3296

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

LLVM_ABI uint32_t flags() const

Definition MachOObjectFile.cpp:4343

LLVM_ABI bool operator==(const MachOBindEntry &) const

Definition MachOObjectFile.cpp:4365

LLVM_ABI void moveNext()

Definition MachOObjectFile.cpp:3856

LLVM_ABI StringRef symbolName() const

Definition MachOObjectFile.cpp:4339

LLVM_ABI int ordinal() const

Definition MachOObjectFile.cpp:4345

LLVM_ABI StringRef sectionName() const

Definition MachOObjectFile.cpp:4355

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

Definition MachOObjectFile.cpp:3840

LLVM_ABI StringRef segmentName() const

Definition MachOObjectFile.cpp:4349

LLVM_ABI uint64_t segmentOffset() const

Definition MachOObjectFile.cpp:4325

LLVM_ABI int64_t addend() const

Definition MachOObjectFile.cpp:4341

LLVM_ABI uint64_t address() const

Definition MachOObjectFile.cpp:4361

friend class MachOObjectFile

LLVM_ABI int32_t segmentIndex() const

Definition MachOObjectFile.cpp:4323

LLVM_ABI StringRef typeName() const

Definition MachOObjectFile.cpp:4327

LLVM_ABI void moveNext()

Definition MachOObjectFile.cpp:3401

LLVM_ABI bool operator==(const MachOChainedFixupEntry &) const

Definition MachOObjectFile.cpp:3491

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

Definition MachOObjectFile.cpp:3339

LLVM_ABI void moveToEnd()

Definition MachOObjectFile.cpp:3397

LLVM_ABI void moveToFirst()

Definition MachOObjectFile.cpp:3383

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

Definition MachOObjectFile.cpp:4777

void moveSectionNext(DataRefImpl &Sec) const override

Definition MachOObjectFile.cpp:1933

ArrayRef< char > getSectionRawFinalSegmentName(DataRefImpl Sec) const

Definition MachOObjectFile.cpp:4556

uint8_t getBytesInAddress() const override

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

Definition MachOObjectFile.cpp:2677

Triple::ArchType getArch() const override

Definition MachOObjectFile.cpp:2902

MachO::mach_header_64 Header64

bool isSectionData(DataRefImpl Sec) const override

Definition MachOObjectFile.cpp:2068

const MachO::mach_header_64 & getHeader64() const

Definition MachOObjectFile.cpp:4838

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

Definition MachOObjectFile.cpp:5180

uint64_t getSectionAlignment(DataRefImpl Sec) const override

Definition MachOObjectFile.cpp:2026

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

Definition MachOObjectFile.cpp:4595

symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override

Definition MachOObjectFile.cpp:2268

Expected< SectionRef > getSection(unsigned SectionIndex) const

Definition MachOObjectFile.cpp:2039

iterator_range< rebase_iterator > rebaseTable(Error &Err)

For use iterating over all rebase table entries.

Definition MachOObjectFile.cpp:3836

std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const

Definition MachOObjectFile.cpp:1807

load_command_iterator begin_load_commands() const

Definition MachOObjectFile.cpp:4527

MachO::encryption_info_command_64 getEncryptionInfoCommand64(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4757

StringRef getFileFormatName() const override

Definition MachOObjectFile.cpp:2681

dice_iterator begin_dices() const

Definition MachOObjectFile.cpp:2922

basic_symbol_iterator symbol_begin() const override

Definition MachOObjectFile.cpp:2618

Expected< std::optional< MachO::linkedit_data_command > > getChainedFixupsLoadCommand() const

Definition MachOObjectFile.cpp:5001

iterator_range< export_iterator > exports(Error &Err) const

For use iterating over all exported symbols.

Definition MachOObjectFile.cpp:3263

uint64_t getSymbolIndex(DataRefImpl Symb) const

Definition MachOObjectFile.cpp:2654

MachO::build_version_command getBuildVersionLoadCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4707

section_iterator section_end() const override

Definition MachOObjectFile.cpp:2671

MachO::build_tool_version getBuildToolVersion(unsigned index) const

Definition MachOObjectFile.cpp:4712

MachO::linkedit_data_command getDataInCodeLoadCommand() const

Definition MachOObjectFile.cpp:4902

MachO::routines_command getRoutinesCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4782

MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const

Definition MachOObjectFile.cpp:4665

unsigned getSymbolSectionID(SymbolRef Symb) const

Definition MachOObjectFile.cpp:1927

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...

Definition MachOObjectFile.cpp:5369

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

Definition MachOObjectFile.cpp:4590

MachO::linker_option_command getLinkerOptionLoadCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4692

uint32_t getLibraryCount() const

Definition MachOObjectFile.cpp:2607

MachO::entry_point_command getEntryPointCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4747

Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override

Definition MachOObjectFile.cpp:1912

uint64_t getRelocationOffset(DataRefImpl Rel) const override

Definition MachOObjectFile.cpp:2259

ArrayRef< uint8_t > getDyldInfoLazyBindOpcodes() const

Definition MachOObjectFile.cpp:4972

void moveSymbolNext(DataRefImpl &Symb) const override

Definition MachOObjectFile.cpp:1768

SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const

Definition MachOObjectFile.cpp:4630

MachO::dysymtab_command getDysymtabLoadCommand() const

Definition MachOObjectFile.cpp:4872

iterator_range< bind_iterator > bindTable(Error &Err)

For use iterating over all bind table entries.

Definition MachOObjectFile.cpp:4498

MachO::mach_header Header

uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override

Definition MachOObjectFile.cpp:1838

relocation_iterator section_rel_begin(DataRefImpl Sec) const override

Definition MachOObjectFile.cpp:2197

MachO::section_64 getSection64(DataRefImpl DRI) const

Definition MachOObjectFile.cpp:4647

MachO::fileset_entry_command getFilesetEntryLoadCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4797

MachO::note_command getNoteLoadCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4702

MachO::thread_command getThreadCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4792

section_iterator section_begin() const override

Definition MachOObjectFile.cpp:2666

Error checkSymbolTable() const

Definition MachOObjectFile.cpp:1701

bool isRelocatableObject() const override

True if this is a relocatable object (.o/.obj).

Definition MachOObjectFile.cpp:5331

MachO::segment_command_64 getSegment64LoadCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4687

relocation_iterator section_rel_end(DataRefImpl Sec) const override

Definition MachOObjectFile.cpp:2205

ArrayRef< uint8_t > getDyldInfoExportsTrie() const

Definition MachOObjectFile.cpp:4986

bool isDebugSection(DataRefImpl Sec) const override

Definition MachOObjectFile.cpp:2084

MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const

Definition MachOObjectFile.cpp:4671

unsigned getSectionType(SectionRef Sec) const

Definition MachOObjectFile.cpp:1790

MachO::segment_command getSegmentLoadCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4682

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)

Definition MachOObjectFile.cpp:1254

StringRef getSectionFinalSegmentName(DataRefImpl Sec) const

Definition MachOObjectFile.cpp:4542

MachO::linkedit_data_command getLinkOptHintsLoadCommand() const

Definition MachOObjectFile.cpp:4916

unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const

Definition MachOObjectFile.cpp:4622

MachO::rpath_command getRpathCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4737

dice_iterator end_dices() const

Definition MachOObjectFile.cpp:2932

MachO::routines_command_64 getRoutinesCommand64(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4787

MachO::sub_framework_command getSubFrameworkCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4762

SmallVector< uint64_t > getFunctionStarts() const

Definition MachOObjectFile.cpp:5286

MachO::sub_library_command getSubLibraryCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4772

MachO::dyld_info_command getDyldInfoLoadCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4722

MachO::sub_umbrella_command getSubUmbrellaCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4767

ArrayRef< uint8_t > getDyldExportsTrie() const

Definition MachOObjectFile.cpp:5272

Expected< uint32_t > getSymbolFlags(DataRefImpl Symb) const override

Definition MachOObjectFile.cpp:1868

section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const

Definition MachOObjectFile.cpp:2612

bool isSectionBSS(DataRefImpl Sec) const override

Definition MachOObjectFile.cpp:2076

Expected< std::pair< size_t, std::vector< ChainedFixupsSegment > > > getChainedFixupsSegments() const

Definition MachOObjectFile.cpp:5071

bool isSectionVirtual(DataRefImpl Sec) const override

Definition MachOObjectFile.cpp:2177

bool getScatteredRelocationScattered(const MachO::any_relocation_info &RE) const

Definition MachOObjectFile.cpp:4585

Expected< StringRef > getSymbolName(DataRefImpl Symb) const override

Definition MachOObjectFile.cpp:1775

bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const

Definition MachOObjectFile.cpp:4578

LoadCommandList::const_iterator load_command_iterator

symbol_iterator getSymbolByIndex(unsigned Index) const

Definition MachOObjectFile.cpp:2642

static Triple getHostArch()

Definition MachOObjectFile.cpp:2868

MachO::encryption_info_command getEncryptionInfoCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4752

const MachO::mach_header & getHeader() const

Definition MachOObjectFile.cpp:4834

unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const

Definition MachOObjectFile.cpp:4607

iterator_range< bind_iterator > weakBindTable(Error &Err)

For use iterating over all weak bind table entries.

Definition MachOObjectFile.cpp:4508

static bool isMachOPairedReloc(uint64_t RelocType, uint64_t Arch)

Definition MachOObjectFile.cpp:5423

ArrayRef< uint8_t > getDyldInfoRebaseOpcodes() const

Definition MachOObjectFile.cpp:4930

iterator_range< load_command_iterator > load_commands() const

Definition MachOObjectFile.cpp:4537

unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const

Definition MachOObjectFile.cpp:4614

MachO::symtab_command getSymtabLoadCommand() const

Definition MachOObjectFile.cpp:4857

Triple getArchTriple(const char **McpuDefault=nullptr) const

Definition MachOObjectFile.cpp:2906

MachO::uuid_command getUuidCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4732

unsigned getPlainRelocationSymbolNum(const MachO::any_relocation_info &RE) const

Definition MachOObjectFile.cpp:4571

ArrayRef< uint8_t > getUuid() const

Definition MachOObjectFile.cpp:5301

bool is64Bit() const override

Definition MachOObjectFile.cpp:5314

MachO::version_min_command getVersionMinLoadCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4697

StringRef mapDebugSectionName(StringRef Name) const override

Maps a debug section name to a standard DWARF section name.

Definition MachOObjectFile.cpp:5362

MachO::dylinker_command getDylinkerCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4727

uint64_t getRelocationType(DataRefImpl Rel) const override

Definition MachOObjectFile.cpp:2293

relocation_iterator extrel_begin() const

Definition MachOObjectFile.cpp:2221

void moveRelocationNext(DataRefImpl &Rel) const override

Definition MachOObjectFile.cpp:2255

MachO::any_relocation_info getRelocation(DataRefImpl Rel) const

Definition MachOObjectFile.cpp:4802

basic_symbol_iterator symbol_end() const override

Definition MachOObjectFile.cpp:2627

MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset, unsigned Index) const

Definition MachOObjectFile.cpp:4851

MachO::data_in_code_entry getDice(DataRefImpl Rel) const

Definition MachOObjectFile.cpp:4829

bool isSectionStripped(DataRefImpl Sec) const override

When dsymutil generates the companion file, it strips all unnecessary sections (e....

Definition MachOObjectFile.cpp:2191

uint64_t getSectionIndex(DataRefImpl Sec) const override

Definition MachOObjectFile.cpp:1948

iterator_range< fixup_iterator > fixupTable(Error &Err)

For iterating over all chained fixups.

Definition MachOObjectFile.cpp:4513

void ReadULEB128s(uint64_t Index, SmallVectorImpl< uint64_t > &Out) const

Definition MachOObjectFile.cpp:5319

iterator_range< bind_iterator > lazyBindTable(Error &Err)

For use iterating over all lazy bind table entries.

Definition MachOObjectFile.cpp:4503

load_command_iterator end_load_commands() const

Definition MachOObjectFile.cpp:4532

ArrayRef< uint8_t > getDyldInfoBindOpcodes() const

Definition MachOObjectFile.cpp:4944

Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override

Definition MachOObjectFile.cpp:1843

uint64_t getSectionAddress(DataRefImpl Sec) const override

Definition MachOObjectFile.cpp:1942

Expected< StringRef > getSectionName(DataRefImpl Sec) const override

Definition MachOObjectFile.cpp:1937

uint8_t getRelocationLength(DataRefImpl Rel) const

Definition MachOObjectFile.cpp:2408

llvm::binaryformat::Swift5ReflectionSectionKind mapReflectionSectionNameToEnumValue(StringRef SectionName) const override

Definition MachOObjectFile.cpp:5412

ArrayRef< uint8_t > getDyldInfoWeakBindOpcodes() const

Definition MachOObjectFile.cpp:4958

static bool isValidArch(StringRef ArchFlag)

Definition MachOObjectFile.cpp:2872

bool isSectionText(DataRefImpl Sec) const override

Definition MachOObjectFile.cpp:2063

bool isSectionCompressed(DataRefImpl Sec) const override

Definition MachOObjectFile.cpp:2059

static ArrayRef< StringRef > getValidArchs()

Definition MachOObjectFile.cpp:2877

bool isSectionBitcode(DataRefImpl Sec) const override

Definition MachOObjectFile.cpp:2184

bool isRelocationScattered(const MachO::any_relocation_info &RE) const

Definition MachOObjectFile.cpp:4564

relocation_iterator locrel_begin() const

Definition MachOObjectFile.cpp:2238

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.

Definition MachOObjectFile.cpp:5020

uint32_t getSymbolAlignment(DataRefImpl Symb) const override

Definition MachOObjectFile.cpp:1829

MachO::source_version_command getSourceVersionCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4742

unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const

Definition MachOObjectFile.cpp:4600

StringRef getStringTableData() const

Definition MachOObjectFile.cpp:5309

void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override

Definition MachOObjectFile.cpp:2298

ArrayRef< char > getSectionRawName(DataRefImpl Sec) const

Definition MachOObjectFile.cpp:4548

uint64_t getNValue(DataRefImpl Sym) const

Definition MachOObjectFile.cpp:1796

ArrayRef< uint8_t > getSegmentContents(StringRef SegmentName) const

Return the raw contents of an entire segment.

Definition MachOObjectFile.cpp:2130

section_iterator getRelocationSection(DataRefImpl Rel) const

Definition MachOObjectFile.cpp:2289

unsigned getSectionID(SectionRef Sec) const

Definition MachOObjectFile.cpp:2173

MachO::linkedit_data_command getLinkeditDataLoadCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4677

ArrayRef< uint8_t > getSectionContents(uint64_t Offset, uint64_t Size) const

Definition MachOObjectFile.cpp:1981

Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override

Definition MachOObjectFile.cpp:1825

MachO::dylib_command getDylibIDLoadCommand(const LoadCommandInfo &L) const

Definition MachOObjectFile.cpp:4717

uint32_t getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, unsigned Index) const

Definition MachOObjectFile.cpp:4843

uint64_t getSectionSize(DataRefImpl Sec) const override

Definition MachOObjectFile.cpp:1952

relocation_iterator extrel_end() const

Definition MachOObjectFile.cpp:2229

static StringRef guessLibraryShortName(StringRef Name, bool &isFramework, StringRef &Suffix)

Definition MachOObjectFile.cpp:2449

relocation_iterator locrel_end() const

Definition MachOObjectFile.cpp:2246

std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const

Definition MachOObjectFile.cpp:2573

MachORebaseEntry encapsulates the current state in the decompression of rebasing opcodes.

LLVM_ABI int32_t segmentIndex() const

Definition MachOObjectFile.cpp:3777

LLVM_ABI StringRef segmentName() const

Definition MachOObjectFile.cpp:3795

LLVM_ABI MachORebaseEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > opcodes, bool is64Bit)

Definition MachOObjectFile.cpp:3501

LLVM_ABI bool operator==(const MachORebaseEntry &) const

Definition MachOObjectFile.cpp:3811

LLVM_ABI uint64_t address() const

Definition MachOObjectFile.cpp:3807

LLVM_ABI void moveNext()

Definition MachOObjectFile.cpp:3517

LLVM_ABI StringRef sectionName() const

Definition MachOObjectFile.cpp:3801

friend class MachOObjectFile

LLVM_ABI uint64_t segmentOffset() const

Definition MachOObjectFile.cpp:3779

LLVM_ABI StringRef typeName() const

Definition MachOObjectFile.cpp:3781

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.

Definition MachOObjectFile.cpp:5342

section_iterator_range sections() const

symbol_iterator_range symbols() const

Expected< uint64_t > getSymbolValue(DataRefImpl Symb) const

DataRefImpl getRawDataRefImpl() 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.

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

const uint32_t x86_EXCEPTION_STATE_COUNT

@ EXPORT_SYMBOL_FLAGS_REEXPORT

@ EXPORT_SYMBOL_FLAGS_KIND_MASK

@ EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER

@ 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

@ BIND_SYMBOL_FLAGS_WEAK_IMPORT

@ BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION

@ 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

@ DYLD_CHAINED_PTR_64_OFFSET

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)

@ S_ATTR_PURE_INSTRUCTIONS

S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine instructions.

const uint32_t x86_EXCEPTION_STATE64_COUNT

const uint32_t x86_THREAD_STATE64_COUNT

constexpr size_t SymbolTableEntrySize

Swift5ReflectionSectionKind

content_iterator< SectionRef > section_iterator

Error createError(const Twine &Err)

content_iterator< MachOBindEntry > bind_iterator

content_iterator< MachOChainedFixupEntry > fixup_iterator

content_iterator< MachORebaseEntry > rebase_iterator

content_iterator< BasicSymbolRef > basic_symbol_iterator

content_iterator< ExportEntry > export_iterator

content_iterator< RelocationRef > relocation_iterator

content_iterator< DiceRef > dice_iterator

LLVM_ABI std::error_code status(const Twine &path, file_status &result, bool follow=true)

Get file status as if by POSIX stat().

LLVM_ABI bool is_directory(const basic_file_status &status)

Does status represent a directory?

LLVM_ABI bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)

In-place remove any '.

LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")

Append to path.

LLVM_ABI StringRef extension(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get extension.

constexpr bool IsLittleEndianHost

LLVM_ABI std::string getDefaultTargetTriple()

getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...

void swapByteOrder(T &Value)

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.

ArrayRef< CharT > arrayRefFromStringRef(StringRef Input)

Construct a string ref from an array ref of unsigned chars.

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

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

FunctionAddr VTableAddr Count

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

void cantFail(Error Err, const char *Msg=nullptr)

Report a fatal error if Err is a failure value.

To bit_cast(const From &from) noexcept

FunctionAddr VTableAddr Next

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...

ArrayRef(const T &OneElt) -> ArrayRef< T >

constexpr int32_t SignExtend32(uint32_t X)

Sign-extend the number in the bottom B bits of X to a 32-bit integer.

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

LLVM_ABI 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.

uint64_t Offset

Definition MachOObjectFile.cpp:248

const char * Name

Definition MachOObjectFile.cpp:250

uint64_t Size

Definition MachOObjectFile.cpp:249

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::@005117267142344013370254144343227032034000327225 d