gdb 10.1: wrong argument lookup code is used for x86_64 frame

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

gdb 10.1: wrong argument lookup code is used for x86_64 frame

Nat!
Hi

my problem is, that this code in gdb:

```
   struct frame_info *frame = get_current_frame ();
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
   obj = gdbarch_fetch_pointer_argument (gdbarch, frame, 0, ptr_type);
```

runs into `i386_fetch_pointer_argument` which does hard coded 32 bit memory
reads. But the executable I am debugging is 64 bit and so is gdb and the
OS.
If I look into *gdbarch, the basic values look sane:

```
   int_bit = 32
   long_bit = 64
   ptr_bit = 64
   addr_bit = 64
```

But `gdbarch_fetch_pointer_argument` will use the
`gdbarch->fetch_pointer_argument` vector to reach
`i386_fetch_pointer_argument`,
which is coded like this:

```
static CORE_ADDR
i386_fetch_pointer_argument (struct frame_info *frame, int argi,
                  struct type *type)
{
   struct gdbarch *gdbarch = get_frame_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR sp = get_frame_register_unsigned (frame, I386_ESP_REGNUM);
   return read_memory_unsigned_integer (sp + (4 * (argi + 1)), 4,
byte_order);
}

```

If I am in architecure i386:x86_64 the first argument is going to be in a
register, why is memory being read ?

If pointer sized memory is read then why is 4 hard coded and not
something like
`gdbarch_ptr_bit( gdbarch) / 8` ?

Is there a x86_64_fetch_pointer_argument, and why isn't it used ?

Ciao

  Nat!


Intro blurb:

```

GNU gdb (GDB) 10.0.50.20200420-git
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
```


gdb --configuration:

```

This GDB was configured as follows:
    configure --host=x86_64-pc-linux-gnu --target=x86_64-pc-linux-gnu
              --with-auto-load-dir=$debugdir:$datadir/auto-load
              --with-auto-load-safe-path=$debugdir:$datadir/auto-load
              --without-expat
              --with-gdb-datadir=/usr/local/share/gdb (relocatable)
              --with-jit-reader-dir=/usr/local/lib/gdb (relocatable)
              --without-libunwind-ia64
              --with-lzma
              --without-babeltrace
              --without-intel-pt
              --with-mpfr
              --without-xxhash
              --without-python
              --without-debuginfod
              --without-guile
              --disable-source-highlight
              --with-separate-debug-dir=/usr/local/lib/debug (relocatable)
```


uname -a:


```
Linux whoever 5.3.0-46-generic #38-Ubuntu SMP Fri Mar 27 17:37:05 UTC
2020 x86_64 x86_64 x86_64 GNU/Linux
```


Reply | Threaded
Open this post in threaded view
|

Re: gdb 10.1: wrong argument lookup code is used for x86_64 frame

Nat!
For my purposes, I could fix this by adding a
amd64_fetch_pointer_argumentfunction to amd64-tdep.c:

```

static CORE_ADDR
amd64_fetch_pointer_argument (struct frame_info *frame, int argi,
               struct type *type)
{
   struct gdbarch *gdbarch = get_frame_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR sp;
   int regnum;
   int len;

   switch( argi)
   {
   case 0  : regnum = AMD64_RDI_REGNUM; break;
   case 1  : regnum = AMD64_RSI_REGNUM; break;
   case 2  : regnum = AMD64_RDX_REGNUM; break;
   case 3  : regnum = AMD64_RCX_REGNUM; break;
   case 4  : regnum = AMD64_R8_REGNUM; break;
   case 5  : regnum = AMD64_R9_REGNUM; break;

   default : sp  = get_frame_register_unsigned( frame, AMD64_RSP_REGNUM);
             len = gdbarch_ptr_bit( gdbarch) / 8;
             return read_memory_unsigned_integer (sp + (len * (argi -
5)), len, byte_order);
   }
   return( get_frame_register_unsigned( frame, regnum));
}

```

The `default:` code path is probably trash :)


And I put this into `amd64_init_abi`:

```

set_gdbarch_fetch_pointer_argument (gdbarch, amd64_fetch_pointer_argument);
```


Ciao

   Nat!