blob: 215039f5be762f87c615132545ca730f5cad95d2 [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"
David Meyer97f77872012-03-01 22:19:54 +000017#include "llvm/ADT/Triple.h"
David Meyer5c2b4ea2012-03-01 01:36:50 +000018#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
David Meyer97f77872012-03-01 22:19:54 +0000159void 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
David Meyer5c2b4ea2012-03-01 01:36:50 +0000169int 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
David Meyer97f77872012-03-01 22:19:54 +0000194 DumpHeaders(obj);
David Meyer5c2b4ea2012-03-01 01:36:50 +0000195 DumpSymbols(obj);
196 DumpDynamicSymbols(obj);
197 DumpLibrariesNeeded(obj);
198 return 0;
199}
200