diff --git a/llvm/test/tools/llvm-nm/ifunc.test b/llvm/test/tools/llvm-nm/ifunc.test --- a/llvm/test/tools/llvm-nm/ifunc.test +++ b/llvm/test/tools/llvm-nm/ifunc.test @@ -5,6 +5,9 @@ # CHECK: i ifunc_local # CHECK-NEXT: i ifunc_global +# CHECK-NEXT: i ifunc_weak +# CHECK-NEXT: U ifunc_undef +# CHECK-NEXT: w ifunc_undef_weak !ELF FileHeader: @@ -25,3 +28,13 @@ Type: STT_GNU_IFUNC Binding: STB_GLOBAL Section: .text + - Name: ifunc_weak + Type: STT_GNU_IFUNC + Binding: STB_WEAK + Section: .text + - Name: ifunc_undef + Type: STT_GNU_IFUNC + Binding: STB_GLOBAL + - Name: ifunc_undef_weak + Type: STT_GNU_IFUNC + Binding: STB_WEAK diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp --- a/llvm/tools/llvm-nm/llvm-nm.cpp +++ b/llvm/tools/llvm-nm/llvm-nm.cpp @@ -1142,13 +1142,16 @@ } } - if ((Symflags & object::SymbolRef::SF_Weak) && !isa(Obj)) { - char Ret = isObject(Obj, I) ? 'v' : 'w'; - return (!(Symflags & object::SymbolRef::SF_Undefined)) ? toupper(Ret) : Ret; + if (Symflags & object::SymbolRef::SF_Undefined) { + if (isa(Obj) || !(Symflags & object::SymbolRef::SF_Weak)) + return 'U'; + return isObject(Obj, I) ? 'v' : 'w'; } - - if (Symflags & object::SymbolRef::SF_Undefined) - return 'U'; + if (ELFObjectFileBase *ELF = dyn_cast(&Obj)) + if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC) + return 'i'; + if (!isa(Obj) && (Symflags & object::SymbolRef::SF_Weak)) + return isObject(Obj, I) ? 'V' : 'W'; if (Symflags & object::SymbolRef::SF_Common) return 'C'; @@ -1169,8 +1172,6 @@ else if (TapiFile *Tapi = dyn_cast(&Obj)) Ret = getSymbolNMTypeChar(*Tapi, I); else if (ELFObjectFileBase *ELF = dyn_cast(&Obj)) { - if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC) - return 'i'; Ret = getSymbolNMTypeChar(*ELF, I); if (ELFSymbolRef(*I).getBinding() == ELF::STB_GNU_UNIQUE) return Ret;