From 91f86b7e1c07e73667537e6b849f9977caeeed3d Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 21 Feb 2014 20:10:59 +0000 Subject: Add a SymbolicFile interface between Binary and ObjectFile. This interface allows IRObjectFile to be implemented without having dummy methods for all section and segment related methods. Both llvm-ar and llvm-nm are changed to use it. Unfortunately the mangler is still not plugged in since it requires some refactoring to make a Module hold a DataLayout. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201881 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-nm/CMakeLists.txt | 2 - tools/llvm-nm/llvm-nm.cpp | 184 +++++++++++++++++-------------------------- 2 files changed, 74 insertions(+), 112 deletions(-) (limited to 'tools/llvm-nm') diff --git a/tools/llvm-nm/CMakeLists.txt b/tools/llvm-nm/CMakeLists.txt index ce758ced44..6128bf9adf 100644 --- a/tools/llvm-nm/CMakeLists.txt +++ b/tools/llvm-nm/CMakeLists.txt @@ -1,6 +1,4 @@ set(LLVM_LINK_COMPONENTS - BitReader - Core Object Support ) diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index fd18454a8f..d93177e245 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -16,11 +16,13 @@ // //===----------------------------------------------------------------------===// +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalAlias.h" +#include "llvm/IR/GlobalVariable.h" #include "llvm/IR/LLVMContext.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/IR/Module.h" #include "llvm/Object/Archive.h" #include "llvm/Object/COFF.h" +#include "llvm/Object/IRObjectFile.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/MachO.h" #include "llvm/Object/MachOUniversal.h" @@ -53,8 +55,7 @@ cl::opt OutputFormat( cl::alias OutputFormat2("f", cl::desc("Alias for --format"), cl::aliasopt(OutputFormat)); -cl::list InputFilenames(cl::Positional, - cl::desc(""), +cl::list InputFilenames(cl::Positional, cl::desc(""), cl::ZeroOrMore); cl::opt UndefinedOnly("undefined-only", @@ -250,67 +251,15 @@ static void sortAndPrintSymbolList() { SymbolList.clear(); } -static char typeCharForSymbol(GlobalValue &GV) { - if (GV.isDeclaration()) - return 'U'; - if (GV.hasLinkOnceLinkage()) - return 'C'; - if (GV.hasCommonLinkage()) - return 'C'; - if (GV.hasWeakLinkage()) - return 'W'; - if (isa(GV) && GV.hasInternalLinkage()) - return 't'; - if (isa(GV)) - return 'T'; - if (isa(GV) && GV.hasInternalLinkage()) - return 'd'; - if (isa(GV)) - return 'D'; - if (const GlobalAlias *GA = dyn_cast(&GV)) { - const GlobalValue *AliasedGV = GA->getAliasedGlobal(); - if (isa(AliasedGV)) - return 'T'; - if (isa(AliasedGV)) - return 'D'; - } - return '?'; -} - -static void dumpSymbolNameForGlobalValue(GlobalValue &GV) { - // Private linkage and available_externally linkage don't exist in symtab. - if (GV.hasPrivateLinkage() || GV.hasLinkerPrivateLinkage() || - GV.hasLinkerPrivateWeakLinkage() || GV.hasAvailableExternallyLinkage()) - return; - char TypeChar = typeCharForSymbol(GV); - if (GV.hasLocalLinkage() && ExternalOnly) - return; - - NMSymbol S; - S.Address = UnknownAddressOrSize; - S.Size = UnknownAddressOrSize; - S.TypeChar = TypeChar; - S.Name = GV.getName(); - SymbolList.push_back(S); -} - -static void dumpSymbolNamesFromModule(Module *M) { - CurrentFilename = M->getModuleIdentifier(); - std::for_each(M->begin(), M->end(), dumpSymbolNameForGlobalValue); - std::for_each(M->global_begin(), M->global_end(), - dumpSymbolNameForGlobalValue); - if (!WithoutAliases) - std::for_each(M->alias_begin(), M->alias_end(), - dumpSymbolNameForGlobalValue); - - sortAndPrintSymbolList(); -} - template -static char getSymbolNMTypeChar(ELFObjectFile &Obj, symbol_iterator I) { +static char getSymbolNMTypeChar(ELFObjectFile &Obj, + basic_symbol_iterator I) { typedef typename ELFObjectFile::Elf_Sym Elf_Sym; typedef typename ELFObjectFile::Elf_Shdr Elf_Shdr; + // OK, this is ELF + symbol_iterator SymI(I); + DataRefImpl Symb = I->getRawDataRefImpl(); const Elf_Sym *ESym = Obj.getSymbol(Symb); const ELFFile &EF = *Obj.getELFFile(); @@ -339,7 +288,7 @@ static char getSymbolNMTypeChar(ELFObjectFile &Obj, symbol_iterator I) { if (ESym->getType() == ELF::STT_SECTION) { StringRef Name; - if (error(I->getName(Name))) + if (error(SymI->getName(Name))) return '?'; return StringSwitch(Name) .StartsWith(".debug", 'N') @@ -352,9 +301,13 @@ static char getSymbolNMTypeChar(ELFObjectFile &Obj, symbol_iterator I) { static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { const coff_symbol *Symb = Obj.getCOFFSymbol(I); + // OK, this is COFF. + symbol_iterator SymI(I); + StringRef Name; - if (error(I->getName(Name))) + if (error(SymI->getName(Name))) return '?'; + char Ret = StringSwitch(Name) .StartsWith(".debug", 'N') .StartsWith(".sxdata", 'N') @@ -366,7 +319,7 @@ static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { uint32_t Characteristics = 0; if (Symb->SectionNumber > 0) { section_iterator SecI = Obj.section_end(); - if (error(I->getSection(SecI))) + if (error(SymI->getSection(SecI))) return '?'; const coff_section *Section = Obj.getCOFFSection(SecI); Characteristics = Section->Characteristics; @@ -407,7 +360,7 @@ static uint8_t getNType(MachOObjectFile &Obj, DataRefImpl Symb) { return STE.n_type; } -static char getSymbolNMTypeChar(MachOObjectFile &Obj, symbol_iterator I) { +static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) { DataRefImpl Symb = I->getRawDataRefImpl(); uint8_t NType = getNType(Obj, Symb); @@ -431,6 +384,23 @@ static char getSymbolNMTypeChar(MachOObjectFile &Obj, symbol_iterator I) { return '?'; } +static char getSymbolNMTypeChar(const GlobalValue &GV) { + if (isa(GV)) + return 't'; + // FIXME: should we print 'b'? At the IR level we cannot be sure if this + // will be in bss or not, but we could approximate. + if (isa(GV)) + return 'd'; + const GlobalAlias *GA = cast(&GV); + const GlobalValue *AliasedGV = GA->getAliasedGlobal(); + return getSymbolNMTypeChar(*AliasedGV); +} + +static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) { + const GlobalValue &GV = Obj.getSymbolGV(I->getRawDataRefImpl()); + return getSymbolNMTypeChar(GV); +} + template static bool isObject(ELFObjectFile &Obj, symbol_iterator I) { typedef typename ELFObjectFile::Elf_Sym Elf_Sym; @@ -441,7 +411,7 @@ static bool isObject(ELFObjectFile &Obj, symbol_iterator I) { return ESym->getType() == ELF::STT_OBJECT; } -static bool isObject(ObjectFile *Obj, symbol_iterator I) { +static bool isObject(SymbolicFile *Obj, basic_symbol_iterator I) { if (ELF32LEObjectFile *ELF = dyn_cast(Obj)) return isObject(*ELF, I); if (ELF64LEObjectFile *ELF = dyn_cast(Obj)) @@ -453,7 +423,7 @@ static bool isObject(ObjectFile *Obj, symbol_iterator I) { return false; } -static char getNMTypeChar(ObjectFile *Obj, symbol_iterator I) { +static char getNMTypeChar(SymbolicFile *Obj, basic_symbol_iterator I) { uint32_t Symflags = I->getFlags(); if ((Symflags & object::SymbolRef::SF_Weak) && !isa(Obj)) { char Ret = isObject(Obj, I) ? 'v' : 'w'; @@ -471,6 +441,8 @@ static char getNMTypeChar(ObjectFile *Obj, symbol_iterator I) { char Ret = '?'; if (Symflags & object::SymbolRef::SF_Absolute) Ret = 'a'; + else if (IRObjectFile *IR = dyn_cast(Obj)) + Ret = getSymbolNMTypeChar(*IR, I); else if (COFFObjectFile *COFF = dyn_cast(Obj)) Ret = getSymbolNMTypeChar(*COFF, I); else if (MachOObjectFile *MachO = dyn_cast(Obj)) @@ -490,8 +462,9 @@ static char getNMTypeChar(ObjectFile *Obj, symbol_iterator I) { return Ret; } -static void getDynamicSymbolIterators(ObjectFile *Obj, symbol_iterator &Begin, - symbol_iterator &End) { +static void getDynamicSymbolIterators(SymbolicFile *Obj, + basic_symbol_iterator &Begin, + basic_symbol_iterator &End) { if (ELF32LEObjectFile *ELF = dyn_cast(Obj)) { Begin = ELF->dynamic_symbol_begin(); End = ELF->dynamic_symbol_end(); @@ -513,9 +486,9 @@ static void getDynamicSymbolIterators(ObjectFile *Obj, symbol_iterator &Begin, return; } -static void dumpSymbolNamesFromObject(ObjectFile *Obj) { - symbol_iterator IBegin = Obj->symbol_begin(); - symbol_iterator IEnd = Obj->symbol_end(); +static void dumpSymbolNamesFromObject(SymbolicFile *Obj) { + basic_symbol_iterator IBegin = Obj->symbol_begin(); + basic_symbol_iterator IEnd = Obj->symbol_end(); if (DynamicSyms) { if (!Obj->isELF()) { error("File format has no dynamic symbol table", Obj->getFileName()); @@ -523,26 +496,44 @@ static void dumpSymbolNamesFromObject(ObjectFile *Obj) { } getDynamicSymbolIterators(Obj, IBegin, IEnd); } - for (symbol_iterator I = IBegin; I != IEnd; ++I) { + std::string NameBuffer; + raw_string_ostream OS(NameBuffer); + for (basic_symbol_iterator I = IBegin; I != IEnd; ++I) { uint32_t SymFlags = I->getFlags(); if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific)) continue; + if (WithoutAliases) { + if (IRObjectFile *IR = dyn_cast(Obj)) { + const GlobalValue &GV = IR->getSymbolGV(I->getRawDataRefImpl()); + if(isa(GV)) + continue; + } + } NMSymbol S; S.Size = UnknownAddressOrSize; S.Address = UnknownAddressOrSize; - if (PrintSize || SizeSort) { - if (error(I->getSize(S.Size))) + if ((PrintSize || SizeSort) && isa(Obj)) { + symbol_iterator SymI = I; + if (error(SymI->getSize(S.Size))) break; } - if (PrintAddress) - if (error(I->getAddress(S.Address))) + if (PrintAddress && isa(Obj)) + if (error(symbol_iterator(I)->getAddress(S.Address))) break; S.TypeChar = getNMTypeChar(Obj, I); - if (error(I->getName(S.Name))) + if (error(I->printName(OS))) break; + OS << '\0'; SymbolList.push_back(S); } + OS.flush(); + const char *P = NameBuffer.c_str(); + for (unsigned I = 0; I < SymbolList.size(); ++I) { + SymbolList[I].Name = P; + P += strlen(P) + 1; + } + CurrentFilename = Obj->getFileName(); sortAndPrintSymbolList(); } @@ -552,22 +543,8 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { if (error(MemoryBuffer::getFileOrSTDIN(Filename, Buffer), Filename)) return; - sys::fs::file_magic Magic = sys::fs::identify_magic(Buffer->getBuffer()); - LLVMContext &Context = getGlobalContext(); - if (Magic == sys::fs::file_magic::bitcode) { - ErrorOr ModuleOrErr = parseBitcodeFile(Buffer.get(), Context); - if (error(ModuleOrErr.getError(), Filename)) { - return; - } else { - Module *Result = ModuleOrErr.get(); - dumpSymbolNamesFromModule(Result); - delete Result; - } - return; - } - - ErrorOr BinaryOrErr = createBinary(Buffer.take(), Magic); + ErrorOr BinaryOrErr = createBinary(Buffer.take(), &Context); if (error(BinaryOrErr.getError(), Filename)) return; OwningPtr Bin(BinaryOrErr.get()); @@ -597,29 +574,16 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { for (Archive::child_iterator I = A->child_begin(), E = A->child_end(); I != E; ++I) { OwningPtr Child; - if (I->getAsBinary(Child)) { - // Try opening it as a bitcode file. - OwningPtr Buff; - if (error(I->getMemoryBuffer(Buff))) - return; - - ErrorOr ModuleOrErr = parseBitcodeFile(Buff.get(), Context); - if (ModuleOrErr) { - Module *Result = ModuleOrErr.get(); - dumpSymbolNamesFromModule(Result); - delete Result; - } + if (I->getAsBinary(Child, &Context)) continue; - } - if (ObjectFile *O = dyn_cast(Child.get())) { + if (SymbolicFile *O = dyn_cast(Child.get())) { outs() << O->getFileName() << ":\n"; dumpSymbolNamesFromObject(O); } } return; } - if (MachOUniversalBinary *UB = - dyn_cast(Bin.get())) { + if (MachOUniversalBinary *UB = dyn_cast(Bin.get())) { for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), E = UB->end_objects(); I != E; ++I) { @@ -631,7 +595,7 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { } return; } - if (ObjectFile *O = dyn_cast(Bin.get())) { + if (SymbolicFile *O = dyn_cast(Bin.get())) { dumpSymbolNamesFromObject(O); return; } -- cgit v1.2.3