[PATCH] Tiny 64-bit Dwarf2 glitch

Kevin Buettner kevinb@redhat.com
Tue Jun 25 13:51:00 GMT 2002


On Jun 25,  3:15pm, Jason Eckhardt wrote:

> On Tue, 25 Jun 2002, Kevin Buettner wrote:
> 
> > >
> > >     /* Read in the prologue.  */
> > > !   lh.total_length = read_4_bytes (abfd, line_ptr);
> > > !   line_ptr += 4;
> > > !   offset_size = 4;
> > > !   if (lh.total_length == 0xffffffff)
> >
> > Why are you eliminating the escape mechanism that indicates 64-bit
> > offsets?
> 
>   Note that I didn't eliminate it, I replaced it with a check of
>   unit->addr_size. I chose to do this because:
>   1. The "escape mechanism" isn't working for at least one back-end
>      (elf64-bigmips). That is, it isn't returning 0xffffffff to
>      indicate 64-bit offsets (this probably needs investigating too,
>      but it is peripheral to what I'm currently trying to solve).
>   2. Even if it did work, I believe the new check is more explanatory/
>      explicit than checking if read_4_bytes returned some hard-coded
>      escape constant value. If this is incorrect, or undesirable,
>      please explain why.

As I understand it, the initial length is either a 4-byte or 12-byte
integer.  If it's a 4-byte integer, then offsets are 4-bytes wide.  If
it's a 12-byte integer, the first four bytes are the special escape code
0xffffffff and the next eight bytes are the actual length.

The address size is the size in bytes of an address on the target
architecture and AFAICT has little to do with whether you're using the
64-bit DWARF format or the 32-bit DWARF format.  (Though I do think it
likely that the address size will be 8 when you're using the 64-bit
DWARF format.)

>   But setting that issue aside, the original code appears bogus
>   (even assuming the escape mechanism works):
> 
>     /* Read in the prologue.  */
>     lh.total_length = read_4_bytes (abfd, line_ptr);
>     line_ptr += 4;
>     offset_size = 4;
>     if (lh.total_length == 0xffffffff)
>       {
>         lh.total_length = read_8_bytes (abfd, line_ptr);
>         line_ptr += 8;
>         offset_size = 8;
>       }
> 
>   Can you see the obvious problem?

No.  It looks right to me.

>   The current patch solved my problem for both 32 and 64-bit ELF64/mips
>   binaries, whereas the original code fails miserably.
> 
>   If someone has a better way to correct the defect, please let me know.
>   This defect prevents a binary analysis tool I'm working on from
>   functioning properly.

I do agree that we need to accomodate older toolchains which don't adhere
to the current (draft) standard.  I think the best way to do this is to
read the first 4 bytes.  If these bytes are 0xffffffff, then read the
next 8 bytes as the length and set the offset size to 8.

OTOH, if the first four bytes were 0 (which isn't a useful size), read
the next four bytes as the size of the section and set the offset size
to 8.

Finally, if neither of these escape values are seen, then the first four
bytes which were read was really the length and the offset size should be
4.

I think the following (untested) patch implements this:

--- dwarf2.c	Tue Jun 25 13:02:33 2002
+++ new.dwarf2.c	Tue Jun 25 11:38:42 2002
@@ -981,24 +981,20 @@ decode_line_info (unit, stash)
   line_ptr = stash->dwarf_line_buffer + unit->line_offset;
 
   /* Read in the prologue.  */
-  if (unit->addr_size == 4)
-    {
-      lh.total_length = read_4_bytes (abfd, line_ptr);
-      line_ptr += 4;
-      offset_size = 4;
-    }
-  else
+  lh.total_length = read_4_bytes (abfd, line_ptr);
+  line_ptr += 4;
+  offset_size = 4;
+  if (lh.total_length == 0xffffffff)
     {
-      BFD_ASSERT (unit->addr_size == 8);
       lh.total_length = read_8_bytes (abfd, line_ptr);
       line_ptr += 8;
       offset_size = 8;
     }
-
-  if (lh.total_length == 0xffffffff)
+  else if (lh.total_length == 0)
     {
-      lh.total_length = read_8_bytes (abfd, line_ptr);
-      line_ptr += 8;
+      /* Handle (non-standard) 64-bit DWARF2 formats.  */
+      lh.total_length = read_4_bytes (abfd, line_ptr);
+      line_ptr += 4;
       offset_size = 8;
     }
   line_end = line_ptr + lh.total_length;

Kevin



More information about the Binutils mailing list