[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/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
24 using namespace llvm;
25 using namespace llvm::object;
26
27 static cl::opt<std::string>
28 InputFilename(cl::Positional, cl::desc("<input object>"), cl::init(""));
29
30 void 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
40 const 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
52 std::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
76 void 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
102 void 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.
119 void 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
135 void DumpLibrary(const LibraryRef &lib) {
136   StringRef path;
137   lib.getPath(path);
138   outs() << "  " << path << "\n";
139 }
140
141 // Iterate through needed libraries
142 void 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
158 int 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