I N F O R M A T I O N

Symptom: Incomplete backtrace.
Cause: Incorrect handling of L+X type instruction in 
gdb-5.1.1/gdb/ia64-tdep.c
:fetch_instruction()
Details: In L+X type instruction immediate data is in slot 1 and 
instruction is in slot 2. Code doesn't correctly skip over slot 1 and 
uses immediate data when decoding instruction. This results in 
non-predictated instructions sometimes being identified as predicated 
causing early exit of the examine_prologue loop. If BR0 has not been 
spilled when L+X instruction is identified then 
frame->saved_regs[IA64_VRAP_REGNUM] is 0. This causes 
ia64_frame_saved_pc to call ia64_saved_pc_after_call which reads 
whatever is in BR0 and uses that as the new PC.

C O N T E X T  D I F F S

Broken: 

  *instr = slotN_contents (bundle, slotnum);
  template = extract_bit_field (bundle, 0, 5);
  *it = template_encoding_table[(int)template][slotnum];

Fixed:

  template = extract_bit_field (bundle, 0, 5);
  // Handle L+X type instructions.
  if ((template == 0x04 || template == 0x05) && slotnum == 1) {
    slotnum = 2;
  }

  *instr = slotN_contents (bundle, slotnum);
  //  template = extract_bit_field (bundle, 0, 5);
  *it = template_encoding_table[(int)template][slotnum];


T O  R E P L I C A T E
Compile attachment

 >gcc -O2 ./test.c
 >./a.out

Program will dump core

gdb ./a.out ./core

Do a backtrace.
Broken version shows only c() and b().
Fixed version shows c() b() a() and main().

Note: b() is slightly complicated since we need the compiler to generate 
a movl before spilling BR0. Generally, the compiler tries to spill BR0 
as early as possible.

E N V I R O N M E N T

[lhsrihan@itanic~/src64/gdb-5.1.1/gdb]./gdb -version
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain 
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "ia64-unknown-linux".

[lhsrihan@itanic~/src64/gdb-5.1.1/gdb]uname -a
Linux itanic.vmware.com 2.4.18 #21 Tue May 21 09:53:20 PDT 2002 ia64 unknown

[lhsrihan@itanic~/src64/gdb-5.1.1/gdb]gcc -v
Reading specs from /usr/lib/gcc-lib/ia64-redhat-linux/2.96/specs
gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-81)

#include <stdlib.h>

int a(float x);
char b(int y);
int c(int z);

int main(void)
{
  a(0.0);
  return 0;
}

int a(float x)
{
  b(1);
  return 0;
}

char b(int y)
{
  long aa = 0xFFFFFFFF349812;
  //  long aa = 11;
  aa /= y;
  aa += y >> 3;
  if (aa)
    c(1);
  return 'c';
}

int c(int z)
{
  int *p = 0;
  *p = z;
  printf("this is c \n");
  return 0;
}
  

Reply via email to