diff options
-rw-r--r-- | include/llvm/Object/MachO.h | 125 | ||||
-rw-r--r-- | lib/Object/MachOObjectFile.cpp | 52 | ||||
-rw-r--r-- | test/tools/llvm-readobj/relocations.test | 14 | ||||
-rw-r--r-- | test/tools/llvm-readobj/sections-ext.test | 14 | ||||
-rw-r--r-- | tools/llvm-readobj/MachODumper.cpp | 16 |
5 files changed, 90 insertions, 131 deletions
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 7bdb638..b02e1ac 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -112,33 +112,11 @@ namespace MachOFormat { MachOInt32 Reserved3; }; - struct MachOInt24 { - uint8_t bytes[3]; - operator uint32_t() const { - return (bytes[2] << 24) | (bytes[1] << 16) | bytes[0]; - } - }; - template<endianness TargetEndianness> struct RelocationEntry { LLVM_MACHOB_IMPORT_TYPES(TargetEndianness) - MachOInt32 Address; - MachOInt24 SymbolNum; - unsigned PCRel : 1; - unsigned Length : 2; - unsigned External : 1; - unsigned Type : 4; - }; - - template<endianness TargetEndianness> - struct ScatteredRelocationEntry { - LLVM_MACHOB_IMPORT_TYPES(TargetEndianness) - unsigned Address : 24; - unsigned Type : 4; - unsigned Length : 2; - unsigned PCRel : 1; - unsigned Scattered : 1; - MachOInt32 Value; + MachOInt32 Word0; + MachOInt32 Word1; }; template<endianness TargetEndianness> @@ -228,8 +206,6 @@ public: SymbolTableEntryBase; typedef MachOFormat::SymtabLoadCommand<support::little> SymtabLoadCommand; typedef MachOFormat::RelocationEntry<support::little> RelocationEntry; - typedef MachOFormat::ScatteredRelocationEntry<support::little> - ScatteredRelocationEntry; typedef MachOFormat::SectionBase SectionBase; typedef MachOFormat::LoadCommand<support::little> LoadCommand; typedef MachOFormat::Header<support::little> Header; @@ -267,11 +243,6 @@ public: const Header *getHeader() const; unsigned getHeaderSize() const; StringRef getData(size_t Offset, size_t Size) const; - const RelocationEntry *getRelocation(DataRefImpl Rel) const; - bool isScattered(const RelocationEntry *RE) const; - bool isPCRel(const RelocationEntry *RE) const; - unsigned getLength(const RelocationEntry *RE) const; - unsigned getType(const RelocationEntry *RE) const; static inline bool classof(const Binary *v) { return v->isMachO(); @@ -508,12 +479,15 @@ MachOObjectFile<MachOT>::getRelocationAddress(DataRefImpl Rel, const Section *Sect = getSection(Sections[Rel.d.b]); uint64_t SectAddress = Sect->Address; const RelocationEntry *RE = getRelocation(Rel); + unsigned Arch = getArch(); + bool isScattered = (Arch != Triple::x86_64) && + (RE->Word0 & macho::RF_Scattered); uint64_t RelAddr; - if (isScattered(RE)) - RelAddr = RE->Address & 0xFFFFFF; + if (isScattered) + RelAddr = RE->Word0 & 0xFFFFFF; else - RelAddr = RE->Address; + RelAddr = RE->Word0; Res = SectAddress + RelAddr; return object_error::success; @@ -524,10 +498,14 @@ error_code MachOObjectFile<MachOT>::getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const { const RelocationEntry *RE = getRelocation(Rel); - if (isScattered(RE)) - Res = RE->Address & 0xFFFFFF; + + unsigned Arch = getArch(); + bool isScattered = (Arch != Triple::x86_64) && + (RE->Word0 & macho::RF_Scattered); + if (isScattered) + Res = RE->Word0 & 0xFFFFFF; else - Res = RE->Address; + Res = RE->Word0; return object_error::success; } @@ -536,8 +514,8 @@ error_code MachOObjectFile<MachOT>::getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const { const RelocationEntry *RE = getRelocation(Rel); - uint32_t SymbolIdx = RE->SymbolNum; - bool isExtern = RE->External; + uint32_t SymbolIdx = RE->Word1 & 0xffffff; + bool isExtern = (RE->Word1 >> 27) & 1; DataRefImpl Sym; moveToNextSymbol(Sym); @@ -557,7 +535,9 @@ template<class MachOT> error_code MachOObjectFile<MachOT>::getRelocationType(DataRefImpl Rel, uint64_t &Res) const { const RelocationEntry *RE = getRelocation(Rel); - Res = getType(RE); + Res = RE->Word0; + Res <<= 32; + Res |= RE->Word1; return object_error::success; } @@ -570,8 +550,14 @@ MachOObjectFile<MachOT>::getRelocationTypeName(DataRefImpl Rel, const RelocationEntry *RE = getRelocation(Rel); unsigned Arch = getArch(); + bool isScattered = (Arch != Triple::x86_64) && + (RE->Word0 & macho::RF_Scattered); - unsigned r_type = getType(RE); + unsigned r_type; + if (isScattered) + r_type = (RE->Word0 >> 24) & 0xF; + else + r_type = (RE->Word1 >> 28) & 0xF; switch (Arch) { case Triple::x86: { @@ -664,20 +650,30 @@ MachOObjectFile<MachOT>::getRelocationValueString(DataRefImpl Rel, const RelocationEntry *RE = getRelocation(Rel); unsigned Arch = getArch(); - bool IsScattered = isScattered(RE); + bool isScattered = (Arch != Triple::x86_64) && + (RE->Word0 & macho::RF_Scattered); std::string fmtbuf; raw_string_ostream fmt(fmtbuf); - unsigned Type = getType(RE); - bool IsPCRel = isPCRel(RE); + unsigned Type; + if (isScattered) + Type = (RE->Word0 >> 24) & 0xF; + else + Type = (RE->Word1 >> 28) & 0xF; + + bool isPCRel; + if (isScattered) + isPCRel = ((RE->Word0 >> 30) & 1); + else + isPCRel = ((RE->Word1 >> 24) & 1); // Determine any addends that should be displayed with the relocation. // These require decoding the relocation type, which is triple-specific. // X86_64 has entirely custom relocation types. if (Arch == Triple::x86_64) { - bool isPCRel = RE->PCRel; + bool isPCRel = ((RE->Word1 >> 24) & 1); switch (Type) { case macho::RIT_X86_64_GOTLoad: // X86_64_RELOC_GOT_LOAD @@ -695,7 +691,7 @@ MachOObjectFile<MachOT>::getRelocationValueString(DataRefImpl Rel, // X86_64_SUBTRACTOR must be followed by a relocation of type // X86_64_RELOC_UNSIGNED. // NOTE: Scattered relocations don't exist on x86_64. - unsigned RType = RENext->Type; + unsigned RType = (RENext->Word1 >> 28) & 0xF; if (RType != 0) report_fatal_error("Expected X86_64_RELOC_UNSIGNED after " "X86_64_RELOC_SUBTRACTOR."); @@ -742,12 +738,12 @@ MachOObjectFile<MachOT>::getRelocationValueString(DataRefImpl Rel, // X86 sect diff's must be followed by a relocation of type // GENERIC_RELOC_PAIR. bool isNextScattered = (Arch != Triple::x86_64) && - (RENext->Address & macho::RF_Scattered); + (RENext->Word0 & macho::RF_Scattered); unsigned RType; if (isNextScattered) - RType = (RENext->Address >> 24) & 0xF; + RType = (RENext->Word0 >> 24) & 0xF; else - RType = RENext->Type; + RType = (RENext->Word1 >> 28) & 0xF; if (RType != 1) report_fatal_error("Expected GENERIC_RELOC_PAIR after " "GENERIC_RELOC_SECTDIFF."); @@ -771,12 +767,12 @@ MachOObjectFile<MachOT>::getRelocationValueString(DataRefImpl Rel, // X86 sect diff's must be followed by a relocation of type // GENERIC_RELOC_PAIR. bool isNextScattered = (Arch != Triple::x86_64) && - (RENext->Address & macho::RF_Scattered); + (RENext->Word0 & macho::RF_Scattered); unsigned RType; if (isNextScattered) - RType = (RENext->Address >> 24) & 0xF; + RType = (RENext->Word0 >> 24) & 0xF; else - RType = RENext->Type; + RType = (RENext->Word1 >> 28) & 0xF; if (RType != 1) report_fatal_error("Expected GENERIC_RELOC_PAIR after " "GENERIC_RELOC_LOCAL_SECTDIFF."); @@ -789,7 +785,7 @@ MachOObjectFile<MachOT>::getRelocationValueString(DataRefImpl Rel, case macho::RIT_Generic_TLV: { printRelocationTargetName(RE, fmt); fmt << "@TLV"; - if (IsPCRel) fmt << "P"; + if (isPCRel) fmt << "P"; break; } default: @@ -802,10 +798,10 @@ MachOObjectFile<MachOT>::getRelocationValueString(DataRefImpl Rel, // Half relocations steal a bit from the length field to encode // whether this is an upper16 or a lower16 relocation. bool isUpper; - if (IsScattered) - isUpper = (RE->Address >> 28) & 1; + if (isScattered) + isUpper = (RE->Word0 >> 28) & 1; else - isUpper = (RE->Length >> 1) & 1; + isUpper = (RE->Word1 >> 25) & 1; if (isUpper) fmt << ":upper16:("; @@ -820,12 +816,12 @@ MachOObjectFile<MachOT>::getRelocationValueString(DataRefImpl Rel, // ARM half relocs must be followed by a relocation of type // ARM_RELOC_PAIR. bool isNextScattered = (Arch != Triple::x86_64) && - (RENext->Address & macho::RF_Scattered); + (RENext->Word0 & macho::RF_Scattered); unsigned RType; if (isNextScattered) - RType = (RENext->Address >> 24) & 0xF; + RType = (RENext->Word0 >> 24) & 0xF; else - RType = RENext->Type; + RType = (RENext->Word1 >> 28) & 0xF; if (RType != 1) report_fatal_error("Expected ARM_RELOC_PAIR after " @@ -864,8 +860,15 @@ error_code MachOObjectFile<MachOT>::getRelocationHidden(DataRefImpl Rel, bool &Result) const { const RelocationEntry *RE = getRelocation(Rel); + unsigned Arch = getArch(); - unsigned Type = getType(RE); + bool isScattered = (Arch != Triple::x86_64) && + (RE->Word0 & macho::RF_Scattered); + unsigned Type; + if (isScattered) + Type = (RE->Word0 >> 24) & 0xF; + else + Type = (RE->Word1 >> 28) & 0xF; Result = false; @@ -881,7 +884,7 @@ MachOObjectFile<MachOT>::getRelocationHidden(DataRefImpl Rel, RelPrev.d.a--; const RelocationEntry *REPrev = getRelocation(RelPrev); - unsigned PrevType = REPrev->Type; + unsigned PrevType = (REPrev->Word1 >> 28) & 0xF; if (PrevType == macho::RIT_X86_64_Subtractor) Result = true; } diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 98e28db..c846206 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -80,46 +80,6 @@ StringRef MachOObjectFileBase::getData(size_t Offset, size_t Size) const { return ObjectFile::getData().substr(Offset, Size); } -const MachOObjectFileBase::RelocationEntry * -MachOObjectFileBase::getRelocation(DataRefImpl Rel) const { - if (const MachOObjectFile32Le *O = dyn_cast<MachOObjectFile32Le>(this)) - return O->getRelocation(Rel); - const MachOObjectFile64Le *O = dyn_cast<MachOObjectFile64Le>(this); - return O->getRelocation(Rel); -} - -bool MachOObjectFileBase::isScattered(const RelocationEntry *RE) const { - unsigned Arch = getArch(); - return (Arch != Triple::x86_64) && (RE->Address & macho::RF_Scattered); -} - -bool MachOObjectFileBase::isPCRel(const RelocationEntry *RE) const { - if (isScattered(RE)) { - const ScatteredRelocationEntry *SRE = - reinterpret_cast<const ScatteredRelocationEntry *>(RE); - return SRE->PCRel; - } - return RE->PCRel; -} - -unsigned MachOObjectFileBase::getLength(const RelocationEntry *RE) const { - if (isScattered(RE)) { - const ScatteredRelocationEntry *SRE = - reinterpret_cast<const ScatteredRelocationEntry *>(RE); - return SRE->Length; - } - return RE->Length; -} - -unsigned MachOObjectFileBase::getType(const RelocationEntry *RE) const { - if (isScattered(RE)) { - const ScatteredRelocationEntry *SRE = - reinterpret_cast<const ScatteredRelocationEntry *>(RE); - return SRE->Type; - } - return RE->Type; -} - ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { StringRef Magic = Buffer->getBuffer().slice(0, 4); error_code ec; @@ -475,12 +435,16 @@ void advanceTo(T &it, size_t Val) { void MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE, raw_string_ostream &fmt) const { + unsigned Arch = getArch(); + bool isScattered = (Arch != Triple::x86_64) && + (RE->Word0 & macho::RF_Scattered); + // Target of a scattered relocation is an address. In the interest of // generating pretty output, scan through the symbol table looking for a // symbol that aligns with that address. If we find one, print it. // Otherwise, we just print the hex address of the target. - if (isScattered(RE)) { - uint32_t Val = RE->SymbolNum; + if (isScattered) { + uint32_t Val = RE->Word1; error_code ec; for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE; @@ -522,8 +486,8 @@ MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE, } StringRef S; - bool isExtern = RE->External; - uint32_t Val = RE->Address; + bool isExtern = (RE->Word1 >> 27) & 1; + uint32_t Val = RE->Word1 & 0xFFFFFF; if (isExtern) { symbol_iterator SI = begin_symbols(); diff --git a/test/tools/llvm-readobj/relocations.test b/test/tools/llvm-readobj/relocations.test index 96aac23..b4b876a 100644 --- a/test/tools/llvm-readobj/relocations.test +++ b/test/tools/llvm-readobj/relocations.test @@ -26,17 +26,17 @@ ELF-NEXT: ] MACHO-I386: Relocations [ MACHO-I386-NEXT: Section __text { -MACHO-I386-NEXT: 0x18 1 2 1 GENERIC_RELOC_VANILLA 0 _SomeOtherFunction -MACHO-I386-NEXT: 0x13 1 2 1 GENERIC_RELOC_VANILLA 0 _puts -MACHO-I386-NEXT: 0xB 0 2 n/a GENERIC_RELOC_LOCAL_SECTDIFF 1 _main -MACHO-I386-NEXT: 0x0 0 2 n/a GENERIC_RELOC_PAIR 1 _main +MACHO-I386-NEXT: 0x18 GENERIC_RELOC_VANILLA _SomeOtherFunction 0x0 +MACHO-I386-NEXT: 0x13 GENERIC_RELOC_VANILLA _puts 0x0 +MACHO-I386-NEXT: 0xB GENERIC_RELOC_LOCAL_SECTDIFF _main 0x{{[0-9A-F]+}} +MACHO-I386-NEXT: 0x0 GENERIC_RELOC_PAIR _main 0x{{[0-9A-F]+}} MACHO-I386-NEXT: } MACHO-I386-NEXT: ] MACHO-X86-64: Relocations [ MACHO-X86-64-NEXT: Section __text { -MACHO-X86-64-NEXT: 0xE 1 2 1 X86_64_RELOC_BRANCH 0 _SomeOtherFunction -MACHO-X86-64-NEXT: 0x9 1 2 1 X86_64_RELOC_BRANCH 0 _puts -MACHO-X86-64-NEXT: 0x4 1 2 1 X86_64_RELOC_SIGNED 0 L_.str +MACHO-X86-64-NEXT: 0xE X86_64_RELOC_BRANCH _SomeOtherFunction 0x0 +MACHO-X86-64-NEXT: 0x9 X86_64_RELOC_BRANCH _puts 0x0 +MACHO-X86-64-NEXT: 0x4 X86_64_RELOC_SIGNED L_.str 0x0 MACHO-X86-64-NEXT: } MACHO-X86-64-NEXT:] diff --git a/test/tools/llvm-readobj/sections-ext.test b/test/tools/llvm-readobj/sections-ext.test index a12d9e4..a16bca2 100644 --- a/test/tools/llvm-readobj/sections-ext.test +++ b/test/tools/llvm-readobj/sections-ext.test @@ -153,10 +153,10 @@ MACHO-I386-NEXT: ] MACHO-I386-NEXT: Reserved1: 0x0 MACHO-I386-NEXT: Reserved2: 0x0 MACHO-I386-NEXT: Relocations [ -MACHO-I386-NEXT: 0x18 1 2 1 GENERIC_RELOC_VANILLA 0 _SomeOtherFunction -MACHO-I386-NEXT: 0x13 1 2 1 GENERIC_RELOC_VANILLA 0 _puts -MACHO-I386-NEXT: 0xB 0 2 n/a GENERIC_RELOC_LOCAL_SECTDIFF 1 _main -MACHO-I386-NEXT: 0x0 0 2 n/a GENERIC_RELOC_PAIR 1 _main +MACHO-I386-NEXT: 0x18 GENERIC_RELOC_VANILLA _SomeOtherFunction 0x0 +MACHO-I386-NEXT: 0x13 GENERIC_RELOC_VANILLA _puts 0x0 +MACHO-I386-NEXT: 0xB GENERIC_RELOC_LOCAL_SECTDIFF _main 0x{{[0-9A-F]+}} +MACHO-I386-NEXT: 0x0 GENERIC_RELOC_PAIR _main 0x{{[0-9A-F]+}} MACHO-I386-NEXT: ] MACHO-I386-NEXT: Symbols [ MACHO-I386-NEXT: Symbol { @@ -196,9 +196,9 @@ MACHO-X86-64-NEXT: ] MACHO-X86-64-NEXT: Reserved1: 0x0 MACHO-X86-64-NEXT: Reserved2: 0x0 MACHO-X86-64-NEXT: Relocations [ -MACHO-X86-64-NEXT: 0xE 1 2 1 X86_64_RELOC_BRANCH 0 _SomeOtherFunction -MACHO-X86-64-NEXT: 0x9 1 2 1 X86_64_RELOC_BRANCH 0 _puts -MACHO-X86-64-NEXT: 0x4 1 2 1 X86_64_RELOC_SIGNED 0 L_.str +MACHO-X86-64-NEXT: 0xE X86_64_RELOC_BRANCH _SomeOtherFunction 0x0 +MACHO-X86-64-NEXT: 0x9 X86_64_RELOC_BRANCH _puts 0x0 +MACHO-X86-64-NEXT: 0x4 X86_64_RELOC_SIGNED L_.str 0x0 MACHO-X86-64-NEXT: ] MACHO-X86-64-NEXT: Symbols [ MACHO-X86-64-NEXT: Symbol { diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index b027d40..2073ddf 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -330,28 +330,20 @@ void MachODumper::printRelocation(section_iterator SecI, relocation_iterator RelI) { uint64_t Offset; SmallString<32> RelocName; + int64_t Info; StringRef SymbolName; SymbolRef Symbol; if (error(RelI->getOffset(Offset))) return; if (error(RelI->getTypeName(RelocName))) return; + if (error(RelI->getAdditionalInfo(Info))) return; if (error(RelI->getSymbol(Symbol))) return; if (error(Symbol.getName(SymbolName))) return; - DataRefImpl DR = RelI->getRawDataRefImpl(); - const MachOObjectFileBase::RelocationEntry *RE = Obj->getRelocation(DR); - bool IsScattered = Obj->isScattered(RE); - raw_ostream& OS = W.startLine(); OS << W.hex(Offset) - << " " << Obj->isPCRel(RE) - << " " << Obj->getLength(RE); - if (IsScattered) - OS << " n/a"; - else - OS << " " << RE->External; - OS << " " << RelocName - << " " << IsScattered + << " " << RelocName << " " << (SymbolName.size() > 0 ? SymbolName : "-") + << " " << W.hex(Info) << "\n"; } |