1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//===- llvm-readobj.cpp - Dump contents of an Object File -----------------===// 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// The LLVM Compiler Infrastructure 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// License. See LICENSE.TXT for details. 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//===----------------------------------------------------------------------===// 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This is a tool similar to readelf, except it works on multiple object file 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// formats. The main purpose of this tool is to provide detailed output suitable 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// for FileCheck. 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Flags should be similar to readelf where supported, but the output format 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// does not need to be identical. The point is to not make users learn yet 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// another set of flags. 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Output should be specialized for each format where appropriate. 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//===----------------------------------------------------------------------===// 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm-readobj.h" 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "Error.h" 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ObjDumper.h" 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "StreamWriter.h" 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Object/Archive.h" 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Object/ObjectFile.h" 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/Casting.h" 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/CommandLine.h" 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/DataTypes.h" 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/Debug.h" 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/FileSystem.h" 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/ManagedStatic.h" 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/PrettyStackTrace.h" 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/Signals.h" 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/TargetRegistry.h" 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/TargetSelect.h" 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <string> 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <system_error> 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using namespace llvm; 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using namespace llvm::object; 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace opts { 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::list<std::string> InputFilenames(cl::Positional, 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("<input object files>"), 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::ZeroOrMore); 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -file-headers, -h 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> FileHeaders("file-headers", 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Display file headers ")); 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::alias FileHeadersShort("h", 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Alias for --file-headers"), 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::aliasopt(FileHeaders)); 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -sections, -s 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> Sections("sections", 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Display all sections.")); 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::alias SectionsShort("s", 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Alias for --sections"), 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::aliasopt(Sections)); 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -section-relocations, -sr 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> SectionRelocations("section-relocations", 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Display relocations for each section shown.")); 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::alias SectionRelocationsShort("sr", 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Alias for --section-relocations"), 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::aliasopt(SectionRelocations)); 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -section-symbols, -st 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> SectionSymbols("section-symbols", 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Display symbols for each section shown.")); 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::alias SectionSymbolsShort("st", 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Alias for --section-symbols"), 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::aliasopt(SectionSymbols)); 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -section-data, -sd 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> SectionData("section-data", 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Display section data for each section shown.")); 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::alias SectionDataShort("sd", 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Alias for --section-data"), 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::aliasopt(SectionData)); 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -relocations, -r 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> Relocations("relocations", 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Display the relocation entries in the file")); 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::alias RelocationsShort("r", 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Alias for --relocations"), 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::aliasopt(Relocations)); 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -symbols, -t 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> Symbols("symbols", 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Display the symbol table")); 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::alias SymbolsShort("t", 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Alias for --symbols"), 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::aliasopt(Symbols)); 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -dyn-symbols, -dt 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> DynamicSymbols("dyn-symbols", 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Display the dynamic symbol table")); 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::alias DynamicSymbolsShort("dt", 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Alias for --dyn-symbols"), 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::aliasopt(DynamicSymbols)); 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -unwind, -u 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> UnwindInfo("unwind", 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Display unwind information")); 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::alias UnwindInfoShort("u", 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Alias for --unwind"), 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::aliasopt(UnwindInfo)); 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -dynamic-table 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> DynamicTable("dynamic-table", 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Display the ELF .dynamic section table")); 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -needed-libs 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> NeededLibraries("needed-libs", 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Display the needed libraries")); 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -program-headers 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> ProgramHeaders("program-headers", 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Display ELF program headers")); 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -expand-relocs 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> ExpandRelocs("expand-relocs", 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Expand each shown relocation to multiple lines")); 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -codeview-linetables 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> CodeViewLineTables("codeview-linetables", 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Display CodeView line table information")); 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -arm-attributes, -a 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> ARMAttributes("arm-attributes", 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Display the ARM attributes section")); 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::alias ARMAttributesShort("-a", cl::desc("Alias for --arm-attributes"), 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::aliasopt(ARMAttributes)); 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // -mips-plt-got 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::opt<bool> 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MipsPLTGOT("mips-plt-got", 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::desc("Display the MIPS GOT and PLT GOT sections")); 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace opts 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static int ReturnValue = EXIT_SUCCESS; 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace llvm { 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool error(std::error_code EC) { 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!EC) 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ReturnValue = EXIT_FAILURE; 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) outs() << "\nError reading file: " << EC.message() << ".\n"; 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) outs().flush(); 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool relocAddressLess(RelocationRef a, RelocationRef b) { 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint64_t a_addr, b_addr; 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error(a.getOffset(a_addr))) return false; 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error(b.getOffset(b_addr))) return false; 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return a_addr < b_addr; 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace llvm 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static void reportError(StringRef Input, std::error_code EC) { 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (Input == "-") 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Input = "<stdin>"; 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) errs() << Input << ": " << EC.message() << "\n"; 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) errs().flush(); 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ReturnValue = EXIT_FAILURE; 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static void reportError(StringRef Input, StringRef Message) { 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (Input == "-") 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Input = "<stdin>"; 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) errs() << Input << ": " << Message << "\n"; 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ReturnValue = EXIT_FAILURE; 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static bool isMipsArch(unsigned Arch) { 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (Arch) { 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case llvm::Triple::mips: 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case llvm::Triple::mipsel: 189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case llvm::Triple::mips64: 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case llvm::Triple::mips64el: 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) default: 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/// @brief Creates an format-specific object file dumper. 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static std::error_code createDumper(const ObjectFile *Obj, StreamWriter &Writer, 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::unique_ptr<ObjDumper> &Result) { 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!Obj) 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return readobj_error::unsupported_file_format; 202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (Obj->isCOFF()) 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return createCOFFDumper(Obj, Writer, Result); 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (Obj->isELF()) 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return createELFDumper(Obj, Writer, Result); 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (Obj->isMachO()) 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return createMachODumper(Obj, Writer, Result); 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return readobj_error::unsupported_obj_file_format; 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/// @brief Dumps the specified object file. 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static void dumpObject(const ObjectFile *Obj) { 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) StreamWriter Writer(outs()); 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::unique_ptr<ObjDumper> Dumper; 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (std::error_code EC = createDumper(Obj, Writer, Dumper)) { 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reportError(Obj->getFileName(), EC); 220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) outs() << '\n'; 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) outs() << "File: " << Obj->getFileName() << "\n"; 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) outs() << "Format: " << Obj->getFileFormatName() << "\n"; 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) outs() << "Arch: " 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << Triple::getArchTypeName((llvm::Triple::ArchType)Obj->getArch()) 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << "\n"; 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) outs() << "AddressSize: " << (8*Obj->getBytesInAddress()) << "bit\n"; 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (Obj->isELF()) 231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) outs() << "LoadName: " << Obj->getLoadName() << "\n"; 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (opts::FileHeaders) 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Dumper->printFileHeaders(); 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (opts::Sections) 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Dumper->printSections(); 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (opts::Relocations) 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Dumper->printRelocations(); 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (opts::Symbols) 240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Dumper->printSymbols(); 241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (opts::DynamicSymbols) 242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Dumper->printDynamicSymbols(); 243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (opts::UnwindInfo) 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Dumper->printUnwindInfo(); 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (opts::DynamicTable) 246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Dumper->printDynamicTable(); 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (opts::NeededLibraries) 248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Dumper->printNeededLibraries(); 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (opts::ProgramHeaders) 250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Dumper->printProgramHeaders(); 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (Obj->getArch() == llvm::Triple::arm && Obj->isELF()) 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (opts::ARMAttributes) 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Dumper->printAttributes(); 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (isMipsArch(Obj->getArch()) && Obj->isELF()) 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (opts::MipsPLTGOT) 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Dumper->printMipsPLTGOT(); 257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/// @brief Dumps each object file in \a Arc; 261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static void dumpArchive(const Archive *Arc) { 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (Archive::child_iterator ArcI = Arc->child_begin(), 263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ArcE = Arc->child_end(); 264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ArcI != ArcE; ++ArcI) { 265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ErrorOr<std::unique_ptr<Binary>> ChildOrErr = ArcI->getAsBinary(); 266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (std::error_code EC = ChildOrErr.getError()) { 267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Ignore non-object files. 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (EC != object_error::invalid_file_type) 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reportError(Arc->getFileName(), EC.message()); 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) continue; 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (ObjectFile *Obj = dyn_cast<ObjectFile>(&*ChildOrErr.get())) 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) dumpObject(Obj); 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reportError(Arc->getFileName(), readobj_error::unrecognized_file_format); 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/// @brief Opens \a File and dumps it. 282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static void dumpInput(StringRef File) { 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // If file isn't stdin, check that it exists. 284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (File != "-" && !sys::fs::exists(File)) { 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reportError(File, readobj_error::file_not_found); 286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Attempt to open the binary. 290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ErrorOr<Binary *> BinaryOrErr = createBinary(File); 291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (std::error_code EC = BinaryOrErr.getError()) { 292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reportError(File, EC); 293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::unique_ptr<Binary> Binary(BinaryOrErr.get()); 296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (Archive *Arc = dyn_cast<Archive>(Binary.get())) 298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) dumpArchive(Arc); 299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else if (ObjectFile *Obj = dyn_cast<ObjectFile>(Binary.get())) 300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) dumpObject(Obj); 301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else 302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reportError(File, readobj_error::unrecognized_file_format); 303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int main(int argc, const char *argv[]) { 307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sys::PrintStackTraceOnErrorSignal(); 308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PrettyStackTraceProgram X(argc, argv); 309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) llvm_shutdown_obj Y; 310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Initialize targets. 312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) llvm::InitializeAllTargetInfos(); 313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Register the target printer for --version. 315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); 316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cl::ParseCommandLineOptions(argc, argv, "LLVM Object Reader\n"); 318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Default to stdin if no filename is specified. 320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (opts::InputFilenames.size() == 0) 321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) opts::InputFilenames.push_back("-"); 322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(), 324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) dumpInput); 325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ReturnValue; 327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)