[llvm-nm] Display defined weak STT_GNU_IFUNC symbols as 'i'

This patch makes the behavior match GNU nm.
Note: undefined STT_GNU_IFUNC symbols use 'U'.

Differential Revision: https://reviews.llvm.org/D95461
This commit is contained in:
Fangrui Song 2021-01-28 09:46:05 -08:00
parent 2dd0c4d846
commit b3af96d07b
2 changed files with 22 additions and 8 deletions

View File

@ -5,6 +5,9 @@
# CHECK: i ifunc_local # CHECK: i ifunc_local
# CHECK-NEXT: i ifunc_global # CHECK-NEXT: i ifunc_global
# CHECK-NEXT: i ifunc_weak
# CHECK-NEXT: U ifunc_undef
# CHECK-NEXT: w ifunc_undef_weak
!ELF !ELF
FileHeader: FileHeader:
@ -25,3 +28,13 @@ Symbols:
Type: STT_GNU_IFUNC Type: STT_GNU_IFUNC
Binding: STB_GLOBAL Binding: STB_GLOBAL
Section: .text 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

View File

@ -1142,13 +1142,16 @@ static char getNMSectionTagAndName(SymbolicFile &Obj, basic_symbol_iterator I,
} }
} }
if ((Symflags & object::SymbolRef::SF_Weak) && !isa<MachOObjectFile>(Obj)) { if (Symflags & object::SymbolRef::SF_Undefined) {
char Ret = isObject(Obj, I) ? 'v' : 'w'; if (isa<MachOObjectFile>(Obj) || !(Symflags & object::SymbolRef::SF_Weak))
return (!(Symflags & object::SymbolRef::SF_Undefined)) ? toupper(Ret) : Ret; return 'U';
return isObject(Obj, I) ? 'v' : 'w';
} }
if (ELFObjectFileBase *ELF = dyn_cast<ELFObjectFileBase>(&Obj))
if (Symflags & object::SymbolRef::SF_Undefined) if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC)
return 'U'; return 'i';
if (!isa<MachOObjectFile>(Obj) && (Symflags & object::SymbolRef::SF_Weak))
return isObject(Obj, I) ? 'V' : 'W';
if (Symflags & object::SymbolRef::SF_Common) if (Symflags & object::SymbolRef::SF_Common)
return 'C'; return 'C';
@ -1169,8 +1172,6 @@ static char getNMSectionTagAndName(SymbolicFile &Obj, basic_symbol_iterator I,
else if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj)) else if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj))
Ret = getSymbolNMTypeChar(*Tapi, I); Ret = getSymbolNMTypeChar(*Tapi, I);
else if (ELFObjectFileBase *ELF = dyn_cast<ELFObjectFileBase>(&Obj)) { else if (ELFObjectFileBase *ELF = dyn_cast<ELFObjectFileBase>(&Obj)) {
if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC)
return 'i';
Ret = getSymbolNMTypeChar(*ELF, I); Ret = getSymbolNMTypeChar(*ELF, I);
if (ELFSymbolRef(*I).getBinding() == ELF::STB_GNU_UNIQUE) if (ELFSymbolRef(*I).getBinding() == ELF::STB_GNU_UNIQUE)
return Ret; return Ret;