From 2d70e263c2b508bf4641273dd89a23149f6f6164 Mon Sep 17 00:00:00 2001 From: David Meyer Date: Fri, 9 Mar 2012 20:59:52 +0000 Subject: Support reading GNU symbol versions in ELFObjectFile * Add enums and structures for GNU version information. * Implement extraction of that information on a per-symbol basis (ELFObjectFile::getSymbolVersion). * Implement a generic interface, GetELFSymbolVersion(), for getting the symbol version from the ObjectFile (hides the templating). * Have llvm-readobj print out the version, when available. * Add a test for the new feature: readobj-elf-versioning.test git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152436 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/llvm-readobj.cpp | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'tools/llvm-readobj') diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 3f8789dc17..0c58fb3fb4 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -17,6 +17,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Object/ObjectFile.h" +#include "llvm/Object/ELF.h" #include "llvm/Analysis/Verifier.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/Format.h" @@ -78,22 +79,35 @@ std::string GetFlagStr(uint32_t Flags) { return result; } -void DumpSymbol(const SymbolRef &sym) { +void DumpSymbol(const SymbolRef &Sym, const ObjectFile *obj, bool IsDynamic) { 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); + Sym.getName(Name); + Sym.getAddress(Address); + Sym.getSize(Size); + Sym.getFileOffset(FileOffset); + Sym.getType(Type); + Sym.getFlags(Flags); + std::string FullName = Name; + + // If this is a dynamic symbol from an ELF object, append + // the symbol's version to the name. + if (IsDynamic && obj->isELF()) { + StringRef Version; + bool IsDefault; + GetELFSymbolVersion(obj, Sym, Version, IsDefault); + if (!Version.empty()) { + FullName += (IsDefault ? "@@" : "@"); + FullName += Version; + } + } // format() can't handle StringRefs - outs() << format(" %-32s", Name.str().c_str()) + outs() << format(" %-32s", FullName.c_str()) << format(" %-4s", GetTypeStr(Type)) << format(" %16"PRIx64, Address) << format(" %16"PRIx64, Size) @@ -111,7 +125,7 @@ void DumpSymbols(const ObjectFile *obj) { symbol_iterator it = obj->begin_symbols(); symbol_iterator ie = obj->end_symbols(); while (it != ie) { - DumpSymbol(*it); + DumpSymbol(*it, obj, false); it.increment(ec); if (ec) report_fatal_error("Symbol iteration failed"); @@ -128,7 +142,7 @@ void DumpDynamicSymbols(const ObjectFile *obj) { symbol_iterator it = obj->begin_dynamic_symbols(); symbol_iterator ie = obj->end_dynamic_symbols(); while (it != ie) { - DumpSymbol(*it); + DumpSymbol(*it, obj, true); it.increment(ec); if (ec) report_fatal_error("Symbol iteration failed"); -- cgit v1.2.3