diff options
author | David Meyer <pdox@google.com> | 2012-03-01 01:36:50 +0000 |
---|---|---|
committer | David Meyer <pdox@google.com> | 2012-03-01 01:36:50 +0000 |
commit | 5c2b4ea73c8f48bb5f96c86fe437385b8fb3dcda (patch) | |
tree | e62d2d345c810a0aaf0a561192a31079c5acb5b6 /tools/llvm-readobj/llvm-readobj.cpp | |
parent | 741981adf3a2bc0c6652c9c4ec846250950f3e68 (diff) |
[Object]
* Add begin_dynamic_table() / end_dynamic_table() private interface to ELFObjectFile.
* Add begin_libraries_needed() / end_libraries_needed() interface to ObjectFile, for grabbing the list of needed libraries for a shared object or dynamic executable.
* Implement this new interface completely for ELF, leave stubs for COFF and MachO.
* Add 'llvm-readobj' tool for dumping ObjectFile information.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151785 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-readobj/llvm-readobj.cpp')
-rw-r--r-- | tools/llvm-readobj/llvm-readobj.cpp | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp new file mode 100644 index 0000000000..7b8683f134 --- /dev/null +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -0,0 +1,188 @@ +/*===- pso-stub.c - Stub executable to run llvm bitcode files -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "llvm/Object/ObjectFile.h" +#include "llvm/Analysis/Verifier.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/FormattedStream.h" + +using namespace llvm; +using namespace llvm::object; + +static cl::opt<std::string> +InputFilename(cl::Positional, cl::desc("<input object>"), cl::init("")); + +void DumpSymbolHeader() { + outs() << format(" %-32s", (const char*)"Name") + << format(" %-4s", (const char*)"Type") + << format(" %-16s", (const char*)"Address") + << format(" %-16s", (const char*)"Size") + << format(" %-16s", (const char*)"FileOffset") + << format(" %-26s", (const char*)"Flags") + << "\n"; +} + +const char *GetTypeStr(SymbolRef::Type Type) { + switch (Type) { + case SymbolRef::ST_Unknown: return "?"; + case SymbolRef::ST_Data: return "DATA"; + case SymbolRef::ST_Debug: return "DBG"; + case SymbolRef::ST_File: return "FILE"; + case SymbolRef::ST_Function: return "FUNC"; + case SymbolRef::ST_Other: return "-"; + } + return "INV"; +} + +std::string GetFlagStr(uint32_t Flags) { + std::string result; + if (Flags & SymbolRef::SF_Undefined) + result += "undef,"; + if (Flags & SymbolRef::SF_Global) + result += "global,"; + if (Flags & SymbolRef::SF_Weak) + result += "weak,"; + if (Flags & SymbolRef::SF_Absolute) + result += "absolute,"; + if (Flags & SymbolRef::SF_ThreadLocal) + result += "threadlocal,"; + if (Flags & SymbolRef::SF_Common) + result += "common,"; + if (Flags & SymbolRef::SF_FormatSpecific) + result += "formatspecific,"; + + // Remove trailing comma + if (result.size() > 0) { + result.erase(result.size() - 1); + } + return result; +} + +void DumpSymbol(const SymbolRef &sym) { + StringRef Name; + SymbolRef::Type Type; + uint32_t Flags; + uint64_t Address; + uint64_t Size; + uint64_t FileOffset; + sym.getName(Name); + sym.getAddress(Address); + sym.getSize(Size); + sym.getFileOffset(FileOffset); + sym.getType(Type); + sym.getFlags(Flags); + + // format() can't handle StringRefs + outs() << format(" %-32s", Name.str().c_str()) + << format(" %-4s", GetTypeStr(Type)) + << format(" %16"PRIx64, Address) + << format(" %16"PRIx64, Size) + << format(" %16"PRIx64, FileOffset) + << " " << GetFlagStr(Flags) + << "\n"; +} + + +// Iterate through the normal symbols in the ObjectFile +void DumpSymbols(const ObjectFile *obj) { + error_code ec; + uint32_t count = 0; + outs() << "Symbols:\n"; + symbol_iterator it = obj->begin_symbols(); + symbol_iterator ie = obj->end_symbols(); + while (it != ie) { + DumpSymbol(*it); + it.increment(ec); + if (ec) + report_fatal_error("Symbol iteration failed"); + ++count; + } + outs() << " Total: " << count << "\n\n"; +} + +// Iterate through the dynamic symbols in the ObjectFile. +void DumpDynamicSymbols(const ObjectFile *obj) { + error_code ec; + uint32_t count = 0; + outs() << "Dynamic Symbols:\n"; + symbol_iterator it = obj->begin_dynamic_symbols(); + symbol_iterator ie = obj->end_dynamic_symbols(); + while (it != ie) { + DumpSymbol(*it); + it.increment(ec); + if (ec) + report_fatal_error("Symbol iteration failed"); + ++count; + } + outs() << " Total: " << count << "\n\n"; +} + +void DumpLibrary(const LibraryRef &lib) { + StringRef path; + lib.getPath(path); + outs() << " " << path << "\n"; +} + +// Iterate through needed libraries +void DumpLibrariesNeeded(const ObjectFile *obj) { + error_code ec; + uint32_t count = 0; + library_iterator it = obj->begin_libraries_needed(); + library_iterator ie = obj->end_libraries_needed(); + outs() << "Libraries needed:\n"; + while (it != ie) { + DumpLibrary(*it); + it.increment(ec); + if (ec) + report_fatal_error("Needed libraries iteration failed"); + ++count; + } + outs() << " Total: " << count << "\n\n"; +} + +int main(int argc, char** argv) { + error_code ec; + sys::PrintStackTraceOnErrorSignal(); + PrettyStackTraceProgram X(argc, argv); + + cl::ParseCommandLineOptions(argc, argv, + "LLVM Object Reader\n"); + + if (InputFilename.empty()) { + errs() << "Please specify an input filename\n"; + return 1; + } + + // Open the object file + OwningPtr<MemoryBuffer> File; + if (MemoryBuffer::getFile(InputFilename, File)) { + errs() << InputFilename << ": Open failed\n"; + return 1; + } + + ObjectFile *obj = ObjectFile::createObjectFile(File.take()); + if (!obj) { + errs() << InputFilename << ": Object type not recognized\n"; + } + + DumpSymbols(obj); + DumpDynamicSymbols(obj); + DumpLibrariesNeeded(obj); + return 0; +} + |