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