diff options
| author | Kevin Enderby <enderby@apple.com> | 2015-01-27 21:28:24 +0000 |
|---|---|---|
| committer | Kevin Enderby <enderby@apple.com> | 2015-01-27 21:28:24 +0000 |
| commit | 9a50944ca0e54710009831237f03b4309dfad373 (patch) | |
| tree | 5ab521d4f3fe3716b5d8bda89bacdb5230471778 /llvm | |
| parent | 3b95af6249314e0e963646c927db044bbfb0f745 (diff) | |
| download | bcm5719-llvm-9a50944ca0e54710009831237f03b4309dfad373.tar.gz bcm5719-llvm-9a50944ca0e54710009831237f03b4309dfad373.zip | |
dd the option, -link-opt-hints to llvm-objdump used with -macho to print the
Mach-O AArch64 linker optimization hints for ADRP code optimization.
llvm-svn: 227246
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/Object/MachO.h | 2 | ||||
| -rw-r--r-- | llvm/lib/Object/MachOObjectFile.cpp | 27 | ||||
| -rw-r--r-- | llvm/test/tools/llvm-objdump/AArch64/Inputs/link-opt-hints.macho-aarch64 | bin | 0 -> 984 bytes | |||
| -rw-r--r-- | llvm/test/tools/llvm-objdump/AArch64/macho-link-opt-hints.test | 11 | ||||
| -rw-r--r-- | llvm/tools/llvm-objdump/MachODump.cpp | 67 | ||||
| -rw-r--r-- | llvm/tools/llvm-objdump/llvm-objdump.cpp | 3 | ||||
| -rw-r--r-- | llvm/tools/llvm-objdump/llvm-objdump.h | 1 |
7 files changed, 107 insertions, 4 deletions
diff --git a/llvm/include/llvm/Object/MachO.h b/llvm/include/llvm/Object/MachO.h index bee1f6ce0b0..a552aca91d7 100644 --- a/llvm/include/llvm/Object/MachO.h +++ b/llvm/include/llvm/Object/MachO.h @@ -395,6 +395,7 @@ public: MachO::symtab_command getSymtabLoadCommand() const; MachO::dysymtab_command getDysymtabLoadCommand() const; MachO::linkedit_data_command getDataInCodeLoadCommand() const; + MachO::linkedit_data_command getLinkOptHintsLoadCommand() const; ArrayRef<uint8_t> getDyldInfoRebaseOpcodes() const; ArrayRef<uint8_t> getDyldInfoBindOpcodes() const; ArrayRef<uint8_t> getDyldInfoWeakBindOpcodes() const; @@ -437,6 +438,7 @@ private: const char *SymtabLoadCmd; const char *DysymtabLoadCmd; const char *DataInCodeLoadCmd; + const char *LinkOptHintsLoadCmd; const char *DyldInfoLoadCmd; const char *UuidLoadCmd; bool HasPageZeroSegment; diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp index 4f544074c3d..4a1c311dd09 100644 --- a/llvm/lib/Object/MachOObjectFile.cpp +++ b/llvm/lib/Object/MachOObjectFile.cpp @@ -248,8 +248,9 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64bits, std::error_code &EC) : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object), SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr), - DataInCodeLoadCmd(nullptr), DyldInfoLoadCmd(nullptr), - UuidLoadCmd(nullptr), HasPageZeroSegment(false) { + DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr), + DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr), + HasPageZeroSegment(false) { uint32_t LoadCommandCount = this->getHeader().ncmds; if (LoadCommandCount == 0) return; @@ -280,6 +281,13 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, return; } DataInCodeLoadCmd = Load.Ptr; + } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) { + // Multiple linker optimization hint tables + if (LinkOptHintsLoadCmd) { + EC = object_error::parse_failed; + return; + } + LinkOptHintsLoadCmd = Load.Ptr; } else if (Load.C.cmd == MachO::LC_DYLD_INFO || Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) { // Multiple dyldinfo load commands @@ -2497,6 +2505,21 @@ MachOObjectFile::getDataInCodeLoadCommand() const { return Cmd; } +MachO::linkedit_data_command +MachOObjectFile::getLinkOptHintsLoadCommand() const { + if (LinkOptHintsLoadCmd) + return getStruct<MachO::linkedit_data_command>(this, LinkOptHintsLoadCmd); + + // If there is no LinkOptHintsLoadCmd return a load command with zero'ed + // fields. + MachO::linkedit_data_command Cmd; + Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT; + Cmd.cmdsize = sizeof(MachO::linkedit_data_command); + Cmd.dataoff = 0; + Cmd.datasize = 0; + return Cmd; +} + ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const { if (!DyldInfoLoadCmd) return ArrayRef<uint8_t>(); diff --git a/llvm/test/tools/llvm-objdump/AArch64/Inputs/link-opt-hints.macho-aarch64 b/llvm/test/tools/llvm-objdump/AArch64/Inputs/link-opt-hints.macho-aarch64 Binary files differnew file mode 100644 index 00000000000..12d33fcdf75 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/AArch64/Inputs/link-opt-hints.macho-aarch64 diff --git a/llvm/test/tools/llvm-objdump/AArch64/macho-link-opt-hints.test b/llvm/test/tools/llvm-objdump/AArch64/macho-link-opt-hints.test new file mode 100644 index 00000000000..932bc4fa838 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/AArch64/macho-link-opt-hints.test @@ -0,0 +1,11 @@ +RUN: llvm-objdump -m -link-opt-hints %p/Inputs/link-opt-hints.macho-aarch64 | FileCheck %s + +CHECK: Linker optimiztion hints (8 total bytes) +CHECK: identifier 8 AdrpLdrGot +CHECK: narguments 2 +CHECK: value 0x18 +CHECK: value 0x1c +CHECK: identifier 7 AdrpAdd +CHECK: narguments 2 +CHECK: value 0x6c +CHECK: value 0x70 diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp index 67aa6a3c1ad..e103842e54f 100644 --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -36,6 +36,7 @@ #include "llvm/Support/Format.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/GraphWriter.h" +#include "llvm/Support/LEB128.h" #include "llvm/Support/MachO.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/TargetRegistry.h" @@ -85,6 +86,11 @@ cl::opt<bool> cl::desc("Print the data in code table for Mach-O objects " "(requires -macho)")); +cl::opt<bool> + llvm::LinkOptHints("link-opt-hints", + cl::desc("Print the linker optimization hints for " + "Mach-O objects (requires -macho)")); + static cl::list<std::string> ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"), cl::ZeroOrMore); @@ -436,6 +442,63 @@ static void PrintDataInCodeTable(MachOObjectFile *O, bool verbose) { } } +static void PrintLinkOptHints(MachOObjectFile *O) { + MachO::linkedit_data_command LohLC = O->getLinkOptHintsLoadCommand(); + const char *loh = O->getData().substr(LohLC.dataoff, 1).data(); + uint32_t nloh = LohLC.datasize; + outs() << "Linker optimiztion hints (" << nloh << " total bytes)\n"; + for (uint32_t i = 0; i < nloh;) { + unsigned n; + uint64_t identifier = decodeULEB128((const uint8_t *)(loh + i), &n); + i += n; + outs() << " identifier " << identifier << " "; + if (i >= nloh) + return; + switch (identifier) { + case 1: + outs() << "AdrpAdrp\n"; + break; + case 2: + outs() << "AdrpLdr\n"; + break; + case 3: + outs() << "AdrpAddLdr\n"; + break; + case 4: + outs() << "AdrpLdrGotLdr\n"; + break; + case 5: + outs() << "AdrpAddStr\n"; + break; + case 6: + outs() << "AdrpLdrGotStr\n"; + break; + case 7: + outs() << "AdrpAdd\n"; + break; + case 8: + outs() << "AdrpLdrGot\n"; + break; + default: + outs() << "Unknown identifier value\n"; + break; + } + uint64_t narguments = decodeULEB128((const uint8_t *)(loh + i), &n); + i += n; + outs() << " narguments " << narguments << "\n"; + if (i >= nloh) + return; + + for (uint32_t j = 0; j < narguments; j++) { + uint64_t value = decodeULEB128((const uint8_t *)(loh + i), &n); + i += n; + outs() << "\tvalue " << format("0x%" PRIx64, value) << "\n"; + if (i >= nloh) + return; + } + } +} + // checkMachOAndArchFlags() checks to see if the ObjectFile is a Mach-O file // and if it is and there is a list of architecture flags is specified then // check to make sure this Mach-O file is one of those architectures or all @@ -483,7 +546,7 @@ static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF, // info. And don't print it otherwise like in the case of printing the // UniversalHeaders or ArchiveHeaders. if (Disassemble || PrivateHeaders || ExportsTrie || Rebase || Bind || - LazyBind || WeakBind || IndirectSymbols || DataInCode) { + LazyBind || WeakBind || IndirectSymbols || DataInCode || LinkOptHints) { outs() << Filename; if (!ArchiveMemberName.empty()) outs() << '(' << ArchiveMemberName << ')'; @@ -498,6 +561,8 @@ static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF, PrintIndirectSymbols(MachOOF, true); if (DataInCode) PrintDataInCodeTable(MachOOF, true); + if (LinkOptHints) + PrintLinkOptHints(MachOOF); if (Relocations) PrintRelocations(MachOOF); if (SectionHeaders) diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 1204a973d45..4935f98eca1 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -905,7 +905,8 @@ int main(int argc, char **argv) { && !(UniversalHeaders && MachOOpt) && !(ArchiveHeaders && MachOOpt) && !(IndirectSymbols && MachOOpt) - && !(DataInCode && MachOOpt)) { + && !(DataInCode && MachOOpt) + && !(LinkOptHints && MachOOpt)) { cl::PrintHelpMessage(); return 2; } diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h index 9bc9622c0a9..402632daea7 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.h +++ b/llvm/tools/llvm-objdump/llvm-objdump.h @@ -38,6 +38,7 @@ extern cl::opt<bool> UniversalHeaders; extern cl::opt<bool> ArchiveHeaders; extern cl::opt<bool> IndirectSymbols; extern cl::opt<bool> DataInCode; +extern cl::opt<bool> LinkOptHints; extern cl::opt<bool> Relocations; extern cl::opt<bool> SectionHeaders; extern cl::opt<bool> SectionContents; |

