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