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