bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug binutils/18218] New: bad handling of .debug_str_offsets section


From: dje at google dot com
Subject: [Bug binutils/18218] New: bad handling of .debug_str_offsets section
Date: Wed, 08 Apr 2015 20:10:50 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=18218

            Bug ID: 18218
           Summary: bad handling of .debug_str_offsets section
           Product: binutils
           Version: unspecified
            Status: NEW
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: dje at google dot com

Problem:

readelf -w readelf-str-offsets.dwo
->
    <c>   DW_AT_producer    : (indexed string: 0x5): <no .debug_str_offsets.dwo
section>

However, this works:

readelf -wi readelf-str-offsets.dwo
->
    <c>   DW_AT_producer    : (indexed string: 0x5): GNU C ...

The appended testcase, readelf-str-offsets-bug.s, was created by compiling
this file:

---snip---
/* We need enough entries in .debug_str_offsets so that                         
   gas/write.c:compress_debug will compress it.                                 
   Threshold is 32 bytes.  */

int var1;
int var2;
int var3;
int var4;

int
main ()
{
  return 0;
}
---snip---

thusly:

gcc -m64 -gdwarf-4 -gsplit-dwarf -c readelf-str-offsets-bug.c -save-temps
-Wa,--compress-debug-sections

and then manually editing the .s file so that .debug_str_offsets appears before
.debug_info, and then recompiling thusly:

gcc -m64 -gdwarf-4 -gsplit-dwarf -c readelf-str-offsets-bug.s
-Wa,--compress-debug-sections

[The system where I tripped over this bug just happened to put
.debug_str_offsets ahead of .debug_info.]

The bug occurs because .debug_str_offsets is loaded and decompressed twice:
1) to display .zdebug_str_offsets itself
2) to display .zdebug_info

The first time through we hit this code in
readelf.c:load_specific_debug_section

  if (section->start == NULL)
    section->size = 0;
  else
    {
      section->size = sec->sh_size;
      if (uncompress_section_contents (&section->start, &section->size))
        sec->sh_size = section->size;   <<<<<<<<<<<<<
    }

Note that we've set sec->sh_size to the new, uncompressed value.

Then we free the section here in display_debug_section:

            if (secondary || (i != info && i != abbrev))
              free_debug_section ((enum dwarf_section_display_enum) i);

Then we'll go to display .debug_info.
But because we no longer have .debug_str_offsets we reload it.
However, it's sh_size field is now bad - it no longer contains the compressed
size.  So we reload the section with the newer larger size thinking all of that
is compressed data, the read fails, and the section is left as marked as
unloaded.

We then get here in fetch_indexed_string:

  if (index_section->start == NULL)
    return (dwo ? _("<no .debug_str_offsets.dwo section>")
                : _("<no .debug_str_offsets section>"));

---

N.B. The above written prior to commit 77115a4a.

2015-04-05  H.J. Lu  <address@hidden>

        * readelf.c (get_elf_section_flags): Support SHF_COMPRESSED.
        (get_compression_header): New.
        (process_section_headers): Dump compression header if needed.
        (uncompress_section_contents): Don't free compressed_buffer here.
        (load_specific_debug_section): Free the compressed buffer, update
        the section buffer and the section size if uncompress is
        successful.

There is still a bug though.
Now I'm getting:

readelf: Warning: DW_FORM_GNU_str_index indirect offset too big: 76207962
and
    <c>   DW_AT_producer    : (indexed string: 0x5): <indirect index offset is
too big>

It seems that when fetch_indexed_string is called, the contents are compressed.

(gdb) p *index_section
$46 = {
  uncompressed_name = 0x47ffab ".debug_str_offsets.dwo",
  compressed_name = 0x47ffc2 ".zdebug_str_offsets.dwo",
  name = 0x47ffc2 ".zdebug_str_offsets.dwo",
  start = 0x68f430 "ZLIB", <<<<<<<<<<<<<<<<<
  address = 0,
  size = 32,
  abbrev_sec = abbrev,
  user_data = 0x0
}

-- 
You are receiving this mail because:
You are on the CC list for the bug.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]