[Object]
[oota-llvm.git] / tools / llvm-readobj / llvm-readobj.cpp
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
25 using namespace llvm;
26 using namespace llvm::object;
27
28 static cl::opt<std::string>
29 InputFilename(cl::Positional, cl::desc("<input object>"), cl::init(""));
30
31 void 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
41 const 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
53 std::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
77 void 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
103 void 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.
120 void 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
136 void DumpLibrary(const LibraryRef &lib) {
137   StringRef path;
138   lib.getPath(path);
139   outs() << "  " << path << "\n";
140 }
141
142 // Iterate through needed libraries
143 void 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
159 void 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
169 int 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