llvm-readobj.cpp revision 663cebc4ad5ac5ad77ac051cbb925a126bba2c23
1//===- llvm-readobj.cpp - Dump contents of an Object File -----------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This program is a utility that works like traditional Unix "readelf", 11// except that it can handle any type of object file recognized by lib/Object. 12// 13// It makes use of the generic ObjectFile interface. 14// 15// Caution: This utility is new, experimental, unsupported, and incomplete. 16// 17//===----------------------------------------------------------------------===// 18 19#include "llvm/ADT/Triple.h" 20#include "llvm/Analysis/Verifier.h" 21#include "llvm/Object/ELF.h" 22#include "llvm/Object/ObjectFile.h" 23#include "llvm/Support/CommandLine.h" 24#include "llvm/Support/Debug.h" 25#include "llvm/Support/Format.h" 26#include "llvm/Support/FormattedStream.h" 27#include "llvm/Support/PrettyStackTrace.h" 28#include "llvm/Support/Signals.h" 29 30using namespace llvm; 31using namespace llvm::object; 32 33static cl::opt<std::string> 34InputFilename(cl::Positional, cl::desc("<input object>"), cl::init("")); 35 36static const char *getTypeStr(SymbolRef::Type Type) { 37 switch (Type) { 38 case SymbolRef::ST_Unknown: return "?"; 39 case SymbolRef::ST_Data: return "DATA"; 40 case SymbolRef::ST_Debug: return "DBG"; 41 case SymbolRef::ST_File: return "FILE"; 42 case SymbolRef::ST_Function: return "FUNC"; 43 case SymbolRef::ST_Other: return "-"; 44 } 45 return "INV"; 46} 47 48static std::string getSymbolFlagStr(uint32_t Flags) { 49 std::string result; 50 if (Flags & SymbolRef::SF_Undefined) 51 result += "undef,"; 52 if (Flags & SymbolRef::SF_Global) 53 result += "global,"; 54 if (Flags & SymbolRef::SF_Weak) 55 result += "weak,"; 56 if (Flags & SymbolRef::SF_Absolute) 57 result += "absolute,"; 58 if (Flags & SymbolRef::SF_ThreadLocal) 59 result += "threadlocal,"; 60 if (Flags & SymbolRef::SF_Common) 61 result += "common,"; 62 if (Flags & SymbolRef::SF_FormatSpecific) 63 result += "formatspecific,"; 64 65 // Remove trailing comma 66 if (result.size() > 0) { 67 result.erase(result.size() - 1); 68 } 69 return result; 70} 71 72static void 73dumpSymbol(const SymbolRef &Sym, const ObjectFile *obj, bool IsDynamic) { 74 StringRef Name; 75 SymbolRef::Type Type; 76 uint32_t Flags; 77 uint64_t Address; 78 uint64_t Size; 79 uint64_t FileOffset; 80 Sym.getName(Name); 81 Sym.getAddress(Address); 82 Sym.getSize(Size); 83 Sym.getFileOffset(FileOffset); 84 Sym.getType(Type); 85 Sym.getFlags(Flags); 86 std::string FullName = Name; 87 88 // If this is a dynamic symbol from an ELF object, append 89 // the symbol's version to the name. 90 if (IsDynamic && obj->isELF()) { 91 StringRef Version; 92 bool IsDefault; 93 GetELFSymbolVersion(obj, Sym, Version, IsDefault); 94 if (!Version.empty()) { 95 FullName += (IsDefault ? "@@" : "@"); 96 FullName += Version; 97 } 98 } 99 100 // format() can't handle StringRefs 101 outs() << format(" %-32s", FullName.c_str()) 102 << format(" %-4s", getTypeStr(Type)) 103 << format(" %16" PRIx64, Address) 104 << format(" %16" PRIx64, Size) 105 << format(" %16" PRIx64, FileOffset) 106 << " " << getSymbolFlagStr(Flags) 107 << "\n"; 108} 109 110// Iterate through the normal symbols in the ObjectFile 111static void dumpSymbols(const ObjectFile *obj) { 112 error_code ec; 113 uint32_t count = 0; 114 outs() << "Symbols:\n"; 115 symbol_iterator it = obj->begin_symbols(); 116 symbol_iterator ie = obj->end_symbols(); 117 while (it != ie) { 118 dumpSymbol(*it, obj, false); 119 it.increment(ec); 120 if (ec) 121 report_fatal_error("Symbol iteration failed"); 122 ++count; 123 } 124 outs() << " Total: " << count << "\n\n"; 125} 126 127// Iterate through the dynamic symbols in the ObjectFile. 128static void dumpDynamicSymbols(const ObjectFile *obj) { 129 error_code ec; 130 uint32_t count = 0; 131 outs() << "Dynamic Symbols:\n"; 132 symbol_iterator it = obj->begin_dynamic_symbols(); 133 symbol_iterator ie = obj->end_dynamic_symbols(); 134 while (it != ie) { 135 dumpSymbol(*it, obj, true); 136 it.increment(ec); 137 if (ec) 138 report_fatal_error("Symbol iteration failed"); 139 ++count; 140 } 141 outs() << " Total: " << count << "\n\n"; 142} 143 144static void dumpLibrary(const LibraryRef &lib) { 145 StringRef path; 146 lib.getPath(path); 147 outs() << " " << path << "\n"; 148} 149 150// Iterate through needed libraries 151static void dumpLibrariesNeeded(const ObjectFile *obj) { 152 error_code ec; 153 uint32_t count = 0; 154 library_iterator it = obj->begin_libraries_needed(); 155 library_iterator ie = obj->end_libraries_needed(); 156 outs() << "Libraries needed:\n"; 157 while (it != ie) { 158 dumpLibrary(*it); 159 it.increment(ec); 160 if (ec) 161 report_fatal_error("Needed libraries iteration failed"); 162 ++count; 163 } 164 outs() << " Total: " << count << "\n\n"; 165} 166 167static void dumpHeaders(const ObjectFile *obj) { 168 outs() << "File Format : " << obj->getFileFormatName() << "\n"; 169 outs() << "Arch : " 170 << Triple::getArchTypeName((llvm::Triple::ArchType)obj->getArch()) 171 << "\n"; 172 outs() << "Address Size: " << (8*obj->getBytesInAddress()) << " bits\n"; 173 outs() << "Load Name : " << obj->getLoadName() << "\n"; 174 outs() << "\n"; 175} 176 177int main(int argc, char** argv) { 178 error_code ec; 179 sys::PrintStackTraceOnErrorSignal(); 180 PrettyStackTraceProgram X(argc, argv); 181 182 cl::ParseCommandLineOptions(argc, argv, 183 "LLVM Object Reader\n"); 184 185 if (InputFilename.empty()) { 186 errs() << "Please specify an input filename\n"; 187 return 1; 188 } 189 190 // Open the object file 191 OwningPtr<MemoryBuffer> File; 192 if (MemoryBuffer::getFile(InputFilename, File)) { 193 errs() << InputFilename << ": Open failed\n"; 194 return 1; 195 } 196 197 ObjectFile *obj = ObjectFile::createObjectFile(File.take()); 198 if (!obj) { 199 errs() << InputFilename << ": Object type not recognized\n"; 200 } 201 202 dumpHeaders(obj); 203 dumpSymbols(obj); 204 dumpDynamicSymbols(obj); 205 dumpLibrariesNeeded(obj); 206 return 0; 207} 208 209