Backtrace from the 2.31 branch: #0 _bfd_error_handler ( fmt=0x690150 "DWARF error: invalid abstract instance DIE ref") at /space/rguenther/src/binutils-gdb/bfd/bfd.c:1177 #1 0x00000000004c6214 in find_abstract_instance (unit=0x7056d8, orig_info_ptr=0x76df90 "\004> ", attr_ptr=0x7fffffffcd10, pname=0x770f18, is_linkage=0x770f14, filename_ptr=0x770f00, linenumber_ptr=0x770f0c) at /space/rguenther/src/binutils-gdb/bfd/dwarf2.c:2843 #2 0x00000000004c6cbe in scan_unit_for_symbols (unit=0x7056d8) at /space/rguenther/src/binutils-gdb/bfd/dwarf2.c:3169 #3 0x00000000004c789f in comp_unit_find_nearest_line (unit=0x7056d8, addr=4198435, filename_ptr=0x7fffffffd018, function_ptr=0x7fffffffce70, linenumber_ptr=0x7fffffffd00c, discriminator_ptr=0x0, stash=0x7054a0) at /space/rguenther/src/binutils-gdb/bfd/dwarf2.c:3616 #4 0x00000000004c9975 in _bfd_dwarf2_find_nearest_line (abfd=0x6fe880, symbols=0x705270, symbol=0x0, section=0x700dd0, offset=35, filename_ptr=0x7fffffffd018, functionname_ptr=0x7fffffffd010, linenumber_ptr=0x7fffffffd00c, discriminator_ptr=0x0, debug_sections=0x68f9a0 <dwarf_debug_sections>, addr_size=4, pinfo=0x700090) at /space/rguenther/src/binutils-gdb/bfd/dwarf2.c:4807 #5 0x0000000000491807 in _bfd_elf_find_nearest_line (abfd=0x6fe880, symbols=0x705270, section=0x700dd0, offset=35, filename_ptr=0x7fffffffd018, functionname_ptr=0x7fffffffd010, line_ptr=0x7fffffffd00c, discriminator_ptr=0x0) at /space/rguenther/src/binutils-gdb/bfd/elf.c:8752 #6 0x000000000042574f in vfinfo (fp=0x7ffff7bd2080 <_IO_2_1_stderr_>, fmt=0x555b18 ": undefined reference to `%pT'\n", ap=0x7fffffffd208, is_warning=1) at /space/rguenther/src/binutils-gdb/ld/ldmisc.c:350 #7 0x000000000042643f in einfo ( fmt=0x555b10 "%X%P: %C: undefined reference to `%pT'\n") at /space/rguenther/src/binutils-gdb/ld/ldmisc.c:626 #8 0x000000000041fd50 in undefined_symbol (info=0x6ced80 <link_info>, name=0x70506c "_ZNSsC1Ev", abfd=0x6fe880, section=0x700dd0, address=35, error=1) at /space/rguenther/src/binutils-gdb/ld/ldmain.c:1346 #9 0x000000000046ad3d in elf_x86_64_relocate_section (output_bfd=0x6e7210, info=0x6ced80 <link_info>, input_bfd=0x6fe880, input_section=0x700dd0, contents=0x701f60 "UH\211", <incomplete sequence \345\270>, relocs=0x7050f8, local_syms=0x6f32b0, local_sections=0x76dd60) at /space/rguenther/src/binutils-gdb/bfd/elf64-x86-64.c:2483 The code says it only handles refs within the same file but the guard for this, a zero die_ref, doesn't work after applying relocations to .debug_info and this function ends up being called from the unresolved symbol diagnostic causing a spurious DWARF error to be reported. /* We only support DW_FORM_ref_addr within the same file, so any relocations should be resolved already. Check this by testing for a zero die_ref; There can't be a valid reference to the header of a .debug_info section. DW_FORM_ref_addr is an offset relative to .debug_info. Normally when using the GNU linker this is accomplished by emitting a symbolic reference to a label, because .debug_info sections are linked at zero. When there are multiple section groups containing .debug_info, as there might be in a relocatable object file, it would be reasonable to assume that a symbolic reference to a label in any .debug_info section might be used. Since we lay out multiple .debug_info sections at non-zero VMAs (see place_sections), and read them contiguously into stash->info_ptr_memory, that means the reference is relative to stash->info_ptr_memory. */ size_t total; info_ptr = unit->stash->info_ptr_memory; info_ptr_end = unit->stash->info_ptr_end; total = info_ptr_end - info_ptr; if (!die_ref || die_ref >= total) { _bfd_error_handler (_("DWARF error: invalid abstract instance DIE ref")); bfd_set_error (bfd_error_bad_value); return FALSE;
Created attachment 11143 [details] testcase To reproduce do > ./ld-new -o a.out ccELcIbzdebugobjtem cccLlhS9debugobjtem ccqD9BbN.ltrans0.ltrans.o ./ld-new: warning: cannot find entry symbol _start; defaulting to 0000000000401000 ./ld-new: ./ld-new: DWARF error: invalid abstract instance DIE ref ccqD9BbN.ltrans0.ltrans.o: in function `strerrno(int)': <artificial>:(.text+0x23): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string()' ./ld-new: <artificial>:(.text+0x3b): undefined reference to `strerrno_s(char*, unsigned long, int)' ./ld-new: <artificial>:(.text+0x55): undefined reference to `std::string::operator=(char const*)' ./ld-new: <artificial>:(.text+0x68): undefined reference to `std::string::operator+=(char const*)' ./ld-new: <artificial>:(.text+0x7d): undefined reference to `std::string::operator=(char const*)' ./ld-new: <artificial>:(.text+0x8e): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()' ./ld-new: <artificial>:(.text+0x99): undefined reference to `_Unwind_Resume' ./ld-new: ccqD9BbN.ltrans0.ltrans.o:(.eh_frame+0x4b): undefined reference to `__gcc_personality_v0'
A similar issue seems to happen with .debug_str lookups: /usr/bin/x86_64-linux-gnu-ld: Dwarf Error: Offset (1678049557) greater than or equal to .debug_str size (5846). ... later undefined reference diagnostic but I do not have a testcase to verify that.
Hi Could I ask if anyone is working on this? If someone can work on it, I can probably create a test case for "/usr/bin/x86_64-linux-gnu-ld: Dwarf Error: Offset (1678049557) greater than or equal to .debug_str size (5846)."
(In reply to Jon Grant from comment #3) > Hi > Could I ask if anyone is working on this? > > If someone can work on it, I can probably create a test case for > "/usr/bin/x86_64-linux-gnu-ld: Dwarf Error: Offset (1678049557) greater than > or equal to .debug_str size (5846)." Please provide a testcase.
There's a testcase for the first attached. Can that be worked on first?
/usr/bin/x86_64-linux-gnu-ld: Dwarf Error: Could not find abbrev number 113. I get this output above as well. Could LD add a string to give more of a clue what 113 relates to? Just store the string with the 113 when it is added to the map etc..
/usr/bin/x86_64-linux-gnu-ld: Dwarf Error: Offset (57611527) greater than or equal to .debug_str size (5853). /usr/bin/x86_64-linux-gnu-ld: Dwarf Error: Invalid abstract instance DIE ref. Can LD at least output the obj file causing the error in those messages please?
Another type of message shows up. Maybe it could be updated to clarify what the info pointer was pointing to? /usr/bin/x86_64-linux-gnu-ld: Dwarf Error: Info pointer extends beyond end of attributes /usr/bin/x86_64-linux-gnu-ld: Dwarf Error: Could not find abbrev number 6285.
(In reply to Jon Grant from comment #5) > There's a testcase for the first attached. Can that be worked on first? No, I need your testcase as well unless it is the same as the one here.
Created attachment 11227 [details] A patch Please try this.
(In reply to H.J. Lu from comment #10) > Created attachment 11227 [details] > A patch > > Please try this. Hi H.J. Could you attach you Ld binary please? I'm on x64 Ubuntu
(In reply to Jon Grant from comment #11) > (In reply to H.J. Lu from comment #10) > > Created attachment 11227 [details] > > A patch > > > > Please try this. > > Hi H.J. > Could you attach you Ld binary please? I'm on x64 Ubuntu You need to build your own linker with my patch.
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a4cd947aca23d58966ead843e120f4c19db01030 commit a4cd947aca23d58966ead843e120f4c19db01030 Author: Alan Modra <amodra@gmail.com> Date: Tue Sep 11 23:50:15 2018 +0930 PR23425, unresolved symbol diagnostic dwarf2.c code reasonably assumes that debug info is local to a file, an assumption now violated by gcc, resulting in "DWARF error: invalid abstract instance DIE ref" or wrong details when attempting to print linker error messages with file, function and line reported. This is because find_abstract_instance is only prepared to handle DW_FORM_ref_addr when the .debug_info section referenced is in the current file. When that isn't the case, relocations to access another file's .debug_info will typically be against a symbol defined at the start of that .debug_info section, plus an addend. Since the dwarf2.c code only considers the current file's debug info, that symbol will be undefined, resolving to zero. In effect the ref_addr will wrongly resolve to the current file's .debug_info. This patch avoids the problem by treating relocations in debug sections against undefined symbols in a similar manner to the way relocations against symbols defined in discarded sections are resolved. They result in a zero value (except in .debug_ranges) regardless of the addend. PR 23425 * reloc.c (bfd_generic_get_relocated_section_contents): Zero reloc fields in debug sections when reloc is against an undefined symbol and called from bfd_simple_get_relocated_section_contents or similar. * dwarf2.c (find_abstract_instance): Return true for zero offset DW_FORM_ref_addr without returning values.
Fixed
Many thanks I built from git, and checked locally. The other "abrev" issue, and "Dwarf Error: Offset (1678049557) greater than or equal to .debug_str size (5846)." no longer visible.
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=0930cb3021b8078b34cf216e79eb8608d017864f commit 0930cb3021b8078b34cf216e79eb8608d017864f Author: Alan Modra <amodra@gmail.com> Date: Sat Oct 13 22:03:02 2018 +1030 _bfd_clear_contents bounds checking This PR shows a fuzzed binary triggering a segfault via a bad relocation in .debug_line. It turns out that unlike normal relocations applied to a section, the linker applies those with symbols from discarded sections via _bfd_clear_contents without checking that the relocation is within the section bounds. The same thing now happens when reading debug sections since commit a4cd947aca23, the PR23425 fix. PR 23770 PR 23425 * reloc.c (_bfd_clear_contents): Replace "location" param with "buf" and "off". Bounds check "off". Return status. * cofflink.c (_bfd_coff_generic_relocate_section): Update _bfd_clear_contents call. * elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): Likewise. * elf32-arc.c (elf_arc_relocate_section): Likewise. * elf32-i386.c (elf_i386_relocate_section): Likewise. * elf32-metag.c (metag_final_link_relocate): Likewise. * elf32-nds32.c (nds32_elf_get_relocated_section_contents): Likewise. * elf32-ppc.c (ppc_elf_relocate_section): Likewise. * elf32-visium.c (visium_elf_relocate_section): Likewise. * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. * elf64-x86-64.c *(elf_x86_64_relocate_section): Likewise. * libbfd-in.h (_bfd_clear_contents): Update prototype. * libbfd.h: Regenerate.
Could I ask if this message could be expanded to give more clues if ever it occurs again in a future build? "/usr/bin/x86_64-linux-gnu-ld: Dwarf Error: Offset (1678049557) greater than or equal to .debug_str size (5846)."