/* Stack unwinding code based on dwarf2 frame info for GDB, the GNU debugger.
- Copyright 2001, 2002 Free Software Foundation, Inc.
+
+ Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
Contributed by Jiri Smid, SuSE Labs.
Based on code written by Daniel Berlin (dan@dberlin.org).
PE_funcrel = DW_EH_PE_funcrel
};
-#define UNWIND_CONTEXT(fi) ((struct context *) (fi->context))
+#define UNWIND_CONTEXT(fi) ((struct context *) (deprecated_get_frame_context (fi)))
\f
static struct cie_unit *cie_chunks;
extern unsigned int dwarf_frame_size;
extern file_ptr dwarf_eh_frame_offset;
extern unsigned int dwarf_eh_frame_size;
+extern asection *dwarf_frame_section;
+extern asection *dwarf_eh_frame_section;
\f
+
extern char *dwarf2_read_section (struct objfile *objfile, file_ptr offset,
- unsigned int size);
+ unsigned int size, asection *sectp);
static struct fde_unit *fde_unit_alloc (void);
static struct cie_unit *cie_unit_alloc (void);
static void unwind_tmp_obstack_init ();
static void unwind_tmp_obstack_free ();
-static unsigned int read_1u (bfd * abfd, char **p);
-static int read_1s (bfd * abfd, char **p);
-static unsigned int read_2u (bfd * abfd, char **p);
-static int read_2s (bfd * abfd, char **p);
-static unsigned int read_4u (bfd * abfd, char **p);
-static int read_4s (bfd * abfd, char **p);
-static ULONGEST read_8u (bfd * abfd, char **p);
-static LONGEST read_8s (bfd * abfd, char **p);
-
-static ULONGEST read_uleb128 (bfd * abfd, char **p);
-static LONGEST read_sleb128 (bfd * abfd, char **p);
-static CORE_ADDR read_pointer (bfd * abfd, char **p);
-static CORE_ADDR read_encoded_pointer (bfd * abfd, char **p,
+static unsigned int read_1u (bfd *abfd, char **p);
+static int read_1s (bfd *abfd, char **p);
+static unsigned int read_2u (bfd *abfd, char **p);
+static int read_2s (bfd *abfd, char **p);
+static unsigned int read_4u (bfd *abfd, char **p);
+static int read_4s (bfd *abfd, char **p);
+static ULONGEST read_8u (bfd *abfd, char **p);
+static LONGEST read_8s (bfd *abfd, char **p);
+
+static ULONGEST read_uleb128 (bfd *abfd, char **p);
+static LONGEST read_sleb128 (bfd *abfd, char **p);
+static CORE_ADDR read_pointer (bfd *abfd, char **p);
+static CORE_ADDR read_encoded_pointer (bfd *abfd, char **p,
unsigned char encoding);
-static enum ptr_encoding pointer_encoding (unsigned char encoding);
+static enum ptr_encoding pointer_encoding (unsigned char encoding,
+ struct objfile *objfile);
-static LONGEST read_initial_length (bfd * abfd, char *buf, int *bytes_read);
-static ULONGEST read_length (bfd * abfd, char *buf, int *bytes_read,
+static LONGEST read_initial_length (bfd *abfd, char *buf, int *bytes_read);
+static ULONGEST read_length (bfd *abfd, char *buf, int *bytes_read,
int dwarf64);
static int is_cie (ULONGEST cie_id, int dwarf64);
int regs_size = sizeof (struct context_reg) * NUM_REGS;
struct context_reg *dreg;
- /* Structure dst contains a pointer to an array of
- * registers of a given frame as well as src does. This
- * array was already allocated before dst was passed to
- * context_cpy but the pointer to it was overriden by
- * '*dst = *src' and the array was lost. This led to the
- * situation, that we've had a copy of src placed in dst,
- * but both of them pointed to the same regs array and
- * thus we've sometimes blindly rewritten it. Now we save
- * the pointer before copying src to dst, return it back
- * after that and copy the registers into their new place
- * finally. --- mludvig@suse.cz */
+ /* Since `struct context' contains a pointer to an array with
+ register values, make sure we end up with a copy of that array,
+ and not with a copy of the pointer to that array. */
dreg = dst->reg;
*dst = *src;
dst->reg = dreg;
-
memcpy (dst->reg, src->reg, regs_size);
}
static unsigned int
-read_1u (bfd * abfd, char **p)
+read_1u (bfd *abfd, char **p)
{
unsigned ret;
}
static int
-read_1s (bfd * abfd, char **p)
+read_1s (bfd *abfd, char **p)
{
int ret;
}
static unsigned int
-read_2u (bfd * abfd, char **p)
+read_2u (bfd *abfd, char **p)
{
unsigned ret;
ret = bfd_get_16 (abfd, (bfd_byte *) * p);
- (*p)++;
+ (*p) += 2;
return ret;
}
static int
-read_2s (bfd * abfd, char **p)
+read_2s (bfd *abfd, char **p)
{
int ret;
}
static unsigned int
-read_4u (bfd * abfd, char **p)
+read_4u (bfd *abfd, char **p)
{
unsigned int ret;
}
static int
-read_4s (bfd * abfd, char **p)
+read_4s (bfd *abfd, char **p)
{
int ret;
}
static ULONGEST
-read_8u (bfd * abfd, char **p)
+read_8u (bfd *abfd, char **p)
{
ULONGEST ret;
}
static LONGEST
-read_8s (bfd * abfd, char **p)
+read_8s (bfd *abfd, char **p)
{
LONGEST ret;
}
static ULONGEST
-read_uleb128 (bfd * abfd, char **p)
+read_uleb128 (bfd *abfd, char **p)
{
ULONGEST ret;
int i, shift;
}
static LONGEST
-read_sleb128 (bfd * abfd, char **p)
+read_sleb128 (bfd *abfd, char **p)
{
LONGEST ret;
int i, shift, size, num_read;
}
static CORE_ADDR
-read_pointer (bfd * abfd, char **p)
+read_pointer (bfd *abfd, char **p)
{
switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
{
case 8:
return read_8u (abfd, p);
default:
- error ("dwarf cfi error: unsupported target address length.");
+ error
+ ("dwarf cfi error: unsupported target address length [in module %s]",
+ bfd_get_filename (abfd));
}
}
-/* This functions only reads appropriate amount of data from *p
- * and returns the resulting value. Calling function must handle
- * different encoding possibilities itself! */
+/* Read the appropriate amount of data from *P and return the
+ resulting value based on ENCODING, which the calling function must
+ provide. */
static CORE_ADDR
-read_encoded_pointer (bfd * abfd, char **p, unsigned char encoding)
+read_encoded_pointer (bfd *abfd, char **p, unsigned char encoding)
{
CORE_ADDR ret;
default:
internal_error (__FILE__, __LINE__,
- "read_encoded_pointer: unknown pointer encoding");
+ "read_encoded_pointer: unknown pointer encoding [in module %s]",
+ bfd_get_filename (abfd));
}
return ret;
}
-/* Variable 'encoding' carries 3 different flags:
- * - encoding & 0x0f : size of the address (handled in read_encoded_pointer())
- * - encoding & 0x70 : type (absolute, relative, ...)
- * - encoding & 0x80 : indirect flag (DW_EH_PE_indirect == 0x80). */
+/* The variable 'encoding' carries three different flags:
+ - encoding & 0x0f : size of the address (handled in read_encoded_pointer())
+ - encoding & 0x70 : type (absolute, relative, ...)
+ - encoding & 0x80 : indirect flag (DW_EH_PE_indirect == 0x80). */
enum ptr_encoding
-pointer_encoding (unsigned char encoding)
+pointer_encoding (unsigned char encoding, struct objfile *objfile)
{
int ret;
if (encoding & DW_EH_PE_indirect)
- warning ("CFI: Unsupported pointer encoding: DW_EH_PE_indirect");
+ warning
+ ("CFI: Unsupported pointer encoding: DW_EH_PE_indirect [in module %s]",
+ objfile->name);
switch (encoding & 0x70)
{
ret = encoding & 0x70;
break;
default:
- internal_error (__FILE__, __LINE__, "CFI: unknown pointer encoding");
+ internal_error (__FILE__, __LINE__,
+ "CFI: unknown pointer encoding [in module %s]",
+ objfile->name);
}
return ret;
}
static LONGEST
-read_initial_length (bfd * abfd, char *buf, int *bytes_read)
+read_initial_length (bfd *abfd, char *buf, int *bytes_read)
{
LONGEST ret = 0;
}
static ULONGEST
-read_length (bfd * abfd, char *buf, int *bytes_read, int dwarf64)
+read_length (bfd *abfd, char *buf, int *bytes_read, int dwarf64)
{
if (dwarf64)
{
fs->pc = read_encoded_pointer (objfile->obfd, &insn_ptr,
fs->addr_encoding);
- if (pointer_encoding (fs->addr_encoding) != PE_absptr)
- warning ("CFI: DW_CFA_set_loc uses relative addressing");
+ if (pointer_encoding (fs->addr_encoding, objfile) != PE_absptr)
+ warning
+ ("CFI: DW_CFA_set_loc uses relative addressing [in module %s]",
+ objfile->name);
break;
break;
default:
- error ("dwarf cfi error: unknown cfa instruction %d.", insn);
+ error
+ ("dwarf cfi error: unknown cfa instruction %d [in module %s]",
+ insn, objfile->name);
}
}
}
gdb_assert (fde->cie_ptr != NULL);
cie = fde->cie_ptr;
-
+
fs->code_align = cie->code_align;
fs->data_align = cie->data_align;
fs->retaddr_column = cie->ra;
fs->addr_encoding = cie->addr_encoding;
fs->objfile = cie->objfile;
-
+
execute_cfa_program (cie->objfile, cie->data,
cie->data + cie->data_length, context, fs);
execute_cfa_program (cie->objfile, fde->data,
switch (context->reg[regnum].how)
{
case REG_CTX_UNSAVED:
- read_register_gen (regnum, reg);
+ deprecated_read_register_gen (regnum, reg);
break;
case REG_CTX_SAVED_OFFSET:
target_read_memory (context->cfa + context->reg[regnum].loc.offset,
reg, REGISTER_RAW_SIZE (regnum));
break;
case REG_CTX_SAVED_REG:
- read_register_gen (context->reg[regnum].loc.reg, reg);
+ deprecated_read_register_gen (context->reg[regnum].loc.reg, reg);
break;
case REG_CTX_SAVED_ADDR:
target_read_memory (context->reg[regnum].loc.addr,
case DW_OP_dup:
if (stack_elt < 1)
- internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ internal_error (__FILE__, __LINE__,
+ "execute_stack_op error [in module %s]",
+ objfile->name);
result = stack[stack_elt - 1];
break;
case DW_OP_drop:
if (--stack_elt < 0)
- internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ internal_error (__FILE__, __LINE__,
+ "execute_stack_op error [in module %s]",
+ objfile->name);
goto no_push;
case DW_OP_pick:
offset = *op_ptr++;
if (offset >= stack_elt - 1)
- internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ internal_error (__FILE__, __LINE__,
+ "execute_stack_op error [in module %s]",
+ objfile->name);
result = stack[stack_elt - 1 - offset];
break;
case DW_OP_over:
if (stack_elt < 2)
- internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ internal_error (__FILE__, __LINE__,
+ "execute_stack_op error [in module %s]",
+ objfile->name);
result = stack[stack_elt - 2];
break;
CORE_ADDR t1, t2, t3;
if (stack_elt < 3)
- internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ internal_error (__FILE__, __LINE__,
+ "execute_stack_op error [in module %s]",
+ objfile->name);
t1 = stack[stack_elt - 1];
t2 = stack[stack_elt - 2];
t3 = stack[stack_elt - 3];
case DW_OP_plus_uconst:
/* Unary operations. */
if (--stack_elt < 0)
- internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ internal_error (__FILE__, __LINE__,
+ "execute_stack_op error [in module %s]",
+ objfile->name);
result = stack[stack_elt];
switch (op)
int len = TARGET_ADDR_BIT / TARGET_CHAR_BIT;
if (len != 4 && len != 8)
internal_error (__FILE__, __LINE__,
- "execute_stack_op error");
+ "execute_stack_op error [in module %s]",
+ objfile->name);
result = read_memory_unsigned_integer (result, len);
}
break;
case DW_OP_deref_size:
{
int len = *op_ptr++;
- if (len != 1 && len != 2 && len != 4 && len !=8)
+ if (len != 1 && len != 2 && len != 4 && len != 8)
internal_error (__FILE__, __LINE__,
- "execute_stack_op error");
+ "execute_stack_op error [in module %s]",
+ objfile->name);
result = read_memory_unsigned_integer (result, len);
}
break;
/* Binary operations. */
CORE_ADDR first, second;
if ((stack_elt -= 2) < 0)
- internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ internal_error (__FILE__, __LINE__,
+ "execute_stack_op error [in module %s]",
+ objfile->name);
second = stack[stack_elt];
first = stack[stack_elt + 1];
result = (LONGEST) first != (LONGEST) second;
break;
default:
- error ("execute_stack_op: Unknown DW_OP_ value");
+ error
+ ("execute_stack_op: Unknown DW_OP_ value [in module %s]",
+ objfile->name);
break;
}
}
case DW_OP_bra:
if (--stack_elt < 0)
- internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ internal_error (__FILE__, __LINE__,
+ "execute_stack_op error [in module %s]",
+ objfile->name);
offset = read_2s (objfile->obfd, &op_ptr);
if (stack[stack_elt] != 0)
op_ptr += offset;
goto no_push;
default:
- internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ internal_error (__FILE__, __LINE__,
+ "execute_stack_op error [in module %s]",
+ objfile->name);
}
/* Most things push a result value. */
if ((size_t) stack_elt >= sizeof (stack) / sizeof (*stack))
- internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ internal_error (__FILE__, __LINE__,
+ "execute_stack_op error [in module %s]",
+ objfile->name);
stack[++stack_elt] = result;
no_push:;
}
/* We were executing this program to get a value. It should be
at top of stack. */
if (--stack_elt < 0)
- internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ internal_error (__FILE__, __LINE__,
+ "execute_stack_op error [in module %s]", objfile->name);
return stack[stack_elt];
}
orig_context->reg[fs->regs.reg[i].loc.reg].loc.addr;
break;
default:
- internal_error (__FILE__, __LINE__, "bad switch");
+ internal_error (__FILE__, __LINE__, "bad switch 0x%02X",
+ orig_context->reg[fs->regs.reg[i].loc.reg].how);
}
break;
case REG_SAVED_EXP:
}
break;
default:
- internal_error (__FILE__, __LINE__, "bad switch");
+ internal_error (__FILE__, __LINE__, "bad switch 0x%02X",
+ fs->regs.reg[i].how);
}
get_reg ((char *) &context->ra, context, fs->retaddr_column);
unwind_tmp_obstack_free ();
-- mludvig */
static void
parse_frame_info (struct objfile *objfile, file_ptr frame_offset,
- unsigned int frame_size, int eh_frame)
+ unsigned int frame_size, asection *frame_section,
+ int eh_frame)
{
bfd *abfd = objfile->obfd;
asection *curr_section_ptr;
unwind_tmp_obstack_init ();
- frame_buffer = dwarf2_read_section (objfile, frame_offset, frame_size);
+ frame_buffer = dwarf2_read_section (objfile, frame_offset, frame_size,
+ frame_section);
start = frame_buffer;
end = frame_buffer + frame_size;
cie = cie->next;
}
if (!cie)
- error ("CFI: can't find CIE pointer");
+ error ("CFI: can't find CIE pointer [in module %s]",
+ bfd_get_filename (abfd));
}
init_loc = read_encoded_pointer (abfd, &start,
cie->addr_encoding);
- switch (pointer_encoding (cie->addr_encoding))
+ switch (pointer_encoding (cie->addr_encoding, objfile))
{
case PE_absptr:
break;
init_loc += curr_section_vma + start - frame_buffer;
break;
default:
- warning ("CFI: Unsupported pointer encoding\n");
+ warning ("CFI: Unsupported pointer encoding [in module %s]",
+ bfd_get_filename (abfd));
}
/* For relocatable objects we must add an offset telling
if (dwarf_frame_offset)
{
parse_frame_info (objfile, dwarf_frame_offset,
- dwarf_frame_size, 0 /* = debug_frame */ );
+ dwarf_frame_size, dwarf_frame_section,
+ 0 /* = debug_frame */ );
after_debug_frame = 1;
}
if (dwarf_eh_frame_offset)
parse_frame_info (objfile, dwarf_eh_frame_offset, dwarf_eh_frame_size,
+ dwarf_eh_frame_section,
1 /* = eh_frame */ + after_debug_frame);
}
if (fs->cfa_how == CFA_REG_OFFSET)
{
val -= fs->cfa_offset;
- write_register_gen (fs->cfa_reg, (char *) &val);
+ deprecated_write_register_gen (fs->cfa_reg, (char *) &val);
}
else
warning ("Can't write fp.");
void
cfi_pop_frame (struct frame_info *fi)
{
- char *regbuf = alloca (MAX_REGISTER_RAW_SIZE);
+ char regbuf[MAX_REGISTER_SIZE];
int regnum;
for (regnum = 0; regnum < NUM_REGS; regnum++)
{
get_reg (regbuf, UNWIND_CONTEXT (fi), regnum);
- write_register_bytes (REGISTER_BYTE (regnum), regbuf,
- REGISTER_RAW_SIZE (regnum));
+ deprecated_write_register_bytes (REGISTER_BYTE (regnum), regbuf,
+ REGISTER_RAW_SIZE (regnum));
}
write_register (PC_REGNUM, UNWIND_CONTEXT (fi)->ra);
}
/* Sets the pc of the frame. */
-void
+CORE_ADDR
cfi_init_frame_pc (int fromleaf, struct frame_info *fi)
{
- if (fi->next)
- get_reg ((char *) &(fi->pc), UNWIND_CONTEXT (fi->next), PC_REGNUM);
+ if (get_next_frame (fi))
+ {
+ CORE_ADDR pc;
+ /* FIXME: cagney/2002-12-04: This is straight wrong. It's
+ assuming that the PC is CORE_ADDR (a host quantity) in size. */
+ get_reg ((void *) &pc, UNWIND_CONTEXT (get_next_frame (fi)), PC_REGNUM);
+ return pc;
+ }
else
- fi->pc = read_pc ();
+ return read_pc ();
}
/* Initialize unwind context informations of the frame. */
unwind_tmp_obstack_init ();
fs = frame_state_alloc ();
- fi->context = frame_obstack_alloc (sizeof (struct context));
+ deprecated_set_frame_context (fi,
+ frame_obstack_zalloc (sizeof
+ (struct context)));
UNWIND_CONTEXT (fi)->reg =
- frame_obstack_alloc (sizeof (struct context_reg) * NUM_REGS);
+ frame_obstack_zalloc (sizeof (struct context_reg) * NUM_REGS);
memset (UNWIND_CONTEXT (fi)->reg, 0,
sizeof (struct context_reg) * NUM_REGS);
- if (fi->next)
+ if (get_next_frame (fi))
{
- context_cpy (UNWIND_CONTEXT (fi), UNWIND_CONTEXT (fi->next));
+ context_cpy (UNWIND_CONTEXT (fi), UNWIND_CONTEXT (get_next_frame (fi)));
frame_state_for (UNWIND_CONTEXT (fi), fs);
update_context (UNWIND_CONTEXT (fi), fs, 1);
}
else
{
- UNWIND_CONTEXT (fi)->ra = fi->pc + 1;
+ UNWIND_CONTEXT (fi)->ra = get_frame_pc (fi) + 1;
frame_state_for (UNWIND_CONTEXT (fi), fs);
update_context (UNWIND_CONTEXT (fi), fs, 0);
}
if (addrp) /* default assumption: not found in memory */
*addrp = 0;
- if (!frame->next)
+ if (!get_next_frame (frame))
{
- read_register_gen (regnum, raw_buffer);
+ deprecated_read_register_gen (regnum, raw_buffer);
if (lval != NULL)
*lval = lval_register;
if (addrp != NULL)
}
else
{
- frame = frame->next;
+ frame = get_next_frame (frame);
switch (UNWIND_CONTEXT (frame)->reg[regnum].how)
{
case REG_CTX_UNSAVED:
- read_register_gen (regnum, raw_buffer);
+ deprecated_read_register_gen (regnum, raw_buffer);
if (lval != NULL)
*lval = not_lval;
if (optimized != NULL)
UNWIND_CONTEXT (frame)->reg[regnum].loc.offset;
break;
case REG_CTX_SAVED_REG:
- read_register_gen (UNWIND_CONTEXT (frame)->reg[regnum].loc.reg,
- raw_buffer);
+ deprecated_read_register_gen (UNWIND_CONTEXT (frame)->reg[regnum].
+ loc.reg, raw_buffer);
if (lval != NULL)
*lval = lval_register;
if (addrp != NULL)
break;
default:
internal_error (__FILE__, __LINE__,
- "cfi_get_saved_register: unknown register rule");
+ "cfi_get_saved_register: unknown register rule 0x%02X",
+ UNWIND_CONTEXT (frame)->reg[regnum].how);
}
}
}