1a9232f7f5d00d900eb10a39e0b7786954d6eac69Benjamin Kramer//===- llvm-readobj.cpp - Dump contents of an Object File -----------------===// 25c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer// 35c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer// The LLVM Compiler Infrastructure 45c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer// 55c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer// This file is distributed under the University of Illinois Open Source 65c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer// License. See LICENSE.TXT for details. 75c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer// 85c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer//===----------------------------------------------------------------------===// 95c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer// 10dd3aa9eab2b40ea1573a5482472bbb89e6f1038dMichael J. Spencer// This is a tool similar to readelf, except it works on multiple object file 11dd3aa9eab2b40ea1573a5482472bbb89e6f1038dMichael J. Spencer// formats. The main purpose of this tool is to provide detailed output suitable 12dd3aa9eab2b40ea1573a5482472bbb89e6f1038dMichael J. Spencer// for FileCheck. 13ee37b6e4cd53b8e2412c522eeab4e39b434f00c6David Meyer// 14dd3aa9eab2b40ea1573a5482472bbb89e6f1038dMichael J. Spencer// Flags should be similar to readelf where supported, but the output format 15dd3aa9eab2b40ea1573a5482472bbb89e6f1038dMichael J. Spencer// does not need to be identical. The point is to not make users learn yet 16dd3aa9eab2b40ea1573a5482472bbb89e6f1038dMichael J. Spencer// another set of flags. 17ee37b6e4cd53b8e2412c522eeab4e39b434f00c6David Meyer// 18dd3aa9eab2b40ea1573a5482472bbb89e6f1038dMichael J. Spencer// Output should be specialized for each format where appropriate. 19ee37b6e4cd53b8e2412c522eeab4e39b434f00c6David Meyer// 20ee37b6e4cd53b8e2412c522eeab4e39b434f00c6David Meyer//===----------------------------------------------------------------------===// 215c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 22d326d05fb9c794e93fc7fc0601028f196600f7e2Michael J. Spencer#include "llvm-readobj.h" 2376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "Error.h" 2476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "ObjDumper.h" 2576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "StreamWriter.h" 2676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/Object/Archive.h" 27f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Object/ObjectFile.h" 2876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/Support/Casting.h" 295c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer#include "llvm/Support/CommandLine.h" 3076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/Support/DataTypes.h" 315c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer#include "llvm/Support/Debug.h" 3276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/Support/FileSystem.h" 3376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/Support/ManagedStatic.h" 34f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Support/PrettyStackTrace.h" 35f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Support/Signals.h" 3676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/Support/TargetRegistry.h" 3776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/Support/TargetSelect.h" 3876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include <string> 39cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include <system_error> 4076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 415c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 425c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerusing namespace llvm; 435c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerusing namespace llvm::object; 445c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 4576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophernamespace opts { 4676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::list<std::string> InputFilenames(cl::Positional, 4776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("<input object files>"), 4876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::ZeroOrMore); 4976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 5076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // -file-headers, -h 5176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::opt<bool> FileHeaders("file-headers", 5276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Display file headers ")); 5376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::alias FileHeadersShort("h", 5476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Alias for --file-headers"), 5576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::aliasopt(FileHeaders)); 5676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 5776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // -sections, -s 5876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::opt<bool> Sections("sections", 5976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Display all sections.")); 6076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::alias SectionsShort("s", 6176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Alias for --sections"), 6276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::aliasopt(Sections)); 6376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 6476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // -section-relocations, -sr 6576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::opt<bool> SectionRelocations("section-relocations", 6676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Display relocations for each section shown.")); 6776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::alias SectionRelocationsShort("sr", 6876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Alias for --section-relocations"), 6976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::aliasopt(SectionRelocations)); 7076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 7176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // -section-symbols, -st 7276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::opt<bool> SectionSymbols("section-symbols", 7376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Display symbols for each section shown.")); 7476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::alias SectionSymbolsShort("st", 7576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Alias for --section-symbols"), 7676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::aliasopt(SectionSymbols)); 7776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 7876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // -section-data, -sd 7976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::opt<bool> SectionData("section-data", 8076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Display section data for each section shown.")); 8176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::alias SectionDataShort("sd", 8276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Alias for --section-data"), 8376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::aliasopt(SectionData)); 8476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 8576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // -relocations, -r 8676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::opt<bool> Relocations("relocations", 8776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Display the relocation entries in the file")); 8876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::alias RelocationsShort("r", 8976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Alias for --relocations"), 9076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::aliasopt(Relocations)); 9176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 9276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // -symbols, -t 9376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::opt<bool> Symbols("symbols", 9476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Display the symbol table")); 9576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::alias SymbolsShort("t", 9676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Alias for --symbols"), 9776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::aliasopt(Symbols)); 9876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 9976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // -dyn-symbols, -dt 10076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::opt<bool> DynamicSymbols("dyn-symbols", 10176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Display the dynamic symbol table")); 10276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::alias DynamicSymbolsShort("dt", 10376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Alias for --dyn-symbols"), 10476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::aliasopt(DynamicSymbols)); 10576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 10676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // -unwind, -u 10776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::opt<bool> UnwindInfo("unwind", 10876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Display unwind information")); 10976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::alias UnwindInfoShort("u", 11076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Alias for --unwind"), 11176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::aliasopt(UnwindInfo)); 11276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 11376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // -dynamic-table 11476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::opt<bool> DynamicTable("dynamic-table", 11576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Display the ELF .dynamic section table")); 11676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 11776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // -needed-libs 11876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::opt<bool> NeededLibraries("needed-libs", 11976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::desc("Display the needed libraries")); 1201c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck 121cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck // -program-headers 122cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck cl::opt<bool> ProgramHeaders("program-headers", 123cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck cl::desc("Display ELF program headers")); 124cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck 1251c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck // -expand-relocs 1261c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck cl::opt<bool> ExpandRelocs("expand-relocs", 1271c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck cl::desc("Expand each shown relocation to multiple lines")); 12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // -codeview-linetables 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::opt<bool> CodeViewLineTables("codeview-linetables", 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::desc("Display CodeView line table information")); 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // -arm-attributes, -a 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::opt<bool> ARMAttributes("arm-attributes", 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::desc("Display the ARM attributes section")); 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::alias ARMAttributesShort("-a", cl::desc("Alias for --arm-attributes"), 13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::aliasopt(ARMAttributes)); 138cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 139cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // -mips-plt-got 140cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines cl::opt<bool> 141cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsPLTGOT("mips-plt-got", 142cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines cl::desc("Display the MIPS GOT and PLT GOT sections")); 14376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher} // namespace opts 14476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 145081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencerstatic int ReturnValue = EXIT_SUCCESS; 146081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer 14776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophernamespace llvm { 14876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 149cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool error(std::error_code EC) { 15076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (!EC) 15176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher return false; 15276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 153081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer ReturnValue = EXIT_FAILURE; 15476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher outs() << "\nError reading file: " << EC.message() << ".\n"; 15576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher outs().flush(); 15676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher return true; 157148ee4f224be6448834bf039807c70bb1a7c78f5Rafael Espindola} 158148ee4f224be6448834bf039807c70bb1a7c78f5Rafael Espindola 15976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherbool relocAddressLess(RelocationRef a, RelocationRef b) { 16076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher uint64_t a_addr, b_addr; 161956ca7265c697107708468b7e1b2fd21f4185baeRafael Espindola if (error(a.getOffset(a_addr))) return false; 162956ca7265c697107708468b7e1b2fd21f4185baeRafael Espindola if (error(b.getOffset(b_addr))) return false; 16376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher return a_addr < b_addr; 164fc73847d8fa79d310b26b7a80275dc48755ec2e3Rafael Espindola} 165fc73847d8fa79d310b26b7a80275dc48755ec2e3Rafael Espindola 16676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher} // namespace llvm 1675c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 168cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic void reportError(StringRef Input, std::error_code EC) { 16976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (Input == "-") 17076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher Input = "<stdin>"; 171fc73847d8fa79d310b26b7a80275dc48755ec2e3Rafael Espindola 17276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher errs() << Input << ": " << EC.message() << "\n"; 17376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher errs().flush(); 174081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer ReturnValue = EXIT_FAILURE; 175fc73847d8fa79d310b26b7a80275dc48755ec2e3Rafael Espindola} 176fc73847d8fa79d310b26b7a80275dc48755ec2e3Rafael Espindola 17776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic void reportError(StringRef Input, StringRef Message) { 17876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (Input == "-") 17976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher Input = "<stdin>"; 1805c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 18176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher errs() << Input << ": " << Message << "\n"; 182081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer ReturnValue = EXIT_FAILURE; 1835c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 1845c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 185cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic bool isMipsArch(unsigned Arch) { 186cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines switch (Arch) { 187cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case llvm::Triple::mips: 188cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case llvm::Triple::mipsel: 189cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case llvm::Triple::mips64: 190cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case llvm::Triple::mips64el: 191cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return true; 192cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines default: 193cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 194cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 195cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 196cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 19776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher/// @brief Creates an format-specific object file dumper. 198cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic std::error_code createDumper(const ObjectFile *Obj, StreamWriter &Writer, 199cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::unique_ptr<ObjDumper> &Result) { 20076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (!Obj) 20176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher return readobj_error::unsupported_file_format; 20276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 20376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (Obj->isCOFF()) 20476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher return createCOFFDumper(Obj, Writer, Result); 20576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (Obj->isELF()) 20676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher return createELFDumper(Obj, Writer, Result); 20776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (Obj->isMachO()) 20876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher return createMachODumper(Obj, Writer, Result); 20976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 21076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher return readobj_error::unsupported_obj_file_format; 2115c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 2125c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 213fc73847d8fa79d310b26b7a80275dc48755ec2e3Rafael Espindola 21476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher/// @brief Dumps the specified object file. 21576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic void dumpObject(const ObjectFile *Obj) { 21676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher StreamWriter Writer(outs()); 21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<ObjDumper> Dumper; 218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = createDumper(Obj, Writer, Dumper)) { 21976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher reportError(Obj->getFileName(), EC); 22076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher return; 221fc73847d8fa79d310b26b7a80275dc48755ec2e3Rafael Espindola } 222fc73847d8fa79d310b26b7a80275dc48755ec2e3Rafael Espindola 22376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher outs() << '\n'; 22476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher outs() << "File: " << Obj->getFileName() << "\n"; 22576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher outs() << "Format: " << Obj->getFileFormatName() << "\n"; 22676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher outs() << "Arch: " 22776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher << Triple::getArchTypeName((llvm::Triple::ArchType)Obj->getArch()) 22897f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer << "\n"; 22976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher outs() << "AddressSize: " << (8*Obj->getBytesInAddress()) << "bit\n"; 23076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (Obj->isELF()) 23176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher outs() << "LoadName: " << Obj->getLoadName() << "\n"; 23276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 23376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (opts::FileHeaders) 23476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher Dumper->printFileHeaders(); 23576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (opts::Sections) 23676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher Dumper->printSections(); 23776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (opts::Relocations) 23876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher Dumper->printRelocations(); 23976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (opts::Symbols) 24076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher Dumper->printSymbols(); 24176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (opts::DynamicSymbols) 24276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher Dumper->printDynamicSymbols(); 24376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (opts::UnwindInfo) 24476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher Dumper->printUnwindInfo(); 24576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (opts::DynamicTable) 24676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher Dumper->printDynamicTable(); 24776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (opts::NeededLibraries) 24876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher Dumper->printNeededLibraries(); 249cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck if (opts::ProgramHeaders) 250cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck Dumper->printProgramHeaders(); 25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Obj->getArch() == llvm::Triple::arm && Obj->isELF()) 25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (opts::ARMAttributes) 25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Dumper->printAttributes(); 254cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (isMipsArch(Obj->getArch()) && Obj->isELF()) 255cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (opts::MipsPLTGOT) 256cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Dumper->printMipsPLTGOT(); 25797f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer} 25897f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer 2595c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 26076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher/// @brief Dumps each object file in \a Arc; 26176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic void dumpArchive(const Archive *Arc) { 26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (Archive::child_iterator ArcI = Arc->child_begin(), 26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ArcE = Arc->child_end(); 26476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher ArcI != ArcE; ++ArcI) { 265cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorOr<std::unique_ptr<Binary>> ChildOrErr = ArcI->getAsBinary(); 266cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = ChildOrErr.getError()) { 26776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // Ignore non-object files. 26876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (EC != object_error::invalid_file_type) 26976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher reportError(Arc->getFileName(), EC.message()); 27076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher continue; 27176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher } 2725c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 273cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ObjectFile *Obj = dyn_cast<ObjectFile>(&*ChildOrErr.get())) 27476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher dumpObject(Obj); 27576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher else 27676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher reportError(Arc->getFileName(), readobj_error::unrecognized_file_format); 2775c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer } 27876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher} 27976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 2805c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 28176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher/// @brief Opens \a File and dumps it. 28276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic void dumpInput(StringRef File) { 28376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // If file isn't stdin, check that it exists. 28476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (File != "-" && !sys::fs::exists(File)) { 28576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher reportError(File, readobj_error::file_not_found); 28676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher return; 2875c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer } 2885c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 28976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // Attempt to open the binary. 29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ErrorOr<Binary *> BinaryOrErr = createBinary(File); 291cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = BinaryOrErr.getError()) { 29276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher reportError(File, EC); 29376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher return; 2945c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer } 29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Binary> Binary(BinaryOrErr.get()); 2965c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 29776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (Archive *Arc = dyn_cast<Archive>(Binary.get())) 29876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher dumpArchive(Arc); 29976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher else if (ObjectFile *Obj = dyn_cast<ObjectFile>(Binary.get())) 30076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher dumpObject(Obj); 30176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher else 30276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher reportError(File, readobj_error::unrecognized_file_format); 30376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher} 30487b47ccc5afcdffb1fa7f04b27fca926ec7fb344Rafael Espindola 30587b47ccc5afcdffb1fa7f04b27fca926ec7fb344Rafael Espindola 30676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherint main(int argc, const char *argv[]) { 30776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher sys::PrintStackTraceOnErrorSignal(); 30876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher PrettyStackTraceProgram X(argc, argv); 30976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher llvm_shutdown_obj Y; 310fc73847d8fa79d310b26b7a80275dc48755ec2e3Rafael Espindola 31176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // Initialize targets. 31276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher llvm::InitializeAllTargetInfos(); 313fc73847d8fa79d310b26b7a80275dc48755ec2e3Rafael Espindola 31476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // Register the target printer for --version. 31576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); 31676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 31776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher cl::ParseCommandLineOptions(argc, argv, "LLVM Object Reader\n"); 318d326d05fb9c794e93fc7fc0601028f196600f7e2Michael J. Spencer 31976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher // Default to stdin if no filename is specified. 32076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher if (opts::InputFilenames.size() == 0) 32176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher opts::InputFilenames.push_back("-"); 32276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher 32376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(), 32476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher dumpInput); 32587b47ccc5afcdffb1fa7f04b27fca926ec7fb344Rafael Espindola 326081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer return ReturnValue; 3275c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 328