From bc884fd9f7bdb64d250be639edc8dc85a20a1975 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 2 Nov 2013 21:16:09 +0000 Subject: move getSymbolNMTypeChar to the one program that needs it: nm. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193933 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/COFF.h | 1 - include/llvm/Object/ELFObjectFile.h | 77 +----------- include/llvm/Object/MachO.h | 1 - include/llvm/Object/ObjectFile.h | 9 -- lib/Object/COFFObjectFile.cpp | 68 ----------- lib/Object/MachOObjectFile.cpp | 37 ------ tools/llvm-nm/llvm-nm.cpp | 225 +++++++++++++++++++++++++++++++++++- 7 files changed, 226 insertions(+), 192 deletions(-) diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 67cc7c6..ec8998c 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -246,7 +246,6 @@ protected: virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const; virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; - virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; virtual error_code getSymbolSection(DataRefImpl Symb, diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 31783d4..962a3e2 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -61,7 +61,6 @@ protected: virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const; virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; - virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; @@ -104,8 +103,6 @@ protected: getRelocationValueString(DataRefImpl Rel, SmallVectorImpl &Result) const; -protected: // ELF specific protected members. - const Elf_Sym *getSymbol(DataRefImpl Symb) const; uint64_t getROffset(DataRefImpl Rel) const; StringRef getRelocationTypeName(uint32_t Type) const; @@ -170,6 +167,8 @@ protected: // ELF specific protected members. public: ELFObjectFile(MemoryBuffer *Object, error_code &ec); + const Elf_Sym *getSymbol(DataRefImpl Symb) const; + virtual symbol_iterator begin_symbols() const; virtual symbol_iterator end_symbols() const; @@ -339,78 +338,6 @@ error_code ELFObjectFile::getSymbolSize(DataRefImpl Symb, } template -error_code ELFObjectFile::getSymbolNMTypeChar(DataRefImpl Symb, - char &Result) const { - const Elf_Sym *ESym = getSymbol(Symb); - const Elf_Shdr *ESec = EF.getSection(ESym); - - char ret = '?'; - - if (ESec) { - switch (ESec->sh_type) { - case ELF::SHT_PROGBITS: - case ELF::SHT_DYNAMIC: - switch (ESec->sh_flags) { - case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR): - ret = 't'; - break; - case (ELF::SHF_ALLOC | ELF::SHF_WRITE): - ret = 'd'; - break; - case ELF::SHF_ALLOC: - case (ELF::SHF_ALLOC | ELF::SHF_MERGE): - case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS): - ret = 'r'; - break; - } - break; - case ELF::SHT_NOBITS: - ret = 'b'; - } - } - - switch (EF.getSymbolTableIndex(ESym)) { - case ELF::SHN_UNDEF: - if (ret == '?') - ret = 'U'; - break; - case ELF::SHN_ABS: - ret = 'a'; - break; - case ELF::SHN_COMMON: - ret = 'c'; - break; - } - - switch (ESym->getBinding()) { - case ELF::STB_GLOBAL: - ret = ::toupper(ret); - break; - case ELF::STB_WEAK: - if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF) - ret = 'w'; - else if (ESym->getType() == ELF::STT_OBJECT) - ret = 'V'; - else - ret = 'W'; - } - - if (ret == '?' && ESym->getType() == ELF::STT_SECTION) { - ErrorOr Name = EF.getSymbolName(toELFSymIter(Symb)); - if (!Name) - return Name; - Result = StringSwitch(*Name) - .StartsWith(".debug", 'N') - .StartsWith(".note", 'n') - .Default('?'); - return object_error::success; - } - - Result = ret; - return object_error::success; -} - -template error_code ELFObjectFile::getSymbolType(DataRefImpl Symb, SymbolRef::Type &Result) const { const Elf_Sym *ESym = getSymbol(Symb); diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index e91c260..100613a 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -67,7 +67,6 @@ public: virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; - virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; virtual error_code getSymbolSection(DataRefImpl Symb, section_iterator &Res) const; diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 0ba4952..9aea639 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -221,10 +221,6 @@ public: error_code getSize(uint64_t &Result) const; error_code getType(SymbolRef::Type &Result) const; - /// Returns the ascii char that should be displayed in a symbol table dump via - /// nm for this symbol. - error_code getNMTypeChar(char &Result) const; - /// Get symbol flags (bitwise OR of SymbolRef::Flags) error_code getFlags(uint32_t &Result) const; @@ -296,7 +292,6 @@ protected: virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0; virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const = 0; - virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0; virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const = 0; virtual error_code getSymbolSection(DataRefImpl Symb, @@ -431,10 +426,6 @@ inline error_code SymbolRef::getSize(uint64_t &Result) const { return OwningObject->getSymbolSize(SymbolPimpl, Result); } -inline error_code SymbolRef::getNMTypeChar(char &Result) const { - return OwningObject->getSymbolNMTypeChar(SymbolPimpl, Result); -} - inline error_code SymbolRef::getFlags(uint32_t &Result) const { return OwningObject->getSymbolFlags(SymbolPimpl, Result); } diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index d48f44c..f33caee 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -207,74 +207,6 @@ error_code COFFObjectFile::getSymbolSize(DataRefImpl Symb, return object_error::success; } -error_code COFFObjectFile::getSymbolNMTypeChar(DataRefImpl Symb, - char &Result) const { - const coff_symbol *symb = toSymb(Symb); - StringRef name; - if (error_code ec = getSymbolName(Symb, name)) - return ec; - char ret = StringSwitch(name) - .StartsWith(".debug", 'N') - .StartsWith(".sxdata", 'N') - .Default('?'); - - if (ret != '?') { - Result = ret; - return object_error::success; - } - - uint32_t Characteristics = 0; - if (symb->SectionNumber > 0) { - const coff_section *Section = NULL; - if (error_code ec = getSection(symb->SectionNumber, Section)) - return ec; - Characteristics = Section->Characteristics; - } - - switch (symb->SectionNumber) { - case COFF::IMAGE_SYM_UNDEFINED: - // Check storage classes. - if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) { - Result = 'w'; - return object_error::success; // Don't do ::toupper. - } else if (symb->Value != 0) // Check for common symbols. - ret = 'c'; - else - ret = 'u'; - break; - case COFF::IMAGE_SYM_ABSOLUTE: - ret = 'a'; - break; - case COFF::IMAGE_SYM_DEBUG: - ret = 'n'; - break; - default: - // Check section type. - if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) - ret = 't'; - else if ( Characteristics & COFF::IMAGE_SCN_MEM_READ - && ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. - ret = 'r'; - else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) - ret = 'd'; - else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) - ret = 'b'; - else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) - ret = 'i'; - - // Check for section symbol. - else if ( symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC - && symb->Value == 0) - ret = 's'; - } - - if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) - ret = ::toupper(static_cast(ret)); - - Result = ret; - return object_error::success; -} - error_code COFFObjectFile::getSymbolSection(DataRefImpl Symb, section_iterator &Result) const { const coff_symbol *symb = toSymb(Symb); diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index f48bb8a..d2cb8bd 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -591,43 +591,6 @@ error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, return object_error::success; } -error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl Symb, - char &Res) const { - nlist_base Entry = getSymbolTableEntryBase(this, Symb); - uint8_t NType = Entry.n_type; - - char Char; - switch (NType & MachO::N_TYPE) { - case MachO::N_UNDF: - Char = 'u'; - break; - case MachO::N_ABS: - Char = 's'; - break; - case MachO::N_SECT: { - section_iterator Sec = end_sections(); - getSymbolSection(Symb, Sec); - DataRefImpl Ref = Sec->getRawDataRefImpl(); - StringRef SectionName; - getSectionName(Ref, SectionName); - StringRef SegmentName = getSectionFinalSegmentName(Ref); - if (SegmentName == "__TEXT" && SectionName == "__text") - Char = 't'; - else - Char = 's'; - } - break; - default: - Char = '?'; - break; - } - - if (NType & (MachO::N_EXT | MachO::N_PEXT)) - Char = toupper(static_cast(Char)); - Res = Char; - return object_error::success; -} - error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, uint32_t &Result) const { nlist_base Entry = getSymbolTableEntryBase(this, DRI); diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index 01dd1c3..8449c29 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -20,6 +20,9 @@ #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/IR/Module.h" #include "llvm/Object/Archive.h" +#include "llvm/Object/COFF.h" +#include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/MachO.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/CommandLine.h" @@ -303,6 +306,226 @@ static void DumpSymbolNamesFromModule(Module *M) { SortAndPrintSymbolList(); } +template +error_code getSymbolNMTypeChar(ELFObjectFile &Obj, symbol_iterator I, + char &Result) { + typedef typename ELFObjectFile::Elf_Sym Elf_Sym; + typedef typename ELFObjectFile::Elf_Shdr Elf_Shdr; + + DataRefImpl Symb = I->getRawDataRefImpl(); + const Elf_Sym *ESym = Obj.getSymbol(Symb); + const ELFFile &EF = *Obj.getELFFile(); + const Elf_Shdr *ESec = EF.getSection(ESym); + + char ret = '?'; + + if (ESec) { + switch (ESec->sh_type) { + case ELF::SHT_PROGBITS: + case ELF::SHT_DYNAMIC: + switch (ESec->sh_flags) { + case(ELF::SHF_ALLOC | ELF::SHF_EXECINSTR) : + ret = 't'; + break; + case(ELF::SHF_ALLOC | ELF::SHF_WRITE) : + ret = 'd'; + break; + case ELF::SHF_ALLOC: + case(ELF::SHF_ALLOC | ELF::SHF_MERGE) : + case(ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS) : + ret = 'r'; + break; + } + break; + case ELF::SHT_NOBITS: + ret = 'b'; + } + } + + switch (EF.getSymbolTableIndex(ESym)) { + case ELF::SHN_UNDEF: + if (ret == '?') + ret = 'U'; + break; + case ELF::SHN_ABS: + ret = 'a'; + break; + case ELF::SHN_COMMON: + ret = 'c'; + break; + } + + switch (ESym->getBinding()) { + case ELF::STB_GLOBAL: + ret = ::toupper(ret); + break; + case ELF::STB_WEAK: + if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF) + ret = 'w'; + else if (ESym->getType() == ELF::STT_OBJECT) + ret = 'V'; + else + ret = 'W'; + } + + if (ret == '?' && ESym->getType() == ELF::STT_SECTION) { + StringRef Name; + error_code EC = I->getName(Name); + if (EC) + return EC; + Result = StringSwitch(Name) + .StartsWith(".debug", 'N') + .StartsWith(".note", 'n') + .Default('?'); + return object_error::success; + } + + Result = ret; + return object_error::success; +} + +static error_code getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I, + char &Result) { + const coff_symbol *symb = Obj.getCOFFSymbol(I); + StringRef name; + if (error_code ec = I->getName(name)) + return ec; + char ret = StringSwitch(name) + .StartsWith(".debug", 'N') + .StartsWith(".sxdata", 'N') + .Default('?'); + + if (ret != '?') { + Result = ret; + return object_error::success; + } + + uint32_t Characteristics = 0; + if (symb->SectionNumber > 0) { + section_iterator SecI = Obj.end_sections(); + if (error_code ec = I->getSection(SecI)) + return ec; + const coff_section *Section = Obj.getCOFFSection(SecI); + Characteristics = Section->Characteristics; + } + + switch (symb->SectionNumber) { + case COFF::IMAGE_SYM_UNDEFINED: + // Check storage classes. + if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) { + Result = 'w'; + return object_error::success; // Don't do ::toupper. + } else if (symb->Value != 0) // Check for common symbols. + ret = 'c'; + else + ret = 'u'; + break; + case COFF::IMAGE_SYM_ABSOLUTE: + ret = 'a'; + break; + case COFF::IMAGE_SYM_DEBUG: + ret = 'n'; + break; + default: + // Check section type. + if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) + ret = 't'; + else if (Characteristics & COFF::IMAGE_SCN_MEM_READ && + ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. + ret = 'r'; + else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) + ret = 'd'; + else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) + ret = 'b'; + else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) + ret = 'i'; + + // Check for section symbol. + else if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC && + symb->Value == 0) + ret = 's'; + } + + if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) + ret = ::toupper(static_cast(ret)); + + Result = ret; + return object_error::success; +} + +static uint8_t getNType(MachOObjectFile &Obj, DataRefImpl Symb) { + if (Obj.is64Bit()) { + MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb); + return STE.n_type; + } + MachO::nlist STE = Obj.getSymbolTableEntry(Symb); + return STE.n_type; +} + +static error_code getSymbolNMTypeChar(MachOObjectFile &Obj, symbol_iterator I, + char &Res) { + DataRefImpl Symb = I->getRawDataRefImpl(); + uint8_t NType = getNType(Obj, Symb); + + char Char; + switch (NType & MachO::N_TYPE) { + case MachO::N_UNDF: + Char = 'u'; + break; + case MachO::N_ABS: + Char = 's'; + break; + case MachO::N_SECT: { + section_iterator Sec = Obj.end_sections(); + Obj.getSymbolSection(Symb, Sec); + DataRefImpl Ref = Sec->getRawDataRefImpl(); + StringRef SectionName; + Obj.getSectionName(Ref, SectionName); + StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref); + if (SegmentName == "__TEXT" && SectionName == "__text") + Char = 't'; + else + Char = 's'; + } break; + default: + Char = '?'; + break; + } + + if (NType & (MachO::N_EXT | MachO::N_PEXT)) + Char = toupper(static_cast(Char)); + Res = Char; + return object_error::success; +} + +static char getNMTypeChar(ObjectFile *Obj, symbol_iterator I) { + char Res = '?'; + if (COFFObjectFile *COFF = dyn_cast(Obj)) { + error(getSymbolNMTypeChar(*COFF, I, Res)); + return Res; + } + if (MachOObjectFile *MachO = dyn_cast(Obj)) { + error(getSymbolNMTypeChar(*MachO, I, Res)); + return Res; + } + + if (ELF32LEObjectFile *ELF = dyn_cast(Obj)) { + error(getSymbolNMTypeChar(*ELF, I, Res)); + return Res; + } + if (ELF64LEObjectFile *ELF = dyn_cast(Obj)) { + error(getSymbolNMTypeChar(*ELF, I, Res)); + return Res; + } + if (ELF32BEObjectFile *ELF = dyn_cast(Obj)) { + error(getSymbolNMTypeChar(*ELF, I, Res)); + return Res; + } + ELF64BEObjectFile *ELF = cast(Obj); + error(getSymbolNMTypeChar(*ELF, I, Res)); + return Res; +} + static void DumpSymbolNamesFromObject(ObjectFile *obj) { error_code ec; symbol_iterator ibegin = obj->begin_symbols(); @@ -325,7 +548,7 @@ static void DumpSymbolNamesFromObject(ObjectFile *obj) { } if (PrintAddress) if (error(i->getAddress(s.Address))) break; - if (error(i->getNMTypeChar(s.TypeChar))) break; + s.TypeChar = getNMTypeChar(obj, i); if (error(i->getName(s.Name))) break; SymbolList.push_back(s); } -- cgit v1.1