Summary: | unresolved symbol diagnostic ends up calling find_abstract_instance with relocations applied causing spurious 'DWARF error: invalid abstract instance DIE ref' | ||
---|---|---|---|
Product: | binutils | Reporter: | Richard Biener <rguenth> |
Component: | ld | Assignee: | Alan Modra <amodra> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | hjl.tools, jg, noloader |
Priority: | P2 | ||
Version: | 2.30 | ||
Target Milestone: | --- | ||
URL: | https://sourceware.org/ml/binutils/2018-09/msg00075.html | ||
Host: | Target: | ||
Build: | Last reconfirmed: | ||
Attachments: |
testcase
A patch |
Description
Richard Biener
2018-07-18 07:27:35 UTC
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)." |