Index: llvm/include/llvm/Object/ELFTypes.h =================================================================== --- llvm/include/llvm/Object/ELFTypes.h +++ llvm/include/llvm/Object/ELFTypes.h @@ -241,6 +241,8 @@ return getBinding() != ELF::STB_LOCAL; } + bool isUniqueGlobal() const { return getBinding() == ELF::STB_GNU_UNIQUE; } + Expected getName(StringRef StrTab) const; }; Index: llvm/test/tools/llvm-nm/X86/Inputs/unique.s =================================================================== --- /dev/null +++ llvm/test/tools/llvm-nm/X86/Inputs/unique.s @@ -0,0 +1,4 @@ + .data + .type foo,%gnu_unique_object +foo: + .byte 0 Index: llvm/test/tools/llvm-nm/X86/unique.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-nm/X86/unique.test @@ -0,0 +1,5 @@ +# RUN: clang -c %p/Inputs/unique.s -o %t +# RUN: llvm-nm %t | FileCheck %s +# Fixes https://bugs.llvm.org/show_bug.cgi?id=41353 + +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,24 @@ SymbolList.clear(); } +template +static bool isUniqueGlobalSymbol(const ELFObjectFile *Obj, + const BasicSymbolRef &Sym) { + return Obj->getSymbol(Sym.getRawDataRefImpl())->isUniqueGlobal(); +} + +static bool isELFUniqueGlobalSymbol(const BasicSymbolRef &Sym) { + const SymbolicFile *Obj = Sym.getObject(); + if (auto *ELF32LE = dyn_cast(Obj)) + return isUniqueGlobalSymbol(ELF32LE, Sym); + if (auto *ELF64LE = dyn_cast(Obj)) + return isUniqueGlobalSymbol(ELF64LE, Sym); + if (auto *ELF32BE = dyn_cast(Obj)) + return isUniqueGlobalSymbol(ELF32BE, Sym); + auto *ELF64BE = cast(Obj); + return isUniqueGlobalSymbol(ELF64BE, Sym); +} + static char getSymbolNMTypeChar(ELFObjectFileBase &Obj, basic_symbol_iterator I) { // OK, this is ELF @@ -944,7 +962,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 +1190,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;