This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Backtraces broken on i386 by unorthodox encoding of push %ebp



I have an i386 program on Linux where some of the functions start with a slightly unorthodox encoding of the usual function prologue:

  08048104 <foo>:
   8048104:	ff f5                	push   %ebp
   8048106:	89 e5                	mov    %esp,%ebp

However, when I have this form of prologue, gdb doesn't recongnise it, and doesn't give a meaningful backtrace.

In this case, the push instruction is encoded using the two-byte PUSH r/m32 (FF /6) form, instead of the more common one-byte PUSH r32 (50+rd) form. The two instructions execute identically, and both have been around since the 8086. So far as I'm aware, the ABI doesn't require the use of the shorter encoding of the instruction in the function prologue. And for this particular application, I would prefer to continue using the two-byte form.

I think it should be pretty straightforward to make gdb accept both versions of the instruction. I'm not familiar with gdb's source code, but at a guess, modifying the start of i386_analyze_frame_setup in gdb/i386-tdep.c so that it does something like this:

  /* Check for `pushl %ebp', either encoded using `push r32' (55)
     or less commonly using `push r/m32' (FF F5). */
  if (op == 0x55 || op == 0xff
      && read_memory_unsigned_integer (pc + 1, 1, byte_order) == 0xf5)
    {
      /* Take into account that we've executed the `pushl %ebp' that
         starts this instruction sequence.  */
      cache->saved_regs[I386_EBP_REGNUM] = 0;
      cache->sp_offset += 4;
      pc += op == 0x55 ? 1 : 2;

I expect the amd64 version of the code could do with a similar change.

Richard


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]