From e3a1818871ad83ecc3200380d10ce105a00ce3f9 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 5 Feb 2014 05:19:19 +0000 Subject: [PATCH] Use the information provided by getFlags to unify some code in llvm-nm. It is not clear how much we should try to expose in getFlags. For example, should there be a SF_Object and a SF_Text? But for information that is already being exposed, we may as well use it in llvm-nm. llvm-svn: 200820 --- lib/Object/COFFObjectFile.cpp | 10 +- tools/llvm-nm/llvm-nm.cpp | 167 +++++++++++++++------------------- 2 files changed, 82 insertions(+), 95 deletions(-) diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 3475ac5c601..a604acda749 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -161,9 +161,13 @@ uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const { // TODO: Correctly set SF_FormatSpecific, SF_Common - if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && - Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) - Result |= SymbolRef::SF_Undefined; + if (Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) { + if (Symb->Value == 0) + Result |= SymbolRef::SF_Undefined; + else + Result |= SymbolRef::SF_Common; + } + // TODO: This are certainly too restrictive. if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index 8d1fa729bd7..3a72862776f 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -316,63 +316,28 @@ static char getSymbolNMTypeChar(ELFObjectFile &Obj, symbol_iterator I) { 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; + return 't'; case(ELF::SHF_TLS | ELF::SHF_ALLOC | ELF::SHF_WRITE) : case(ELF::SHF_ALLOC | ELF::SHF_WRITE) : - Ret = 'd'; - break; + return 'd'; case ELF::SHF_ALLOC: case(ELF::SHF_ALLOC | ELF::SHF_MERGE) : case(ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS) : - Ret = 'r'; - break; + return 'r'; } break; case ELF::SHT_NOBITS: - Ret = 'b'; + return '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) { - if (ESym->getType() == ELF::STT_OBJECT) - Ret = 'v'; - else - Ret = 'w'; - } - else if (ESym->getType() == ELF::STT_OBJECT) - Ret = 'V'; - else - Ret = 'W'; - } - - if (Ret == '?' && ESym->getType() == ELF::STT_SECTION) { + if (ESym->getType() == ELF::STT_SECTION) { StringRef Name; if (error(I->getName(Name))) return '?'; @@ -382,7 +347,7 @@ static char getSymbolNMTypeChar(ELFObjectFile &Obj, symbol_iterator I) { .Default('?'); } - return Ret; + return '?'; } static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { @@ -408,45 +373,29 @@ static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { } switch (Symb->SectionNumber) { - case COFF::IMAGE_SYM_UNDEFINED: - // Check storage classes. - if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) { - return 'w'; // 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; + return 'n'; default: // Check section type. if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) - Ret = 't'; + return 't'; else if (Characteristics & COFF::IMAGE_SCN_MEM_READ && ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. - Ret = 'r'; + return 'r'; else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) - Ret = 'd'; + return 'd'; else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) - Ret = 'b'; + return 'b'; else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) - Ret = 'i'; + return 'i'; // Check for section symbol. else if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC && Symb->Value == 0) - Ret = 's'; + return 's'; } - if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) - Ret = ::toupper(static_cast(Ret)); - - return Ret; + return '?'; } static uint8_t getNType(MachOObjectFile &Obj, DataRefImpl Symb) { @@ -462,14 +411,9 @@ static char getSymbolNMTypeChar(MachOObjectFile &Obj, symbol_iterator I) { 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; + return 's'; case MachO::N_SECT: { section_iterator Sec = Obj.end_sections(); Obj.getSymbolSection(Symb, Sec); @@ -478,33 +422,72 @@ static char getSymbolNMTypeChar(MachOObjectFile &Obj, symbol_iterator I) { Obj.getSectionName(Ref, SectionName); StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref); if (SegmentName == "__TEXT" && SectionName == "__text") - Char = 't'; + return 't'; else - Char = 's'; - } break; - default: - Char = '?'; - break; + return 's'; + } } - if (NType & (MachO::N_EXT | MachO::N_PEXT)) - Char = toupper(static_cast(Char)); - return Char; + return '?'; +} + +template +static bool isObject(ELFObjectFile &Obj, symbol_iterator I) { + typedef typename ELFObjectFile::Elf_Sym Elf_Sym; + + DataRefImpl Symb = I->getRawDataRefImpl(); + const Elf_Sym *ESym = Obj.getSymbol(Symb); + + return ESym->getType() == ELF::STT_OBJECT; +} + +static bool isObject(ObjectFile *Obj, symbol_iterator I) { + if (ELF32LEObjectFile *ELF = dyn_cast(Obj)) + return isObject(*ELF, I); + if (ELF64LEObjectFile *ELF = dyn_cast(Obj)) + return isObject(*ELF, I); + if (ELF32BEObjectFile *ELF = dyn_cast(Obj)) + return isObject(*ELF, I); + if (ELF64BEObjectFile *ELF = dyn_cast(Obj)) + return isObject(*ELF, I); + return false; } static char getNMTypeChar(ObjectFile *Obj, symbol_iterator I) { - if (COFFObjectFile *COFF = dyn_cast(Obj)) - return getSymbolNMTypeChar(*COFF, I); - if (MachOObjectFile *MachO = dyn_cast(Obj)) - return getSymbolNMTypeChar(*MachO, I); - if (ELF32LEObjectFile *ELF = dyn_cast(Obj)) - return getSymbolNMTypeChar(*ELF, I); - if (ELF64LEObjectFile *ELF = dyn_cast(Obj)) - return getSymbolNMTypeChar(*ELF, I); - if (ELF32BEObjectFile *ELF = dyn_cast(Obj)) - return getSymbolNMTypeChar(*ELF, I); - ELF64BEObjectFile *ELF = cast(Obj); - return getSymbolNMTypeChar(*ELF, I); + uint32_t Symflags = I->getFlags(); + if ((Symflags & object::SymbolRef::SF_Weak) && !isa(Obj)) { + char Ret = isObject(Obj, I) ? 'v' : 'w'; + if (!(Symflags & object::SymbolRef::SF_Undefined)) + Ret = toupper(Ret); + return Ret; + } + + if (Symflags & object::SymbolRef::SF_Undefined) + return 'U'; + + if (Symflags & object::SymbolRef::SF_Common) + return 'C'; + + char Ret = '?'; + if (Symflags & object::SymbolRef::SF_Absolute) + Ret = 'a'; + else if (COFFObjectFile *COFF = dyn_cast(Obj)) + Ret = getSymbolNMTypeChar(*COFF, I); + else if (MachOObjectFile *MachO = dyn_cast(Obj)) + Ret = getSymbolNMTypeChar(*MachO, I); + else if (ELF32LEObjectFile *ELF = dyn_cast(Obj)) + Ret = getSymbolNMTypeChar(*ELF, I); + else if (ELF64LEObjectFile *ELF = dyn_cast(Obj)) + Ret = getSymbolNMTypeChar(*ELF, I); + else if (ELF32BEObjectFile *ELF = dyn_cast(Obj)) + Ret = getSymbolNMTypeChar(*ELF, I); + else + Ret = getSymbolNMTypeChar(*cast(Obj), I); + + if (Symflags & object::SymbolRef::SF_Global) + Ret = toupper(Ret); + + return Ret; } static void getDynamicSymbolIterators(ObjectFile *Obj, symbol_iterator &Begin,