llvm-readobj.cpp revision 97f7787bfb56ad31fe20ec0bb9c3c9f3253d14fb
1/*===- pso-stub.c - Stub executable to run llvm bitcode files -------------===// 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//===----------------------------------------------------------------------===*/ 11 12#include <stdio.h> 13#include <stdlib.h> 14#include <string.h> 15#include "llvm/Object/ObjectFile.h" 16#include "llvm/Analysis/Verifier.h" 17#include "llvm/ADT/Triple.h" 18#include "llvm/Support/Format.h" 19#include "llvm/Support/CommandLine.h" 20#include "llvm/Support/PrettyStackTrace.h" 21#include "llvm/Support/Debug.h" 22#include "llvm/Support/Signals.h" 23#include "llvm/Support/FormattedStream.h" 24 25using namespace llvm; 26using namespace llvm::object; 27 28static cl::opt<std::string> 29InputFilename(cl::Positional, cl::desc("<input object>"), cl::init("")); 30 31void DumpSymbolHeader() { 32 outs() << format(" %-32s", (const char*)"Name") 33 << format(" %-4s", (const char*)"Type") 34 << format(" %-16s", (const char*)"Address") 35 << format(" %-16s", (const char*)"Size") 36 << format(" %-16s", (const char*)"FileOffset") 37 << format(" %-26s", (const char*)"Flags") 38 << "\n"; 39} 40 41const char *GetTypeStr(SymbolRef::Type Type) { 42 switch (Type) { 43 case SymbolRef::ST_Unknown: return "?"; 44 case SymbolRef::ST_Data: return "DATA"; 45 case SymbolRef::ST_Debug: return "DBG"; 46 case SymbolRef::ST_File: return "FILE"; 47 case SymbolRef::ST_Function: return "FUNC"; 48 case SymbolRef::ST_Other: return "-"; 49 } 50 return "INV"; 51} 52 53std::string GetFlagStr(uint32_t Flags) { 54 std::string result; 55 if (Flags & SymbolRef::SF_Undefined) 56 result += "undef,"; 57 if (Flags & SymbolRef::SF_Global) 58 result += "global,"; 59 if (Flags & SymbolRef::SF_Weak) 60 result += "weak,"; 61 if (Flags & SymbolRef::SF_Absolute) 62 result += "absolute,"; 63 if (Flags & SymbolRef::SF_ThreadLocal) 64 result += "threadlocal,"; 65 if (Flags & SymbolRef::SF_Common) 66 result += "common,"; 67 if (Flags & SymbolRef::SF_FormatSpecific) 68 result += "formatspecific,"; 69 70 // Remove trailing comma 71 if (result.size() > 0) { 72 result.erase(result.size() - 1); 73 } 74 return result; 75} 76 77void DumpSymbol(const SymbolRef &sym) { 78 StringRef Name; 79 SymbolRef::Type Type; 80 uint32_t Flags; 81 uint64_t Address; 82 uint64_t Size; 83 uint64_t FileOffset; 84 sym.getName(Name); 85 sym.getAddress(Address); 86 sym.getSize(Size); 87 sym.getFileOffset(FileOffset); 88 sym.getType(Type); 89 sym.getFlags(Flags); 90 91 // format() can't handle StringRefs 92 outs() << format(" %-32s", Name.str().c_str()) 93 << format(" %-4s", GetTypeStr(Type)) 94 << format(" %16"PRIx64, Address) 95 << format(" %16"PRIx64, Size) 96 << format(" %16"PRIx64, FileOffset) 97 << " " << GetFlagStr(Flags) 98 << "\n"; 99} 100 101 102// Iterate through the normal symbols in the ObjectFile 103void DumpSymbols(const ObjectFile *obj) { 104 error_code ec; 105 uint32_t count = 0; 106 outs() << "Symbols:\n"; 107 symbol_iterator it = obj->begin_symbols(); 108 symbol_iterator ie = obj->end_symbols(); 109 while (it != ie) { 110 DumpSymbol(*it); 111 it.increment(ec); 112 if (ec) 113 report_fatal_error("Symbol iteration failed"); 114 ++count; 115 } 116 outs() << " Total: " << count << "\n\n"; 117} 118 119// Iterate through the dynamic symbols in the ObjectFile. 120void DumpDynamicSymbols(const ObjectFile *obj) { 121 error_code ec; 122 uint32_t count = 0; 123 outs() << "Dynamic Symbols:\n"; 124 symbol_iterator it = obj->begin_dynamic_symbols(); 125 symbol_iterator ie = obj->end_dynamic_symbols(); 126 while (it != ie) { 127 DumpSymbol(*it); 128 it.increment(ec); 129 if (ec) 130 report_fatal_error("Symbol iteration failed"); 131 ++count; 132 } 133 outs() << " Total: " << count << "\n\n"; 134} 135 136void DumpLibrary(const LibraryRef &lib) { 137 StringRef path; 138 lib.getPath(path); 139 outs() << " " << path << "\n"; 140} 141 142// Iterate through needed libraries 143void DumpLibrariesNeeded(const ObjectFile *obj) { 144 error_code ec; 145 uint32_t count = 0; 146 library_iterator it = obj->begin_libraries_needed(); 147 library_iterator ie = obj->end_libraries_needed(); 148 outs() << "Libraries needed:\n"; 149 while (it != ie) { 150 DumpLibrary(*it); 151 it.increment(ec); 152 if (ec) 153 report_fatal_error("Needed libraries iteration failed"); 154 ++count; 155 } 156 outs() << " Total: " << count << "\n\n"; 157} 158 159void DumpHeaders(const ObjectFile *obj) { 160 outs() << "File Format : " << obj->getFileFormatName() << "\n"; 161 outs() << "Arch : " 162 << Triple::getArchTypeName((llvm::Triple::ArchType)obj->getArch()) 163 << "\n"; 164 outs() << "Address Size: " << (8*obj->getBytesInAddress()) << " bits\n"; 165 outs() << "Load Name : " << obj->getLoadName() << "\n"; 166 outs() << "\n"; 167} 168 169int main(int argc, char** argv) { 170 error_code ec; 171 sys::PrintStackTraceOnErrorSignal(); 172 PrettyStackTraceProgram X(argc, argv); 173 174 cl::ParseCommandLineOptions(argc, argv, 175 "LLVM Object Reader\n"); 176 177 if (InputFilename.empty()) { 178 errs() << "Please specify an input filename\n"; 179 return 1; 180 } 181 182 // Open the object file 183 OwningPtr<MemoryBuffer> File; 184 if (MemoryBuffer::getFile(InputFilename, File)) { 185 errs() << InputFilename << ": Open failed\n"; 186 return 1; 187 } 188 189 ObjectFile *obj = ObjectFile::createObjectFile(File.take()); 190 if (!obj) { 191 errs() << InputFilename << ": Object type not recognized\n"; 192 } 193 194 DumpHeaders(obj); 195 DumpSymbols(obj); 196 DumpDynamicSymbols(obj); 197 DumpLibrariesNeeded(obj); 198 return 0; 199} 200 201