1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

move getSymbolNMTypeChar to the one program that needs it: nm.

llvm-svn: 193933
This commit is contained in:
Rafael Espindola 2013-11-02 21:16:09 +00:00
parent 844544bbd9
commit 3c7f6cf61c
7 changed files with 226 additions and 192 deletions

View File

@ -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,

View File

@ -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<char> &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;
@ -338,78 +337,6 @@ error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb,
return object_error::success;
}
template <class ELFT>
error_code ELFObjectFile<ELFT>::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<StringRef> Name = EF.getSymbolName(toELFSymIter(Symb));
if (!Name)
return Name;
Result = StringSwitch<char>(*Name)
.StartsWith(".debug", 'N')
.StartsWith(".note", 'n')
.Default('?');
return object_error::success;
}
Result = ret;
return object_error::success;
}
template <class ELFT>
error_code ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb,
SymbolRef::Type &Result) const {

View File

@ -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;

View File

@ -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);
}

View File

@ -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<char>(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<unsigned char>(ret));
Result = ret;
return object_error::success;
}
error_code COFFObjectFile::getSymbolSection(DataRefImpl Symb,
section_iterator &Result) const {
const coff_symbol *symb = toSymb(Symb);

View File

@ -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<unsigned char>(Char));
Res = Char;
return object_error::success;
}
error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI,
uint32_t &Result) const {
nlist_base Entry = getSymbolTableEntryBase(this, DRI);

View File

@ -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 <class ELFT>
error_code getSymbolNMTypeChar(ELFObjectFile<ELFT> &Obj, symbol_iterator I,
char &Result) {
typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr;
DataRefImpl Symb = I->getRawDataRefImpl();
const Elf_Sym *ESym = Obj.getSymbol(Symb);
const ELFFile<ELFT> &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<char>(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<char>(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<unsigned char>(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<unsigned char>(Char));
Res = Char;
return object_error::success;
}
static char getNMTypeChar(ObjectFile *Obj, symbol_iterator I) {
char Res = '?';
if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(Obj)) {
error(getSymbolNMTypeChar(*COFF, I, Res));
return Res;
}
if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj)) {
error(getSymbolNMTypeChar(*MachO, I, Res));
return Res;
}
if (ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(Obj)) {
error(getSymbolNMTypeChar(*ELF, I, Res));
return Res;
}
if (ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(Obj)) {
error(getSymbolNMTypeChar(*ELF, I, Res));
return Res;
}
if (ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(Obj)) {
error(getSymbolNMTypeChar(*ELF, I, Res));
return Res;
}
ELF64BEObjectFile *ELF = cast<ELF64BEObjectFile>(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);
}