blob: 7b8683f134b8c7ca80cdfd220fc8a0baadf61a6c [file] [log] [blame]
David Meyer5c2b4ea2012-03-01 01:36:50 +00001/*===- 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