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