Index: llvm/include/llvm/Object/ELFObjectFile.h =================================================================== --- llvm/include/llvm/Object/ELFObjectFile.h +++ llvm/include/llvm/Object/ELFObjectFile.h @@ -56,6 +56,7 @@ 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; @@ -144,6 +145,10 @@ return getObject()->getSymbolSize(getRawDataRefImpl()); } + uint8_t getBinding() const { + return getObject()->getSymbolBinding(getRawDataRefImpl()); + } + uint8_t getOther() const { return getObject()->getSymbolOther(getRawDataRefImpl()); } @@ -251,6 +256,7 @@ 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; @@ -554,6 +560,11 @@ } 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; } Index: llvm/test/tools/llvm-nm/X86/unique.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-nm/X86/unique.test @@ -0,0 +1,10 @@ +# Fixes https://bugs.llvm.org/show_bug.cgi?id=41353 +# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t.o +# RUN: llvm-nm %t.o | FileCheck %s + + .data + .type foo,%gnu_unique_object +foo: + .byte 0 + +# CHECK: 0000000000000000 u foo Index: llvm/tools/llvm-nm/llvm-nm.cpp =================================================================== --- llvm/tools/llvm-nm/llvm-nm.cpp +++ llvm/tools/llvm-nm/llvm-nm.cpp @@ -923,6 +923,14 @@ SymbolList.clear(); } +static bool isELFUniqueGlobalSymbol(const BasicSymbolRef &Sym) { + const SymbolicFile *Obj = Sym.getObject(); + if (!Obj->isELF()) + return false; + ELFSymbolRef ELFSym(Sym); + return ELFSym.getBinding() == ELF::STB_GNU_UNIQUE; +} + static char getSymbolNMTypeChar(ELFObjectFileBase &Obj, basic_symbol_iterator I) { // OK, this is ELF @@ -944,7 +952,7 @@ return 't'; case (ELF::SHF_TLS | ELF::SHF_ALLOC | ELF::SHF_WRITE): case (ELF::SHF_ALLOC | ELF::SHF_WRITE): - return 'd'; + return isELFUniqueGlobalSymbol(*SymI) ? 'u' : 'd'; case ELF::SHF_ALLOC: case (ELF::SHF_ALLOC | ELF::SHF_MERGE): case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS): @@ -1172,7 +1180,7 @@ else Ret = getSymbolNMTypeChar(cast(Obj), I); - if (Symflags & object::SymbolRef::SF_Global) + if ((Symflags & object::SymbolRef::SF_Global) && !isELFUniqueGlobalSymbol(*I)) Ret = toupper(Ret); return Ret;