Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -2412,6 +2412,34 @@ return Ret; } +// gold/gdb-index.cc Gdb_index_info_reader::visit_die traverses .debug_info to +// extract symbols when .debug_gnu_pubnames is absent. This function implements +// a subset of it to improve coverage of the .gdb_index symbol table. +static void extractSymbol(DWARFDie D, uint32_t Idx, + std::vector &Ret) { + switch (D.getTag()) { + case DW_TAG_constant: + case DW_TAG_enumerator: + case DW_TAG_subprogram: + case DW_TAG_variable: { + // Ignore mangled names for now. + if (StringRef(D.getName(DINameKind::LinkageName)).startswith("_Z")) + break; + // As of 2018-11, gold uses 0 as the attributes part. We follow it here. + if (const char *Name = D.getName(DINameKind::ShortName)) + Ret.push_back({{Name, computeGdbHash(Name)}, Idx}); + break; + } + default: + break; + } + DWARFDie Child = D.getFirstChild(); + while (Child) { + extractSymbol(Child, Idx, Ret); + Child = Child.getSibling(); + } +} + template static std::vector readPubNamesAndTypes(const LLDDwarfObj &Obj, @@ -2544,6 +2572,13 @@ NameAttrs[I] = readPubNamesAndTypes( static_cast &>(Dwarf.getDWARFObj()), Chunks[I].CompilationUnits); + if (NameAttrs[I].empty()) { + uint32_t Idx = 0; + for (const auto &U : Dwarf.info_section_units()) + if (DWARFDie CUDie = U->getUnitDIE(false)) + extractSymbol(CUDie, Idx, NameAttrs[Idx]); + ++Idx; + } }); auto *Ret = make(); Index: test/ELF/gdb-index-debug-info.s =================================================================== --- /dev/null +++ test/ELF/gdb-index-debug-info.s @@ -0,0 +1,33 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld --gdb-index %t.o -o %t +# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s + +# CHECK: String name: __libc_csu_init + +.section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 8 # DW_FORM_string + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 + +.section .debug_info,"",@progbits +.Lcu_begin0: + .long .Lcu_end0 - .Lcu_begin0 - 4 + .short 4 # DWARF version number + .long 0 # Offset Into Abbrev. Section + .byte 4 # Address Size +.Ldie: + .byte 1 # Abbrev [1] DW_TAG_compile_unit + .byte 2 # Abbrev [2] DW_TAG_subprogram + .asciz "__libc_csu_init" # DW_AT_name + .byte 0 +.Lcu_end0: