X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=tools%2Fllvm-readobj%2Fllvm-readobj.cpp;h=2a75ababb2e8a60f7eff67a8cab760556079cb04;hp=d66c02f4130b4d0a04d8d7655c643a1ae7a39ad1;hb=3aa1034794ef6a4c9b9196c00debbd318b36fdd3;hpb=1ad45020ec8518a5c9bea7ec1007798a456bff56 diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index d66c02f4130..2a75ababb2e 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -24,6 +24,9 @@ #include "ObjDumper.h" #include "StreamWriter.h" #include "llvm/Object/Archive.h" +#include "llvm/Object/COFFImportFile.h" +#include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" @@ -38,7 +41,6 @@ #include #include - using namespace llvm; using namespace llvm::object; @@ -89,6 +91,10 @@ namespace opts { cl::desc("Alias for --relocations"), cl::aliasopt(Relocations)); + // -dyn-relocations + cl::opt DynRelocs("dyn-relocations", + cl::desc("Display the dynamic relocation entries in the file")); + // -symbols, -t cl::opt Symbols("symbols", cl::desc("Display the symbol table")); @@ -122,40 +128,124 @@ namespace opts { cl::opt ProgramHeaders("program-headers", cl::desc("Display ELF program headers")); + // -hash-table + cl::opt HashTable("hash-table", + cl::desc("Display ELF hash table")); + + // -gnu-hash-table + cl::opt GnuHashTable("gnu-hash-table", + cl::desc("Display ELF .gnu.hash section")); + // -expand-relocs cl::opt ExpandRelocs("expand-relocs", cl::desc("Expand each shown relocation to multiple lines")); - // -codeview-linetables - cl::opt CodeViewLineTables("codeview-linetables", - cl::desc("Display CodeView line table information")); + // -codeview + cl::opt CodeView("codeview", + cl::desc("Display CodeView debug information")); + + // -codeview-subsection-bytes + cl::opt CodeViewSubsectionBytes( + "codeview-subsection-bytes", + cl::desc("Dump raw contents of codeview debug sections and records")); // -arm-attributes, -a cl::opt ARMAttributes("arm-attributes", cl::desc("Display the ARM attributes section")); cl::alias ARMAttributesShort("-a", cl::desc("Alias for --arm-attributes"), cl::aliasopt(ARMAttributes)); -} // namespace opts -static int ReturnValue = EXIT_SUCCESS; + // -mips-plt-got + cl::opt + MipsPLTGOT("mips-plt-got", + cl::desc("Display the MIPS GOT and PLT GOT sections")); + + // -mips-abi-flags + cl::opt MipsABIFlags("mips-abi-flags", + cl::desc("Display the MIPS.abiflags section")); + + // -mips-reginfo + cl::opt MipsReginfo("mips-reginfo", + cl::desc("Display the MIPS .reginfo section")); + + // -coff-imports + cl::opt + COFFImports("coff-imports", cl::desc("Display the PE/COFF import table")); + + // -coff-exports + cl::opt + COFFExports("coff-exports", cl::desc("Display the PE/COFF export table")); + + // -coff-directives + cl::opt + COFFDirectives("coff-directives", + cl::desc("Display the PE/COFF .drectve section")); + + // -coff-basereloc + cl::opt + COFFBaseRelocs("coff-basereloc", + cl::desc("Display the PE/COFF .reloc section")); + + // -macho-data-in-code + cl::opt + MachODataInCode("macho-data-in-code", + cl::desc("Display MachO Data in Code command")); + + // -macho-indirect-symbols + cl::opt + MachOIndirectSymbols("macho-indirect-symbols", + cl::desc("Display MachO indirect symbols")); + + // -macho-linker-options + cl::opt + MachOLinkerOptions("macho-linker-options", + cl::desc("Display MachO linker options")); + + // -macho-segment + cl::opt + MachOSegment("macho-segment", + cl::desc("Display MachO Segment command")); + + // -macho-version-min + cl::opt + MachOVersionMin("macho-version-min", + cl::desc("Display MachO version min command")); + + // -macho-dysymtab + cl::opt + MachODysymtab("macho-dysymtab", + cl::desc("Display MachO Dysymtab command")); + + // -stackmap + cl::opt + PrintStackMap("stackmap", + cl::desc("Display contents of stackmap section")); + + // -version-info + cl::opt + VersionInfo("version-info", + cl::desc("Display ELF version sections (if present)")); + cl::alias VersionInfoShort("V", cl::desc("Alias for -version-info"), + cl::aliasopt(VersionInfo)); +} // namespace opts namespace llvm { -bool error(std::error_code EC) { +LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg) { + outs() << "\nError reading file: " << Msg << ".\n"; + outs().flush(); + exit(1); +} + +void error(std::error_code EC) { if (!EC) - return false; + return; - ReturnValue = EXIT_FAILURE; - outs() << "\nError reading file: " << EC.message() << ".\n"; - outs().flush(); - return true; + reportError(EC.message()); } bool relocAddressLess(RelocationRef a, RelocationRef b) { - uint64_t a_addr, b_addr; - if (error(a.getOffset(a_addr))) return false; - if (error(b.getOffset(b_addr))) return false; - return a_addr < b_addr; + return a.getOffset() < b.getOffset(); } } // namespace llvm @@ -164,17 +254,26 @@ static void reportError(StringRef Input, std::error_code EC) { if (Input == "-") Input = ""; - errs() << Input << ": " << EC.message() << "\n"; - errs().flush(); - ReturnValue = EXIT_FAILURE; + reportError(Twine(Input) + ": " + EC.message()); } static void reportError(StringRef Input, StringRef Message) { if (Input == "-") Input = ""; - errs() << Input << ": " << Message << "\n"; - ReturnValue = EXIT_FAILURE; + reportError(Twine(Input) + ": " + Message); +} + +static bool isMipsArch(unsigned Arch) { + switch (Arch) { + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + return true; + default: + return false; + } } /// @brief Creates an format-specific object file dumper. @@ -193,15 +292,12 @@ static std::error_code createDumper(const ObjectFile *Obj, StreamWriter &Writer, return readobj_error::unsupported_obj_file_format; } - /// @brief Dumps the specified object file. static void dumpObject(const ObjectFile *Obj) { StreamWriter Writer(outs()); std::unique_ptr Dumper; - if (std::error_code EC = createDumper(Obj, Writer, Dumper)) { + if (std::error_code EC = createDumper(Obj, Writer, Dumper)) reportError(Obj->getFileName(), EC); - return; - } outs() << '\n'; outs() << "File: " << Obj->getFileName() << "\n"; @@ -210,8 +306,7 @@ static void dumpObject(const ObjectFile *Obj) { << Triple::getArchTypeName((llvm::Triple::ArchType)Obj->getArch()) << "\n"; outs() << "AddressSize: " << (8*Obj->getBytesInAddress()) << "bit\n"; - if (Obj->isELF()) - outs() << "LoadName: " << Obj->getLoadName() << "\n"; + Dumper->printLoadName(); if (opts::FileHeaders) Dumper->printFileHeaders(); @@ -219,6 +314,8 @@ static void dumpObject(const ObjectFile *Obj) { Dumper->printSections(); if (opts::Relocations) Dumper->printRelocations(); + if (opts::DynRelocs) + Dumper->printDynamicRelocations(); if (opts::Symbols) Dumper->printSymbols(); if (opts::DynamicSymbols) @@ -231,66 +328,112 @@ static void dumpObject(const ObjectFile *Obj) { Dumper->printNeededLibraries(); if (opts::ProgramHeaders) Dumper->printProgramHeaders(); + if (opts::HashTable) + Dumper->printHashTable(); + if (opts::GnuHashTable) + Dumper->printGnuHashTable(); + if (opts::VersionInfo) + Dumper->printVersionInfo(); if (Obj->getArch() == llvm::Triple::arm && Obj->isELF()) if (opts::ARMAttributes) Dumper->printAttributes(); + if (isMipsArch(Obj->getArch()) && Obj->isELF()) { + if (opts::MipsPLTGOT) + Dumper->printMipsPLTGOT(); + if (opts::MipsABIFlags) + Dumper->printMipsABIFlags(); + if (opts::MipsReginfo) + Dumper->printMipsReginfo(); + } + if (Obj->isCOFF()) { + if (opts::COFFImports) + Dumper->printCOFFImports(); + if (opts::COFFExports) + Dumper->printCOFFExports(); + if (opts::COFFDirectives) + Dumper->printCOFFDirectives(); + if (opts::COFFBaseRelocs) + Dumper->printCOFFBaseReloc(); + } + if (Obj->isMachO()) { + if (opts::MachODataInCode) + Dumper->printMachODataInCode(); + if (opts::MachOIndirectSymbols) + Dumper->printMachOIndirectSymbols(); + if (opts::MachOLinkerOptions) + Dumper->printMachOLinkerOptions(); + if (opts::MachOSegment) + Dumper->printMachOSegment(); + if (opts::MachOVersionMin) + Dumper->printMachOVersionMin(); + if (opts::MachODysymtab) + Dumper->printMachODysymtab(); + } + if (opts::PrintStackMap) + Dumper->printStackMap(); } - /// @brief Dumps each object file in \a Arc; static void dumpArchive(const Archive *Arc) { - for (Archive::child_iterator ArcI = Arc->child_begin(), - ArcE = Arc->child_end(); - ArcI != ArcE; ++ArcI) { - std::unique_ptr child; - if (std::error_code EC = ArcI->getAsBinary(child)) { + for (auto &ErrorOrChild : Arc->children()) { + if (std::error_code EC = ErrorOrChild.getError()) + reportError(Arc->getFileName(), EC.message()); + const auto &Child = *ErrorOrChild; + ErrorOr> ChildOrErr = Child.getAsBinary(); + if (std::error_code EC = ChildOrErr.getError()) { // Ignore non-object files. if (EC != object_error::invalid_file_type) reportError(Arc->getFileName(), EC.message()); continue; } - if (ObjectFile *Obj = dyn_cast(child.get())) + if (ObjectFile *Obj = dyn_cast(&*ChildOrErr.get())) dumpObject(Obj); else reportError(Arc->getFileName(), readobj_error::unrecognized_file_format); } } +/// @brief Dumps each object file in \a MachO Universal Binary; +static void dumpMachOUniversalBinary(const MachOUniversalBinary *UBinary) { + for (const MachOUniversalBinary::ObjectForArch &Obj : UBinary->objects()) { + ErrorOr> ObjOrErr = Obj.getAsObjectFile(); + if (ObjOrErr) + dumpObject(&*ObjOrErr.get()); + else if (ErrorOr> AOrErr = Obj.getAsArchive()) + dumpArchive(&*AOrErr.get()); + else + reportError(UBinary->getFileName(), ObjOrErr.getError().message()); + } +} /// @brief Opens \a File and dumps it. static void dumpInput(StringRef File) { - // If file isn't stdin, check that it exists. - if (File != "-" && !sys::fs::exists(File)) { - reportError(File, readobj_error::file_not_found); - return; - } // Attempt to open the binary. - ErrorOr BinaryOrErr = createBinary(File); - if (std::error_code EC = BinaryOrErr.getError()) { + ErrorOr> BinaryOrErr = createBinary(File); + if (std::error_code EC = BinaryOrErr.getError()) reportError(File, EC); - return; - } - std::unique_ptr Binary(BinaryOrErr.get()); + Binary &Binary = *BinaryOrErr.get().getBinary(); - if (Archive *Arc = dyn_cast(Binary.get())) + if (Archive *Arc = dyn_cast(&Binary)) dumpArchive(Arc); - else if (ObjectFile *Obj = dyn_cast(Binary.get())) + else if (MachOUniversalBinary *UBinary = + dyn_cast(&Binary)) + dumpMachOUniversalBinary(UBinary); + else if (ObjectFile *Obj = dyn_cast(&Binary)) dumpObject(Obj); + else if (COFFImportFile *Import = dyn_cast(&Binary)) + dumpCOFFImportFile(Import); else reportError(File, readobj_error::unrecognized_file_format); } - int main(int argc, const char *argv[]) { sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; - // Initialize targets. - llvm::InitializeAllTargetInfos(); - // Register the target printer for --version. cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); @@ -303,5 +446,5 @@ int main(int argc, const char *argv[]) { std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(), dumpInput); - return ReturnValue; + return 0; }