diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp --- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp +++ b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp @@ -157,7 +157,11 @@ if (!SymbolTypeOrErr) return SymbolTypeOrErr.takeError(); SymbolRef::Type SymbolType = *SymbolTypeOrErr; - if (SymbolType != SymbolRef::ST_Function && SymbolType != SymbolRef::ST_Data) + // This list ensure ELF STT_NOTYPE, STT_FUNC, STT_DATA and STT_GNU_IFUNC are + // included. Functions defined in assembly are often STT_NONE. + if (SymbolType != SymbolRef::ST_Unknown && + SymbolType != SymbolRef::ST_Function && + SymbolType != SymbolRef::ST_Data && SymbolType != SymbolRef::ST_Other) return Error::success(); Expected SymbolAddressOrErr = Symbol.getAddress(); if (!SymbolAddressOrErr) @@ -186,9 +190,11 @@ // Mach-O symbol table names have leading underscore, skip it. if (Module->isMachO() && !SymbolName.empty() && SymbolName[0] == '_') SymbolName = SymbolName.drop_front(); - // FIXME: If a function has alias, there are two entries in symbol table - // with same address size. Make sure we choose the correct one. - auto &M = SymbolType == SymbolRef::ST_Function ? Functions : Objects; + + // DATA command symbolizes just ST_Data (ELF STT_OBJECT) symbols as an + // optimization. Treat everything else (ELF STT_NOTYPE, STT_FUNC and + // STT_GNU_IFUNC ) function symbols which can be symbolize addresses. + auto &M = SymbolType != SymbolRef::ST_Data ? Functions : Objects; SymbolDesc SD = { SymbolAddress, SymbolSize }; M.emplace_back(SD, SymbolName); return Error::success(); diff --git a/llvm/test/DebugInfo/Symbolize/ELF/symtab-ifunc.s b/llvm/test/DebugInfo/Symbolize/ELF/symtab-ifunc.s new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/Symbolize/ELF/symtab-ifunc.s @@ -0,0 +1,27 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t +# RUN: llvm-symbolizer --obj=%t 0 1 + +# CHECK: g_ifunc +# CHECK-NEXT: ??:0:0 +# CHECK-EMPTY: +# CHECK-NEXT: l_ifunc +# CHECK-NEXT: ??:0:0 +# CHECK-EMPTY: + +## TODO Find the closest STT_FILE symbol as the filename of l_ifunc. +.file "symtab-ifunc.s" + +.Lg_resolver: + ret +.size .Lg_resolver, 1 + +.globl g_ifunc +.set g_ifunc, .Lg_resolver +.type g_ifunc, @gnu_indirect_function + +.Ll_resolver: + ret +.size .Ll_resolver, 1 + +.set l_ifunc, .Ll_resolver +.type l_ifunc, @gnu_indirect_function diff --git a/llvm/test/DebugInfo/Symbolize/ELF/symtab-notype.s b/llvm/test/DebugInfo/Symbolize/ELF/symtab-notype.s new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/Symbolize/ELF/symtab-notype.s @@ -0,0 +1,54 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t +# RUN: llvm-symbolizer --obj=%t 0 1 2 3 4 5 6 7 + +# CHECK: _start +# CHECK-NEXT: ??:0:0 +# CHECK-EMPTY: +# CHECK-NEXT: g_notype +# CHECK-NEXT: ??:0:0 +# CHECK-EMPTY: +# CHECK-NEXT: g_notype +# CHECK-NEXT: ??:0:0 +# CHECK-EMPTY: +# CHECK-NEXT: ??:0:0 +# CHECK-NEXT: ??:0:0 +# CHECK-EMPTY: + +## This is a gap. +# CHECK-NEXT: ?? +# CHECK-NEXT: ??:0:0 +# CHECK-EMPTY: + +# CHECK-NEXT: l_notype +# CHECK-NEXT: ??:0:0 +# CHECK-EMPTY: + +# CHECK-NEXT: l_notype_nosize +# CHECK-NEXT: ??:0:0 +# CHECK-EMPTY: +# CHECK-NEXT: l_notype_nosize +# CHECK-NEXT: ??:0:0 +# CHECK-EMPTY: +# CHECK-NEXT: l_notype_nosize +# CHECK-NEXT: ??:0:0 +# CHECK-EMPTY: + +## TODO Find the closest STT_FILE symbol as the filename of a local symbol. +.file "symtab-notype.s" + +.globl _start, g_notype +_start: + retq + +g_notype: + nop + retq +.size g_notype, . - g_notype + + nop + +l_notype: + retq +.size l_notype, . - l_notype + +l_notype_nosize: