From bcb935c90080872fee4badccc9add6789486af3c Mon Sep 17 00:00:00 2001 From: Jordan Rupprecht Date: Fri, 24 May 2019 04:02:05 +0000 Subject: [PATCH] [llvm-nm] Fix Bug 41353 - unique symbols printed as D instead of u Summary: https://bugs.llvm.org/show_bug.cgi?id=41353 I'm new to LLVM and C++ so please do not hesitate to iterate with me on this fix. Patch by Mike Pozulp! Reviewers: rupprecht, zbrid, grimar, jhenderson Reviewed By: rupprecht, jhenderson Subscribers: jhenderson, chrisjackson, MaskRay, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D61117 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361595 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/ELFObjectFile.h | 11 +++++++ test/tools/llvm-nm/X86/unique.test | 50 +++++++++++++++++++++++++++++ tools/llvm-nm/llvm-nm.cpp | 12 +++++-- 3 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 test/tools/llvm-nm/X86/unique.test diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index ed54ad02ccf..d5e9d3638dc 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -56,6 +56,7 @@ protected: virtual uint16_t getEMachine() const = 0; virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0; + virtual uint8_t getSymbolBinding(DataRefImpl Symb) const = 0; virtual uint8_t getSymbolOther(DataRefImpl Symb) const = 0; virtual uint8_t getSymbolELFType(DataRefImpl Symb) const = 0; @@ -145,6 +146,10 @@ public: return getObject()->getSymbolSize(getRawDataRefImpl()); } + uint8_t getBinding() const { + return getObject()->getSymbolBinding(getRawDataRefImpl()); + } + uint8_t getOther() const { return getObject()->getSymbolOther(getRawDataRefImpl()); } @@ -252,6 +257,7 @@ protected: uint32_t getSymbolAlignment(DataRefImpl Symb) const override; uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; + uint8_t getSymbolBinding(DataRefImpl Symb) const override; uint8_t getSymbolOther(DataRefImpl Symb) const override; uint8_t getSymbolELFType(DataRefImpl Symb) const override; Expected getSymbolType(DataRefImpl Symb) const override; @@ -553,6 +559,11 @@ uint64_t ELFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const { return getSymbol(Symb)->st_size; } +template +uint8_t ELFObjectFile::getSymbolBinding(DataRefImpl Symb) const { + return getSymbol(Symb)->getBinding(); +} + template uint8_t ELFObjectFile::getSymbolOther(DataRefImpl Symb) const { return getSymbol(Symb)->st_other; diff --git a/test/tools/llvm-nm/X86/unique.test b/test/tools/llvm-nm/X86/unique.test new file mode 100644 index 00000000000..a8879d74cf9 --- /dev/null +++ b/test/tools/llvm-nm/X86/unique.test @@ -0,0 +1,50 @@ +## Check that we print 'u' for unique symbols +## and 'U' for a unique symbol without a section. +# RUN: yaml2obj %s | llvm-nm - | FileCheck %s + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .nobits + Type: SHT_NOBITS + - Name: .progbits + Type: SHT_PROGBITS + - Name: .progbits_alloc + Type: SHT_PROGBITS + Flags: [SHF_ALLOC] + - Name: .progbits_alloc_write + Type: SHT_PROGBITS + Flags: [SHF_ALLOC, SHF_WRITE] + - Name: .progbits_execinstr + Type: SHT_PROGBITS + Flags: [SHF_EXECINSTR] +Symbols: + - Name: nosection + Binding: STB_GNU_UNIQUE + - Name: nobits + Section: .nobits + Binding: STB_GNU_UNIQUE + - Name: progbits + Section: .progbits + Binding: STB_GNU_UNIQUE + - Name: progbits_alloc + Section: .progbits_alloc + Binding: STB_GNU_UNIQUE + - Name: progbits_alloc_write + Section: .progbits_alloc_write + Binding: STB_GNU_UNIQUE + - Name: progbits_execinstr + Section: .progbits_execinstr + Binding: STB_GNU_UNIQUE +... + +# CHECK: 0000000000000000 u nobits +# CHECK: U nosection +# CHECK: 0000000000000000 u progbits +# CHECK: 0000000000000000 u progbits_alloc +# CHECK: 0000000000000000 u progbits_alloc_write +# CHECK: 0000000000000000 u progbits_execinstr diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index f21978d50cc..871ca638d9d 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -894,6 +894,9 @@ static char getSymbolNMTypeChar(ELFObjectFileBase &Obj, return '?'; } + if (SymI->getBinding() == ELF::STB_GNU_UNIQUE) + return 'u'; + elf_section_iterator SecI = *SecIOrErr; if (SecI != Obj.section_end()) { uint32_t Type = SecI->getType(); @@ -1119,10 +1122,13 @@ static char getNMSectionTagAndName(SymbolicFile &Obj, basic_symbol_iterator I, else Ret = getSymbolNMTypeChar(cast(Obj), I); - if (Symflags & object::SymbolRef::SF_Global) - Ret = toupper(Ret); + if (!(Symflags & object::SymbolRef::SF_Global)) + return Ret; + + if (Obj.isELF() && ELFSymbolRef(*I).getBinding() == ELF::STB_GNU_UNIQUE) + return Ret; - return Ret; + return toupper(Ret); } // getNsectForSegSect() is used to implement the Mach-O "-s segname sectname" -- 2.50.1