dwarf_block_to_fb_offset() and 64-bit host

Jonathan Larmour <[email protected]>
Newsgroups gmane.comp.gdb.devel
Message-ID <[email protected]>
Hi folks,

I've been looking at a problem on a remote Cortex-M target, which notably
happens to have a somewhat atypical property of using an address space of
0x9xxxxxxx - in other words, addresses will have the top bit set.

When debugging, there is a problem with a GDB built for a 64-bit host,
versus one built for 32-bit, all from exactly the same source base. It
manifests with this sort of issue with a 64-bit hosted GDB:

Breakpoint 2, fileio1_main (id=0, id@entry=<error reading variable: Cannot
access memory at address 0x9001917c>)
    at /.../fatfs1.c:431

The cited address is perfectly valid and readable. Whereas on a 32-bit GDB:
Breakpoint 2, fileio1_main (id=0) at /.../fatfs1.c:431

I have tracked down where the 32-bit and 64-bit builds of GDB diverge in
behaviour and it's in dwarf2expr.c's dwarf_block_to_fb_offset():

int
dwarf_block_to_fb_offset (const gdb_byte *buf, const gdb_byte *buf_end,
                          CORE_ADDR *fb_offset_return)
{
  int64_t fb_offset;
[snip]
  buf++;

  buf = gdb_read_sleb128 (buf, buf_end, &fb_offset);
  if (buf == NULL)
    return 0;
  *fb_offset_return = fb_offset;
  if (buf != buf_end || fb_offset != (LONGEST) *fb_offset_return)
    return 0;

  return 1;
}

In the 32-bit (working) build, in one failing example, fb_offset ends up
as -28, whereas *fb_offset_return is 0xffffffe4 - this is because
CORE_ADDR is an *unsigned* 32-bit type (due to bfd_vma). But LONGEST is a
signed long long - 64-bits - so the comparison between fb_offset and
*fb_offset_return ends up comparing -28 and 4294967268. So 0 is returned.

In the 64-bit (buggy) build, fb_offset is still -28 but *fb_offset_return
is 0xffffffffffffffe4 (CORE_ADDR now being an unsigned 64-bit type), which
when cast to LONGEST (which is signed) is still -28. Therefore 1 is
returned. This later results in read_frame_arg()'s call to
ops->read_variable_at_entry incorrectly believing there is a different
value of the variable on entry.

I'm unsure about where the bug really lies. I'm not familiar enough with
Dwarf, but I have to wonder why there's the test for "fb_offset !=
(LONGEST) *fb_offset_return" in the first place.

Any help/advice from anyone with Dwarf experience would be welcome, thanks.

Jifl
-- 
------["Si fractum non sit, noli id reficere"]------       Opinions==mine
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.