32 using namespace object;
45 if (P < O->getData().
begin() || P +
sizeof(
T) > O->getData().
end())
49 memcpy(&Cmd, P,
sizeof(
T));
58 if (P < O->getData().
begin() || P +
sizeof(
T) > O->getData().
end())
62 memcpy(&Cmd, P,
sizeof(
T));
71 uintptr_t CommandAddr =
reinterpret_cast<uintptr_t
>(L.
Ptr);
73 bool Is64 = O->is64Bit();
79 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec *
SectionSize;
80 return reinterpret_cast<const char*
>(SectionAddr);
83 static const char *
getPtr(
const MachOObjectFile *O,
size_t Offset) {
84 return O->getData().substr(Offset, 1).data();
89 const char *
P =
reinterpret_cast<const char *
>(DRI.
p);
90 return getStruct<MachO::nlist_base>(O,
P);
109 return O->getHeader().cputype;
124 if (O->isLittleEndian())
137 if (O->isLittleEndian())
149 if (O->isLittleEndian())
166 auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr);
168 return CmdOrErr.getError();
169 if (CmdOrErr->cmdsize < 8)
173 Load.
C = CmdOrErr.get();
190 template <
typename T>
192 std::error_code &EC) {
193 auto HeaderOrErr = getStructOrErr<T>(Obj,
getPtr(Obj, 0));
195 Header = HeaderOrErr.get();
197 EC = HeaderOrErr.getError();
203 template <
typename SegmentCmd>
207 const unsigned SegmentLoadSize =
sizeof(SegmentCmd);
208 if (Load.
C.
cmdsize < SegmentLoadSize)
210 auto SegOrErr = getStructOrErr<SegmentCmd>(Obj, Load.
Ptr);
212 return SegOrErr.getError();
213 SegmentCmd S = SegOrErr.get();
216 if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
217 S.nsects * SectionSize > Load.
C.
cmdsize - SegmentLoadSize)
219 for (
unsigned J = 0; J < S.nsects; ++J) {
224 return std::error_code();
228 bool Is64bits, std::error_code &EC)
229 :
ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
230 SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
231 DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
232 DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
233 HasPageZeroSegment(
false) {
242 if (LoadCommandCount == 0)
247 EC = LoadOrErr.getError();
251 for (
unsigned I = 0;
I < LoadCommandCount; ++
I) {
259 SymtabLoadCmd = Load.
Ptr;
262 if (DysymtabLoadCmd) {
266 DysymtabLoadCmd = Load.
Ptr;
269 if (DataInCodeLoadCmd) {
273 DataInCodeLoadCmd = Load.
Ptr;
276 if (LinkOptHintsLoadCmd) {
280 LinkOptHintsLoadCmd = Load.
Ptr;
284 if (DyldInfoLoadCmd) {
288 DyldInfoLoadCmd = Load.
Ptr;
295 UuidLoadCmd = Load.
Ptr;
297 if ((EC = parseSegmentLoadCommand<MachO::segment_command_64>(
298 this, Load, Sections, HasPageZeroSegment)))
301 if ((EC = parseSegmentLoadCommand<MachO::segment_command>(
302 this, Load, Sections, HasPageZeroSegment)))
311 if (
I < LoadCommandCount - 1) {
314 EC = LoadOrErr.getError();
317 Load = LoadOrErr.get();
320 assert(LoadCommands.
size() == LoadCommandCount);
324 unsigned SymbolTableEntrySize =
is64Bit() ?
327 Symb.
p += SymbolTableEntrySize;
333 const char *Start = &StringTable.
data()[Entry.
n_strx];
336 "Symbol name entry points before beginning or past end of file.");
364 if (NValue >= StringTable.
size())
366 const char *Start = &StringTable.
data()[NValue];
368 return std::error_code();
371 uint64_t MachOObjectFile::getSymbolValueImpl(
DataRefImpl Sym)
const {
394 uint8_t n_type = Entry.
n_type;
412 uint8_t MachOType = Entry.
n_type;
413 uint16_t MachOFlags = Entry.
n_desc;
451 uint8_t index = Entry.
n_sect;
458 if (DRI.
d.
a >= Sections.
size())
463 return std::error_code();
480 return std::error_code();
511 return std::error_code();
524 return uint64_t(1) <<
Align;
587 "Only implemented for MH_OBJECT");
604 unsigned SymbolTableEntrySize =
is64Bit() ?
607 uint64_t Offset = S.
symoff + SymbolIdx * SymbolTableEntrySize;
609 Sym.
p =
reinterpret_cast<uintptr_t
>(
getPtr(
this, Offset));
628 unsigned Arch = this->
getArch();
632 static const char *
const Table[] = {
633 "GENERIC_RELOC_VANILLA",
634 "GENERIC_RELOC_PAIR",
635 "GENERIC_RELOC_SECTDIFF",
636 "GENERIC_RELOC_PB_LA_PTR",
637 "GENERIC_RELOC_LOCAL_SECTDIFF",
638 "GENERIC_RELOC_TLV" };
647 static const char *
const Table[] = {
648 "X86_64_RELOC_UNSIGNED",
649 "X86_64_RELOC_SIGNED",
650 "X86_64_RELOC_BRANCH",
651 "X86_64_RELOC_GOT_LOAD",
653 "X86_64_RELOC_SUBTRACTOR",
654 "X86_64_RELOC_SIGNED_1",
655 "X86_64_RELOC_SIGNED_2",
656 "X86_64_RELOC_SIGNED_4",
657 "X86_64_RELOC_TLV" };
666 static const char *
const Table[] = {
669 "ARM_RELOC_SECTDIFF",
670 "ARM_RELOC_LOCAL_SECTDIFF",
671 "ARM_RELOC_PB_LA_PTR",
673 "ARM_THUMB_RELOC_BR22",
674 "ARM_THUMB_32BIT_BRANCH",
676 "ARM_RELOC_HALF_SECTDIFF" };
685 static const char *
const Table[] = {
686 "ARM64_RELOC_UNSIGNED",
"ARM64_RELOC_SUBTRACTOR",
687 "ARM64_RELOC_BRANCH26",
"ARM64_RELOC_PAGE21",
688 "ARM64_RELOC_PAGEOFF12",
"ARM64_RELOC_GOT_LOAD_PAGE21",
689 "ARM64_RELOC_GOT_LOAD_PAGEOFF12",
"ARM64_RELOC_POINTER_TO_GOT",
690 "ARM64_RELOC_TLVP_LOAD_PAGE21",
"ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
701 static const char *
const Table[] = {
710 "PPC_RELOC_SECTDIFF",
711 "PPC_RELOC_PB_LA_PTR",
712 "PPC_RELOC_HI16_SECTDIFF",
713 "PPC_RELOC_LO16_SECTDIFF",
714 "PPC_RELOC_HA16_SECTDIFF",
716 "PPC_RELOC_LO14_SECTDIFF",
717 "PPC_RELOC_LOCAL_SECTDIFF" };
768 StringRef Foo,
F, DotFramework, V, Dylib, Lib, Dot, Qtx;
769 size_t a, b, c, d, Idx;
776 if (a == Name.
npos || a == 0)
781 Idx = Foo.
rfind(
'_');
782 if (Idx != Foo.
npos && Foo.
size() >= 2) {
784 Foo = Foo.
slice(0, Idx);
788 b = Name.
rfind(
'/', a);
794 DotFramework = Name.
slice(Idx + Foo.
size(),
795 Idx + Foo.
size() +
sizeof(
".framework/")-1);
796 if (F == Foo && DotFramework ==
".framework/") {
804 c = Name.
rfind(
'/', b);
805 if (c == Name.
npos || c == 0)
810 d = Name.
rfind(
'/', c);
816 DotFramework = Name.
slice(Idx + Foo.
size(),
817 Idx + Foo.
size() +
sizeof(
".framework/")-1);
818 if (F == Foo && DotFramework ==
".framework/") {
826 if (a == Name.
npos || a == 0)
829 if (Dylib !=
".dylib")
834 Dot = Name.
slice(a-2, a-1);
839 b = Name.
rfind(
'/', a);
845 Idx = Name.
find(
'_', b);
846 if (Idx != Name.
npos && Idx != b) {
847 Lib = Name.
slice(b, Idx);
848 Suffix = Name.
slice(Idx, a);
851 Lib = Name.
slice(b, a);
854 if (Lib.
size() >= 3) {
865 b = Name.
rfind(
'/', a);
867 Lib = Name.
slice(0, a);
869 Lib = Name.
slice(b+1, a);
871 if (Lib.
size() >= 3) {
886 if (Index >= Libraries.
size())
891 if (LibrariesShortNames.
size() == 0) {
892 for (
unsigned i = 0; i < Libraries.
size(); i++) {
894 getStruct<MachO::dylib_command>(
this, Libraries[i]);
897 const char *
P = (
const char *)(Libraries[i]) + D.
dylib.
name;
904 if (shortName.
empty())
907 LibrariesShortNames.
push_back(shortName);
911 Res = LibrariesShortNames[Index];
912 return std::error_code();
918 Sec.
d.
a = Rel->getRawDataRefImpl().d.a;
932 unsigned SymbolTableEntrySize =
is64Bit() ?
935 unsigned Offset = Symtab.
symoff +
936 Symtab.
nsyms * SymbolTableEntrySize;
937 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(
this, Offset));
947 if (Index >= Symtab.
nsyms)
949 unsigned SymbolTableEntrySize =
951 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(
this, Symtab.
symoff));
952 DRI.
p += Index * SymbolTableEntrySize;
963 DRI.
d.
a = Sections.
size();
976 return "Mach-O 32-bit i386";
980 return "Mach-O 32-bit ppc";
982 return "Mach-O 32-bit unknown";
988 return "Mach-O 64-bit x86-64";
990 return "Mach-O arm64";
992 return "Mach-O 64-bit ppc64";
994 return "Mach-O 64-bit unknown";
1018 const char **McpuDefault) {
1020 *McpuDefault =
nullptr;
1026 return Triple(
"i386-apple-darwin");
1033 return Triple(
"x86_64-apple-darwin");
1035 return Triple(
"x86_64h-apple-darwin");
1042 return Triple(
"armv4t-apple-darwin");
1044 return Triple(
"armv5e-apple-darwin");
1046 return Triple(
"xscale-apple-darwin");
1048 return Triple(
"armv6-apple-darwin");
1051 *McpuDefault =
"cortex-m0";
1052 return Triple(
"armv6m-apple-darwin");
1054 return Triple(
"armv7-apple-darwin");
1057 *McpuDefault =
"cortex-m4";
1058 return Triple(
"armv7em-apple-darwin");
1060 return Triple(
"armv7k-apple-darwin");
1063 *McpuDefault =
"cortex-m3";
1064 return Triple(
"armv7m-apple-darwin");
1066 return Triple(
"armv7s-apple-darwin");
1073 return Triple(
"arm64-apple-darwin");
1080 return Triple(
"ppc-apple-darwin");
1087 return Triple(
"ppc64-apple-darwin");
1097 const char **McpuDefault) {
1099 *McpuDefault =
nullptr;
1105 return Triple(
"thumbv4t-apple-darwin");
1107 return Triple(
"thumbv5e-apple-darwin");
1109 return Triple(
"xscale-apple-darwin");
1111 return Triple(
"thumbv6-apple-darwin");
1114 *McpuDefault =
"cortex-m0";
1115 return Triple(
"thumbv6m-apple-darwin");
1117 return Triple(
"thumbv7-apple-darwin");
1120 *McpuDefault =
"cortex-m4";
1121 return Triple(
"thumbv7em-apple-darwin");
1123 return Triple(
"thumbv7k-apple-darwin");
1126 *McpuDefault =
"cortex-m3";
1127 return Triple(
"thumbv7m-apple-darwin");
1129 return Triple(
"thumbv7s-apple-darwin");
1139 const char **McpuDefault,
1154 .
Case(
"x86_64",
true)
1155 .
Case(
"x86_64h",
true)
1156 .
Case(
"armv4t",
true)
1158 .
Case(
"armv5e",
true)
1159 .
Case(
"armv6",
true)
1160 .
Case(
"armv6m",
true)
1161 .
Case(
"armv7",
true)
1162 .
Case(
"armv7em",
true)
1163 .
Case(
"armv7k",
true)
1164 .
Case(
"armv7m",
true)
1165 .
Case(
"armv7s",
true)
1166 .
Case(
"arm64",
true)
1168 .
Case(
"ppc64",
true)
1177 Triple *ThumbTriple)
const {
1196 if (!DataInCodeLoadCmd)
1200 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(
this, DicLC.
dataoff));
1206 if (!DataInCodeLoadCmd)
1211 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(
this, Offset));
1218 void ExportEntry::moveToFirst() {
1220 pushDownUntilBottom();
1223 void ExportEntry::moveToEnd() {
1230 if (Done || Other.Done)
1231 return (Done == Other.Done);
1233 if (Stack.
size() != Other.Stack.
size())
1236 if (!CumulativeString.
equals(Other.CumulativeString))
1239 for (
unsigned i=0; i < Stack.
size(); ++i) {
1240 if (Stack[i].Start != Other.Stack[i].Start)
1246 uint64_t ExportEntry::readULEB128(
const uint8_t *&Ptr) {
1250 if (Ptr > Trie.
end()) {
1258 return CumulativeString;
1262 return Stack.
back().Flags;
1266 return Stack.
back().Address;
1270 return Stack.
back().Other;
1274 const char* ImportName = Stack.
back().ImportName;
1281 return Stack.
back().Start - Trie.
begin();
1284 ExportEntry::NodeState::NodeState(
const uint8_t *Ptr)
1286 ImportName(nullptr), ChildCount(0), NextChildIndex(0),
1287 ParentStringLength(0), IsExportNode(
false) {
1290 void ExportEntry::pushNode(uint64_t offset) {
1291 const uint8_t *Ptr = Trie.
begin() + offset;
1292 NodeState State(Ptr);
1293 uint64_t ExportInfoSize = readULEB128(State.Current);
1294 State.IsExportNode = (ExportInfoSize != 0);
1295 const uint8_t* Children = State.Current + ExportInfoSize;
1296 if (State.IsExportNode) {
1297 State.Flags = readULEB128(State.Current);
1300 State.Other = readULEB128(State.Current);
1301 State.ImportName =
reinterpret_cast<const char*
>(State.Current);
1303 State.Address = readULEB128(State.Current);
1305 State.Other = readULEB128(State.Current);
1308 State.ChildCount = *Children;
1309 State.Current = Children + 1;
1310 State.NextChildIndex = 0;
1311 State.ParentStringLength = CumulativeString.
size();
1315 void ExportEntry::pushDownUntilBottom() {
1316 while (Stack.
back().NextChildIndex < Stack.
back().ChildCount) {
1317 NodeState &Top = Stack.
back();
1318 CumulativeString.
resize(Top.ParentStringLength);
1319 for (;*Top.Current != 0; Top.Current++) {
1320 char C = *Top.Current;
1324 uint64_t childNodeIndex = readULEB128(Top.Current);
1325 Top.NextChildIndex += 1;
1326 pushNode(childNodeIndex);
1328 if (!Stack.
back().IsExportNode) {
1350 if (Stack.
empty() || !Stack.
back().IsExportNode) {
1357 while (!Stack.
empty()) {
1358 NodeState &Top = Stack.
back();
1359 if (Top.NextChildIndex < Top.ChildCount) {
1360 pushDownUntilBottom();
1364 if (Top.IsExportNode) {
1366 CumulativeString.
resize(Top.ParentStringLength);
1378 if (Trie.
size() == 0)
1381 Start.moveToFirst();
1396 : Opcodes(Bytes), Ptr(Bytes.
begin()), SegmentOffset(0), SegmentIndex(0),
1397 RemainingLoopCount(0), AdvanceAmount(0),
RebaseType(0),
1398 PointerSize(is64Bit ? 8 : 4), Malformed(
false), Done(
false) {}
1400 void MachORebaseEntry::moveToFirst() {
1401 Ptr = Opcodes.
begin();
1405 void MachORebaseEntry::moveToEnd() {
1406 Ptr = Opcodes.
end();
1407 RemainingLoopCount = 0;
1413 SegmentOffset += AdvanceAmount;
1414 if (RemainingLoopCount) {
1415 --RemainingLoopCount;
1418 if (Ptr == Opcodes.
end()) {
1423 while (More && !Malformed) {
1425 uint8_t Byte = *Ptr++;
1436 RebaseType = ImmValue;
1439 llvm::dbgs() <<
"REBASE_OPCODE_SET_TYPE_IMM: "
1440 <<
"RebaseType=" << (
int) RebaseType <<
"\n");
1443 SegmentIndex = ImmValue;
1444 SegmentOffset = readULEB128();
1447 llvm::dbgs() <<
"REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1448 <<
"SegmentIndex=" << SegmentIndex <<
", "
1449 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
1453 SegmentOffset += readULEB128();
1455 llvm::dbgs() <<
"REBASE_OPCODE_ADD_ADDR_ULEB: "
1456 <<
format(
"SegmentOffset=0x%06X",
1457 SegmentOffset) <<
"\n");
1460 SegmentOffset += ImmValue * PointerSize;
1462 llvm::dbgs() <<
"REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
1463 <<
format(
"SegmentOffset=0x%06X",
1464 SegmentOffset) <<
"\n");
1467 AdvanceAmount = PointerSize;
1468 RemainingLoopCount = ImmValue - 1;
1471 llvm::dbgs() <<
"REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
1472 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
1473 <<
", AdvanceAmount=" << AdvanceAmount
1474 <<
", RemainingLoopCount=" << RemainingLoopCount
1478 AdvanceAmount = PointerSize;
1479 RemainingLoopCount = readULEB128() - 1;
1482 llvm::dbgs() <<
"REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
1483 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
1484 <<
", AdvanceAmount=" << AdvanceAmount
1485 <<
", RemainingLoopCount=" << RemainingLoopCount
1489 AdvanceAmount = readULEB128() + PointerSize;
1490 RemainingLoopCount = 0;
1493 llvm::dbgs() <<
"REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
1494 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
1495 <<
", AdvanceAmount=" << AdvanceAmount
1496 <<
", RemainingLoopCount=" << RemainingLoopCount
1500 RemainingLoopCount = readULEB128() - 1;
1501 AdvanceAmount = readULEB128() + PointerSize;
1504 llvm::dbgs() <<
"REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
1505 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
1506 <<
", AdvanceAmount=" << AdvanceAmount
1507 <<
", RemainingLoopCount=" << RemainingLoopCount
1516 uint64_t MachORebaseEntry::readULEB128() {
1520 if (Ptr > Opcodes.
end()) {
1521 Ptr = Opcodes.
end();
1532 switch (RebaseType) {
1536 return "text abs32";
1538 return "text rel32";
1544 assert(Opcodes == Other.Opcodes &&
"compare iterators of different files");
1545 return (Ptr == Other.Ptr) &&
1546 (RemainingLoopCount == Other.RemainingLoopCount) &&
1547 (Done == Other.Done);
1553 Start.moveToFirst();
1569 : Opcodes(Bytes), Ptr(Bytes.
begin()), SegmentOffset(0), SegmentIndex(0),
1570 Ordinal(0),
Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
1571 BindType(0), PointerSize(is64Bit ? 8 : 4),
1572 TableKind(BK), Malformed(
false), Done(
false) {}
1574 void MachOBindEntry::moveToFirst() {
1575 Ptr = Opcodes.
begin();
1579 void MachOBindEntry::moveToEnd() {
1580 Ptr = Opcodes.
end();
1581 RemainingLoopCount = 0;
1587 SegmentOffset += AdvanceAmount;
1588 if (RemainingLoopCount) {
1589 --RemainingLoopCount;
1592 if (Ptr == Opcodes.
end()) {
1597 while (More && !Malformed) {
1599 uint8_t Byte = *Ptr++;
1602 int8_t SignExtended;
1603 const uint8_t *SymStart;
1609 bool NotLastEntry =
false;
1610 for (
const uint8_t *
P = Ptr;
P < Opcodes.
end(); ++
P) {
1612 NotLastEntry =
true;
1627 llvm::dbgs() <<
"BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
1628 <<
"Ordinal=" << Ordinal <<
"\n");
1631 Ordinal = readULEB128();
1634 llvm::dbgs() <<
"BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
1635 <<
"Ordinal=" << Ordinal <<
"\n");
1639 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
1640 Ordinal = SignExtended;
1645 llvm::dbgs() <<
"BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
1646 <<
"Ordinal=" << Ordinal <<
"\n");
1654 SymbolName =
StringRef(reinterpret_cast<const char*>(SymStart),
1659 llvm::dbgs() <<
"BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
1660 <<
"SymbolName=" << SymbolName <<
"\n");
1667 BindType = ImmValue;
1671 <<
"BindType=" << (
int)BindType <<
"\n");
1674 Addend = readSLEB128();
1679 llvm::dbgs() <<
"BIND_OPCODE_SET_ADDEND_SLEB: "
1680 <<
"Addend=" << Addend <<
"\n");
1683 SegmentIndex = ImmValue;
1684 SegmentOffset = readULEB128();
1687 llvm::dbgs() <<
"BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1688 <<
"SegmentIndex=" << SegmentIndex <<
", "
1689 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
1693 SegmentOffset += readULEB128();
1695 llvm::dbgs() <<
"BIND_OPCODE_ADD_ADDR_ULEB: "
1696 <<
format(
"SegmentOffset=0x%06X",
1697 SegmentOffset) <<
"\n");
1700 AdvanceAmount = PointerSize;
1701 RemainingLoopCount = 0;
1704 <<
format(
"SegmentOffset=0x%06X",
1705 SegmentOffset) <<
"\n");
1708 AdvanceAmount = readULEB128() + PointerSize;
1709 RemainingLoopCount = 0;
1714 llvm::dbgs() <<
"BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
1715 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
1716 <<
", AdvanceAmount=" << AdvanceAmount
1717 <<
", RemainingLoopCount=" << RemainingLoopCount
1721 AdvanceAmount = ImmValue * PointerSize + PointerSize;
1722 RemainingLoopCount = 0;
1727 <<
"BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
1728 <<
format(
"SegmentOffset=0x%06X",
1729 SegmentOffset) <<
"\n");
1732 RemainingLoopCount = readULEB128() - 1;
1733 AdvanceAmount = readULEB128() + PointerSize;
1738 llvm::dbgs() <<
"BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
1739 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
1740 <<
", AdvanceAmount=" << AdvanceAmount
1741 <<
", RemainingLoopCount=" << RemainingLoopCount
1750 uint64_t MachOBindEntry::readULEB128() {
1754 if (Ptr > Opcodes.
end()) {
1755 Ptr = Opcodes.
end();
1761 int64_t MachOBindEntry::readSLEB128() {
1765 if (Ptr > Opcodes.
end()) {
1766 Ptr = Opcodes.
end();
1782 return "text abs32";
1784 return "text rel32";
1798 assert(Opcodes == Other.Opcodes &&
"compare iterators of different files");
1799 return (Ptr == Other.Ptr) &&
1800 (RemainingLoopCount == Other.RemainingLoopCount) &&
1801 (Done == Other.Done);
1808 Start.moveToFirst();
1834 return LoadCommands.
begin();
1839 return LoadCommands.
end();
1856 assert(Sec.
d.
a < Sections.
size() &&
"Should have detected this earlier");
1857 const section_base *Base =
1858 reinterpret_cast<const section_base *
>(Sections[Sec.
d.
a]);
1864 assert(Sec.
d.
a < Sections.
size() &&
"Should have detected this earlier");
1865 const section_base *Base =
1866 reinterpret_cast<const section_base *
>(Sections[Sec.
d.
a]);
1888 return (RE.
r_word1 >> 27) & 1;
1904 return (RE.
r_word0 >> 24) & 0xf;
1945 DRI.
d.
a = SecNum - 1;
1950 assert(DRI.
d.
a < Sections.
size() &&
"Should have detected this earlier");
1951 return getStruct<MachO::section>(
this, Sections[DRI.
d.
a]);
1955 assert(DRI.
d.
a < Sections.
size() &&
"Should have detected this earlier");
1956 return getStruct<MachO::section_64>(
this, Sections[DRI.
d.
a]);
1960 unsigned Index)
const {
1962 return getStruct<MachO::section>(
this, Sec);
1966 unsigned Index)
const {
1968 return getStruct<MachO::section_64>(
this, Sec);
1973 const char *
P =
reinterpret_cast<const char *
>(DRI.
p);
1974 return getStruct<MachO::nlist>(
this,
P);
1979 const char *
P =
reinterpret_cast<const char *
>(DRI.
p);
1980 return getStruct<MachO::nlist_64>(
this,
P);
1985 return getStruct<MachO::linkedit_data_command>(
this, L.
Ptr);
1990 return getStruct<MachO::segment_command>(
this, L.
Ptr);
1995 return getStruct<MachO::segment_command_64>(
this, L.
Ptr);
2000 return getStruct<MachO::linker_option_command>(
this, L.
Ptr);
2005 return getStruct<MachO::version_min_command>(
this, L.
Ptr);
2010 return getStruct<MachO::dylib_command>(
this, L.
Ptr);
2015 return getStruct<MachO::dyld_info_command>(
this, L.
Ptr);
2020 return getStruct<MachO::dylinker_command>(
this, L.
Ptr);
2025 return getStruct<MachO::uuid_command>(
this, L.
Ptr);
2030 return getStruct<MachO::rpath_command>(
this, L.
Ptr);
2035 return getStruct<MachO::source_version_command>(
this, L.
Ptr);
2040 return getStruct<MachO::entry_point_command>(
this, L.
Ptr);
2045 return getStruct<MachO::encryption_info_command>(
this, L.
Ptr);
2050 return getStruct<MachO::encryption_info_command_64>(
this, L.
Ptr);
2055 return getStruct<MachO::sub_framework_command>(
this, L.
Ptr);
2060 return getStruct<MachO::sub_umbrella_command>(
this, L.
Ptr);
2065 return getStruct<MachO::sub_library_command>(
this, L.
Ptr);
2070 return getStruct<MachO::sub_client_command>(
this, L.
Ptr);
2075 return getStruct<MachO::routines_command>(
this, L.
Ptr);
2080 return getStruct<MachO::routines_command_64>(
this, L.
Ptr);
2085 return getStruct<MachO::thread_command>(
this, L.
Ptr);
2103 return getStruct<MachO::any_relocation_info>(
2104 this, reinterpret_cast<const char *>(
P));
2109 const char *
P =
reinterpret_cast<const char *
>(Rel.
p);
2110 return getStruct<MachO::data_in_code_entry>(
this,
P);
2124 unsigned Index)
const {
2126 return getStruct<uint32_t>(
this,
getPtr(
this, Offset));
2131 unsigned Index)
const {
2133 return getStruct<MachO::data_in_code_entry>(
this,
getPtr(
this, Offset));
2138 return getStruct<MachO::symtab_command>(
this, SymtabLoadCmd);
2152 if (DysymtabLoadCmd)
2153 return getStruct<MachO::dysymtab_command>(
this, DysymtabLoadCmd);
2169 Cmd.extrefsymoff = 0;
2170 Cmd.nextrefsyms = 0;
2171 Cmd.indirectsymoff = 0;
2172 Cmd.nindirectsyms = 0;
2182 if (DataInCodeLoadCmd)
2183 return getStruct<MachO::linkedit_data_command>(
this, DataInCodeLoadCmd);
2196 if (LinkOptHintsLoadCmd)
2197 return getStruct<MachO::linkedit_data_command>(
this, LinkOptHintsLoadCmd);
2210 if (!DyldInfoLoadCmd)
2214 = getStruct<MachO::dyld_info_command>(
this, DyldInfoLoadCmd);
2215 const uint8_t *Ptr =
reinterpret_cast<const uint8_t*
>(
2216 getPtr(
this, DyldInfo.rebase_off));
2221 if (!DyldInfoLoadCmd)
2225 = getStruct<MachO::dyld_info_command>(
this, DyldInfoLoadCmd);
2226 const uint8_t *Ptr =
reinterpret_cast<const uint8_t*
>(
2227 getPtr(
this, DyldInfo.bind_off));
2232 if (!DyldInfoLoadCmd)
2236 = getStruct<MachO::dyld_info_command>(
this, DyldInfoLoadCmd);
2237 const uint8_t *Ptr =
reinterpret_cast<const uint8_t*
>(
2238 getPtr(
this, DyldInfo.weak_bind_off));
2243 if (!DyldInfoLoadCmd)
2247 = getStruct<MachO::dyld_info_command>(
this, DyldInfoLoadCmd);
2248 const uint8_t *Ptr =
reinterpret_cast<const uint8_t*
>(
2249 getPtr(
this, DyldInfo.lazy_bind_off));
2254 if (!DyldInfoLoadCmd)
2258 = getStruct<MachO::dyld_info_command>(
this, DyldInfoLoadCmd);
2259 const uint8_t *Ptr =
reinterpret_cast<const uint8_t*
>(
2260 getPtr(
this, DyldInfo.export_off));
2286 uint32_t offset = Index;
2288 while (uint64_t delta = extractor.
getULEB128(&offset)) {
2302 std::unique_ptr<MachOObjectFile>
Ret;
2303 if (Magic ==
"\xFE\xED\xFA\xCE")
2305 else if (Magic ==
"\xCE\xFA\xED\xFE")
2307 else if (Magic ==
"\xFE\xED\xFA\xCF")
2309 else if (Magic ==
"\xCF\xFA\xED\xFE")
2316 return std::move(Ret);
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
static ErrorOr< std::unique_ptr< MachOObjectFile > > createMachOObjectFile(MemoryBufferRef Object)
static unsigned getScatteredRelocationLength(const MachO::any_relocation_info &RE)
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const
iterator_range< export_iterator > exports() const
For use iterating over all exported symbols.
Represents either an error or a value T.
static unsigned int getMachOType(bool isLE, bool is64Bits)
load_command_iterator end_load_commands() const
DataRefImpl getRawDataRefImpl() const
std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const
SymbolRef::Type getSymbolType(DataRefImpl Symb) const override
StringRef getStringTableData() const
size_t size() const
size - Get the string size.
basic_symbol_iterator symbol_begin_impl() const override
StringRef getFileFormatName() const override
MachO::linkedit_data_command getLinkOptHintsLoadCommand() const
uint64_t getRelocationOffset(DataRefImpl Rel) const override
bool isSectionVirtual(DataRefImpl Sec) const override
ArrayRef< char > getSectionRawFinalSegmentName(DataRefImpl Sec) const
ArrayRef< char > getSectionRawName(DataRefImpl Sec) const
MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset, unsigned Index) const
std::error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override
void moveRelocationNext(DataRefImpl &Rel) const override
ExportEntry encapsulates the current-state-of-the-walk used when doing a non-recursive walk of the tr...
StringRef typeName() const
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static ErrorOr< T > getStructOrErr(const MachOObjectFile *O, const char *P)
std::string getDefaultTargetTriple()
getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...
size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
static Triple getHostArch()
uint32_t getScatteredRelocationType(const MachO::any_relocation_info &RE) const
uint8_t getRelocationLength(DataRefImpl Rel) const
This class is the base class for all object file types.
void swapStruct(mach_header &mh)
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
uint64_t getRelocationType(DataRefImpl Rel) const override
const_iterator begin(StringRef path)
Get begin iterator over path.
StringRef otherName() const
static StringRef parseSegmentOrSectionName(const char *P)
MachORebaseEntry encapsulates the current state in the decompression of rebasing opcodes.
uint64_t getSectionAlignment(DataRefImpl Sec) const override
static const char * getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L, unsigned Sec)
ErrorOr< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
ArrayRef< uint8_t > getDyldInfoLazyBindOpcodes() const
load_command_iterator begin_load_commands() const
DataRefImpl getRawDataRefImpl() const
StringSwitch & Case(const char(&S)[N], const T &Value)
static uint32_t getPlainRelocationAddress(const MachO::any_relocation_info &RE)
uint32_t getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, unsigned Index) const
bool operator==(const MachORebaseEntry &) const
iterator_range< rebase_iterator > rebaseTable() const
For use iterating over all rebase table entries.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
static T getStruct(const MachOObjectFile *O, const char *P)
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
uint64_t getSectionAddress(DataRefImpl Sec) const override
content_iterator< ExportEntry > export_iterator
bool operator==(const ExportEntry &) const
ExportEntry(ArrayRef< uint8_t > Trie)
bool isSectionText(DataRefImpl Sec) const override
MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, std::error_code &EC)
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
MachO::segment_command_64 getSegment64LoadCommand(const LoadCommandInfo &L) const
static uint32_t getSectionFlags(const MachOObjectFile *O, DataRefImpl Sec)
static void advance(T &it, size_t Val)
StringRef getData() const
MachO::uuid_command getUuidCommand(const LoadCommandInfo &L) const
uint64_t segmentOffset() const
bool equals(StringRef RHS) const
Check for string equality.
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
void ReadULEB128s(uint64_t Index, SmallVectorImpl< uint64_t > &Out) const
MachOBindEntry encapsulates the current state in the decompression of binding opcodes.
MachO::linker_option_command getLinkerOptionLoadCommand(const LoadCommandInfo &L) const
uint32_t nodeOffset() const
MachO::encryption_info_command_64 getEncryptionInfoCommand64(const LoadCommandInfo &L) const
static ErrorOr< MachOObjectFile::LoadCommandInfo > getNextLoadCommandInfo(const MachOObjectFile *Obj, const MachOObjectFile::LoadCommandInfo &L)
dice_iterator end_dices() const
uint32_t getScatteredRelocationValue(const MachO::any_relocation_info &RE) const
static bool getScatteredRelocationPCRel(const MachOObjectFile *O, const MachO::any_relocation_info &RE)
MachO::dylib_command getDylibIDLoadCommand(const LoadCommandInfo &L) const
static const bool IsLittleEndianHost
ErrorOr< StringRef > getSymbolName(DataRefImpl Symb) const override
static unsigned getPlainRelocationLength(const MachOObjectFile *O, const MachO::any_relocation_info &RE)
static Triple getThumbArch(uint32_t CPUType, uint32_t CPUSubType, const char **McpuDefault=nullptr)
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
unsigned getArch() const override
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
MachO::routines_command getRoutinesCommand(const LoadCommandInfo &L) const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
MachO::dylinker_command getDylinkerCommand(const LoadCommandInfo &L) const
const MachO::mach_header & getHeader() const
bool getScatteredRelocationScattered(const MachO::any_relocation_info &RE) const
MachO::section_64 getSection64(DataRefImpl DRI) const
size_t size() const
size - Get the array size.
MachO::entry_point_command getEntryPointCommand(const LoadCommandInfo &L) const
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr)
Utility function to decode a ULEB128 value.
StringRef symbolName() const
MachO::routines_command_64 getRoutinesCommand64(const LoadCommandInfo &L) const
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
void moveSectionNext(DataRefImpl &Sec) const override
LLVM_CONSTEXPR size_t array_lengthof(T(&)[N])
Find the length of an array.
content_iterator< SectionRef > section_iterator
static uint8_t GET_COMM_ALIGN(uint16_t n_desc)
static std::error_code parseSegmentLoadCommand(const MachOObjectFile *Obj, const MachOObjectFile::LoadCommandInfo &Load, SmallVectorImpl< const char * > &Sections, bool &IsPageZeroSegment)
A switch()-like statement whose cases are string literals.
friend const_iterator end(StringRef path)
Get end iterator over path.
unsigned int getType() const
unsigned getSectionID(SectionRef Sec) const
const MachO::mach_header_64 & getHeader64() const
S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine instructions.
S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4 gigabytes).
unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const
ArrayRef< uint8_t > getUuid() const
iterator_range< load_command_iterator > load_commands() const
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const
uint32_t segmentIndex() const
MachO::section getSection(DataRefImpl DRI) const
static bool is64Bit(const char *name)
MachO::segment_command getSegmentLoadCommand(const LoadCommandInfo &L) const
unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const
ArrayRef< uint8_t > getDyldInfoRebaseOpcodes() const
MachO::source_version_command getSourceVersionCommand(const LoadCommandInfo &L) const
MachO::linkedit_data_command getDataInCodeLoadCommand() const
DiceRef - This is a value type class that represents a single data in code entry in the table in a Ma...
MachORebaseEntry(ArrayRef< uint8_t > opcodes, bool is64Bit)
MachO::sub_framework_command getSubFrameworkCommand(const LoadCommandInfo &L) const
content_iterator< MachOBindEntry > bind_iterator
bool operator==(const MachOBindEntry &) const
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
content_iterator< RelocationRef > relocation_iterator
StringRef typeName() const
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
MachO::thread_command getThreadCommand(const LoadCommandInfo &L) const
static void parseHeader(const MachOObjectFile *Obj, T &Header, std::error_code &EC)
uint64_t getNValue(DataRefImpl Sym) const
Triple - Helper class for working with autoconf configuration names.
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr)
Utility function to decode a SLEB128 value.
section_iterator getRelocationSection(DataRefImpl Rel) const
static const char *const Magic
std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const
basic_symbol_iterator symbol_end() const
content_iterator< BasicSymbolRef > basic_symbol_iterator
section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const
static const char * getPtr(const MachOObjectFile *O, size_t Offset)
void moveSymbolNext(DataRefImpl &Symb) const override
unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
friend class RelocationRef
unsigned getSymbolSectionID(SymbolRef Symb) const
bool isSectionData(DataRefImpl Sec) const override
StringRef getBuffer() const
content_iterator< DiceRef > dice_iterator
StringRef getSectionFinalSegmentName(DataRefImpl Sec) const
std::error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override
static ErrorOr< MachOObjectFile::LoadCommandInfo > getLoadCommandInfo(const MachOObjectFile *Obj, const char *Ptr)
MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const
ArrayRef< uint8_t > getDyldInfoExportsTrie() const
uint64_t segmentOffset() const
MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const
static bool getPlainRelocationPCRel(const MachOObjectFile *O, const MachO::any_relocation_info &RE)
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
R Default(const T &Value) const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
uint32_t getSymbolFlags(DataRefImpl Symb) const override
MachO::sub_library_command getSubLibraryCommand(const LoadCommandInfo &L) const
SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const
A range adaptor for a pair of iterators.
MachO::encryption_info_command getEncryptionInfoCommand(const LoadCommandInfo &L) const
static unsigned getScatteredRelocationAddress(const MachO::any_relocation_info &RE)
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
This is a value type class that represents a single symbol in the list of symbols in the object file...
static MachO::nlist_base getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI)
MachO::mach_header_64 Header64
MachOBindEntry(ArrayRef< uint8_t > Opcodes, bool is64Bit, MachOBindEntry::Kind)
MachO::linkedit_data_command getLinkeditDataLoadCommand(const LoadCommandInfo &L) const
static unsigned getCPUType(const MachOObjectFile *O)
MachO::version_min_command getVersionMinLoadCommand(const LoadCommandInfo &L) const
static StringRef guessLibraryShortName(StringRef Name, bool &isFramework, StringRef &Suffix)
bool isSectionBSS(DataRefImpl Sec) const override
MachO::symtab_command getSymtabLoadCommand() const
std::error_code getSymbolSection(DataRefImpl Symb, section_iterator &Res) const override
uint64_t getSymbolValue(DataRefImpl Symb) const
struct llvm::object::DataRefImpl::@97 d
basic_symbol_iterator getSymbolByIndex(unsigned Index) const
bool isLittleEndian() const
dice_iterator begin_dices() const
section_iterator section_begin() const override
static bool isValidArch(StringRef ArchFlag)
relocation_iterator section_rel_end(DataRefImpl Sec) const override
MachO::dysymtab_command getDysymtabLoadCommand() const
MachO::mach_header Header
MachO::rpath_command getRpathCommand(const LoadCommandInfo &L) const
MachO::data_in_code_entry getDice(DataRefImpl Rel) const
MachO::sub_umbrella_command getSubUmbrellaCommand(const LoadCommandInfo &L) const
static ErrorOr< MachOObjectFile::LoadCommandInfo > getFirstLoadCommandInfo(const MachOObjectFile *Obj)
unsigned getSectionType(SectionRef Sec) const
section_iterator section_end() const override
iterator_range< bind_iterator > lazyBindTable() const
For use iterating over all lazy bind table entries.
ArrayRef< uint8_t > getDyldInfoWeakBindOpcodes() const
C - The default llvm calling convention, compatible with C.
StringRef - Represent a constant reference to a string, i.e.
basic_symbol_iterator symbol_end_impl() const override
S_ZEROFILL - Zero fill on demand section.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
static unsigned getPlainRelocationType(const MachOObjectFile *O, const MachO::any_relocation_info &RE)
unsigned getPlainRelocationSymbolNum(const MachO::any_relocation_info &RE) const
SectionType
These are the section type and attributes fields.
MachO::dyld_info_command getDyldInfoLoadCommand(const LoadCommandInfo &L) const
bool isRelocationScattered(const MachO::any_relocation_info &RE) const
MachO::sub_client_command getSubClientCommand(const LoadCommandInfo &L) const
content_iterator< MachORebaseEntry > rebase_iterator
iterator_range< bind_iterator > bindTable() const
For use iterating over all bind table entries.
iterator_range< bind_iterator > weakBindTable() const
For use iterating over all lazy bind table entries.
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
uint32_t segmentIndex() const
This is a value type class that represents a single section in the list of sections in the object fil...
bool empty() const
empty - Check if the string is empty.
uint64_t getSectionSize(DataRefImpl Sec) const override
ArrayRef< uint8_t > getDyldInfoBindOpcodes() const