This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[5.2.1] huge patch
- From: Michal Ludvig <mludvig at suse dot cz>
- To: gdb-patches at sources dot redhat dot com
- Date: Tue, 02 Jul 2002 15:45:05 +0200
- Subject: [5.2.1] huge patch
- Organization: SuSE CR
Hi all,
this pretty huge one includes all commits to mainline for almost a month
ago for x86-64 port. There is nothing new, only already used things.
FYI It compiles and works and it doesn't touch non-x86-64 parts at all.
Can I commit it to 5.2 branch?
Michal Ludvig
--
* SuSE CR, s.r.o * mludvig@suse.cz
* +420 2 9654 5373 * http://www.suse.cz
Index: ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/ChangeLog,v
retrieving revision 1.2298.2.56
diff -c -3 -p -r1.2298.2.56 ChangeLog
*** ChangeLog 22 Jun 2002 16:49:31 -0000 1.2298.2.56
--- ChangeLog 27 Jun 2002 12:43:02 -0000
***************
*** 1,3 ****
--- 1,48 ----
+ 2002-06-27 Michal Ludvig <mludvig@suse.cz>
+
+ Merge from mainline:
+
+ 2002-06-21 Michal Ludvig <mludvig@suse.cz>
+ * dwarf2cfi.c (read_encoded_pointer): Don't handle pointer
+ encoding anymore.
+ (pointer_encoding, enum ptr_encoding): New.
+ (execute_cfa_program): Take care about pointer encoding.
+ (dwarf2_build_frame_info): Only call parse_frame_info for
+ .debug_frame and .eh_frame.
+ (parse_frame_info): New, derived from former dwarf2_build_frame_info.
+ fixed augmentation handling, added relative addressing,
+ ignore duplicate FDEs. Added comments.
+ * dwarf2cfi.c: Reindented.
+
+ 2002-06-20 Michal Ludvig <mludvig@suse.cz>
+ * x86-64-tdep.c (x86_64_register_nr2name): Rename to
+ x86_64_register_name. Return type changed to 'const char *'.
+ (x86_64_register_name2nr): Rename to x86_64_register_number.
+ (x86_64_gdbarch_init): Update to reflect the change.
+ * x86-64-tdep.h: Ditto.
+ * x86-64-linux-nat.c (x86_64_fxsave_offset)
+ (supply_fpregset): Ditto.
+
+ 2002-06-11 Michal Ludvig <mludvig@suse.cz>
+ * dwarf2cfi.c (unwind_tmp_obstack_init): New.
+ (unwind_tmp_obstack_free, parse_frame_info)
+ (update_context, cfi_read_fp, cfi_write_fp)
+ (cfi_frame_chain, cfi_init_extra_frame_info)
+ (cfi_virtual_frame_pointer): Use the above function.
+ * x86-64-tdep.c (x86_64_skip_prologue): Fix to work on functions
+ without debug information too.
+
+ 2002-06-07 Michal Ludvig <mludvig@suse.cz>
+ * x86-64-linux-nat.c (x86_64_fxsave_offset): New.
+ (supply_fpregset, fill_fpregset): Don't call i387_*_fxsave,
+ better do the things actually here.
+ * x86-64-tdep.c (x86_64_register_name2nr): New.
+ (x86_64_register_name): Renamed to x86_64_register_nr2name.
+ (x86_64_gdbarch_init): Respect the above change.
+ * x86-64-tdep.h (x86_64_register_name2nr)
+ (x86_64_register_nr2name): Add prototypes.
+ * config/i386/x86-64linux.mt (TDEPFILES): Remove i387-tdep.o.
+
2002-06-22 Andrew Cagney <ac131313@redhat.com>
* NEWS: Mention below.
Index: dwarf2cfi.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2cfi.c,v
retrieving revision 1.1.2.4
diff -c -3 -p -r1.1.2.4 dwarf2cfi.c
*** dwarf2cfi.c 22 May 2002 13:23:23 -0000 1.1.2.4
--- dwarf2cfi.c 27 Jun 2002 12:43:02 -0000
***************
*** 34,40 ****
Frame Descriptors. */
struct cie_unit
{
! /* Offset of this unit in dwarf_frame_buffer. */
ULONGEST offset;
/* A null-terminated string that identifies the augmentation to this CIE or
--- 34,40 ----
Frame Descriptors. */
struct cie_unit
{
! /* Offset of this unit in .debug_frame or .eh_frame. */
ULONGEST offset;
/* A null-terminated string that identifies the augmentation to this CIE or
*************** struct frame_state
*** 176,181 ****
--- 176,190 ----
struct objfile *objfile;
};
+ enum ptr_encoding
+ {
+ PE_absptr = DW_EH_PE_absptr,
+ PE_pcrel = DW_EH_PE_pcrel,
+ PE_textrel = DW_EH_PE_textrel,
+ PE_datarel = DW_EH_PE_datarel,
+ PE_funcrel = DW_EH_PE_funcrel
+ };
+
#define UNWIND_CONTEXT(fi) ((struct context *) (fi->context))
*************** extern file_ptr dwarf_frame_offset;
*** 188,195 ****
extern unsigned int dwarf_frame_size;
extern file_ptr dwarf_eh_frame_offset;
extern unsigned int dwarf_eh_frame_size;
-
- static char *dwarf_frame_buffer;
extern char *dwarf2_read_section (struct objfile *objfile, file_ptr offset,
--- 197,202 ----
*************** static void fde_chunks_need_space ();
*** 201,226 ****
static struct context *context_alloc ();
static struct frame_state *frame_state_alloc ();
static void unwind_tmp_obstack_free ();
static void context_cpy (struct context *dst, struct context *src);
! 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 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);
--- 208,235 ----
static struct context *context_alloc ();
static struct frame_state *frame_state_alloc ();
+ static void unwind_tmp_obstack_init ();
static void unwind_tmp_obstack_free ();
static void context_cpy (struct context *dst, struct context *src);
! 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 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);
*************** static void frame_state_for (struct cont
*** 235,245 ****
static void get_reg (char *reg, struct context *context, int regnum);
static CORE_ADDR execute_stack_op (struct objfile *objfile,
char *op_ptr, char *op_end,
! struct context *context, CORE_ADDR initial);
static void update_context (struct context *context, struct frame_state *fs,
int chain);
-
/* Memory allocation functions. */
static struct fde_unit *
fde_unit_alloc (void)
--- 244,255 ----
static void get_reg (char *reg, struct context *context, int regnum);
static CORE_ADDR execute_stack_op (struct objfile *objfile,
char *op_ptr, char *op_end,
! struct context *context,
! CORE_ADDR initial);
static void update_context (struct context *context, struct frame_state *fs,
int chain);
+
/* Memory allocation functions. */
static struct fde_unit *
fde_unit_alloc (void)
*************** frame_state_alloc ()
*** 301,317 ****
fs = (struct frame_state *) obstack_alloc (&unwind_tmp_obstack,
sizeof (struct frame_state));
memset (fs, 0, sizeof (struct frame_state));
! fs->regs.reg = (struct frame_state_reg *) obstack_alloc (&unwind_tmp_obstack,
! regs_size);
memset (fs->regs.reg, 0, regs_size);
return fs;
}
static void
unwind_tmp_obstack_free ()
{
obstack_free (&unwind_tmp_obstack, NULL);
! obstack_init (&unwind_tmp_obstack);
}
static void
--- 311,333 ----
fs = (struct frame_state *) obstack_alloc (&unwind_tmp_obstack,
sizeof (struct frame_state));
memset (fs, 0, sizeof (struct frame_state));
! fs->regs.reg =
! (struct frame_state_reg *) obstack_alloc (&unwind_tmp_obstack, regs_size);
memset (fs->regs.reg, 0, regs_size);
return fs;
}
static void
+ unwind_tmp_obstack_init ()
+ {
+ obstack_init (&unwind_tmp_obstack);
+ }
+
+ static void
unwind_tmp_obstack_free ()
{
obstack_free (&unwind_tmp_obstack, NULL);
! unwind_tmp_obstack_init ();
}
static void
*************** context_cpy (struct context *dst, struct
*** 334,425 ****
dreg = dst->reg;
*dst = *src;
dst->reg = dreg;
!
memcpy (dst->reg, src->reg, regs_size);
}
static unsigned int
! read_1u (bfd *abfd, char **p)
{
unsigned ret;
! ret= bfd_get_8 (abfd, (bfd_byte *) *p);
! (*p) ++;
return ret;
}
static int
! read_1s (bfd *abfd, char **p)
{
int ret;
! ret= bfd_get_signed_8 (abfd, (bfd_byte *) *p);
! (*p) ++;
return ret;
}
static unsigned int
! read_2u (bfd *abfd, char **p)
{
unsigned ret;
! ret= bfd_get_16 (abfd, (bfd_byte *) *p);
! (*p) ++;
return ret;
}
static int
! read_2s (bfd *abfd, char **p)
{
int ret;
! ret= bfd_get_signed_16 (abfd, (bfd_byte *) *p);
(*p) += 2;
return ret;
}
static unsigned int
! read_4u (bfd *abfd, char **p)
{
unsigned int ret;
! ret= bfd_get_32 (abfd, (bfd_byte *) *p);
(*p) += 4;
return ret;
}
static int
! read_4s (bfd *abfd, char **p)
{
int ret;
! ret= bfd_get_signed_32 (abfd, (bfd_byte *) *p);
(*p) += 4;
return ret;
}
static ULONGEST
! read_8u (bfd *abfd, char **p)
{
ULONGEST ret;
! ret = bfd_get_64 (abfd, (bfd_byte *) *p);
(*p) += 8;
return ret;
}
static LONGEST
! read_8s (bfd *abfd, char **p)
{
LONGEST ret;
! ret = bfd_get_signed_64 (abfd, (bfd_byte *) *p);
(*p) += 8;
return ret;
}
static ULONGEST
! read_uleb128 (bfd *abfd, char **p)
{
ULONGEST ret;
int i, shift;
--- 350,441 ----
dreg = dst->reg;
*dst = *src;
dst->reg = dreg;
!
memcpy (dst->reg, src->reg, regs_size);
}
static unsigned int
! read_1u (bfd * abfd, char **p)
{
unsigned ret;
! ret = bfd_get_8 (abfd, (bfd_byte *) * p);
! (*p)++;
return ret;
}
static int
! read_1s (bfd * abfd, char **p)
{
int ret;
! ret = bfd_get_signed_8 (abfd, (bfd_byte *) * p);
! (*p)++;
return ret;
}
static unsigned int
! read_2u (bfd * abfd, char **p)
{
unsigned ret;
! ret = bfd_get_16 (abfd, (bfd_byte *) * p);
! (*p)++;
return ret;
}
static int
! read_2s (bfd * abfd, char **p)
{
int ret;
! ret = bfd_get_signed_16 (abfd, (bfd_byte *) * p);
(*p) += 2;
return ret;
}
static unsigned int
! read_4u (bfd * abfd, char **p)
{
unsigned int ret;
! ret = bfd_get_32 (abfd, (bfd_byte *) * p);
(*p) += 4;
return ret;
}
static int
! read_4s (bfd * abfd, char **p)
{
int ret;
! ret = bfd_get_signed_32 (abfd, (bfd_byte *) * p);
(*p) += 4;
return ret;
}
static ULONGEST
! read_8u (bfd * abfd, char **p)
{
ULONGEST ret;
! ret = bfd_get_64 (abfd, (bfd_byte *) * p);
(*p) += 8;
return ret;
}
static LONGEST
! read_8s (bfd * abfd, char **p)
{
LONGEST ret;
! ret = bfd_get_signed_64 (abfd, (bfd_byte *) * p);
(*p) += 8;
return ret;
}
static ULONGEST
! read_uleb128 (bfd * abfd, char **p)
{
ULONGEST ret;
int i, shift;
*************** read_uleb128 (bfd *abfd, char **p)
*** 430,437 ****
i = 0;
while (1)
{
! byte = bfd_get_8 (abfd, (bfd_byte *) *p);
! (*p) ++;
ret |= ((unsigned long) (byte & 127) << shift);
if ((byte & 128) == 0)
{
--- 446,453 ----
i = 0;
while (1)
{
! byte = bfd_get_8 (abfd, (bfd_byte *) * p);
! (*p)++;
ret |= ((unsigned long) (byte & 127) << shift);
if ((byte & 128) == 0)
{
*************** read_uleb128 (bfd *abfd, char **p)
*** 443,449 ****
}
static LONGEST
! read_sleb128 (bfd *abfd, char **p)
{
LONGEST ret;
int i, shift, size, num_read;
--- 459,465 ----
}
static LONGEST
! read_sleb128 (bfd * abfd, char **p)
{
LONGEST ret;
int i, shift, size, num_read;
*************** read_sleb128 (bfd *abfd, char **p)
*** 456,463 ****
i = 0;
while (1)
{
! byte = bfd_get_8 (abfd, (bfd_byte *) *p);
! (*p) ++;
ret |= ((long) (byte & 127) << shift);
shift += 7;
if ((byte & 128) == 0)
--- 472,479 ----
i = 0;
while (1)
{
! byte = bfd_get_8 (abfd, (bfd_byte *) * p);
! (*p)++;
ret |= ((long) (byte & 127) << shift);
shift += 7;
if ((byte & 128) == 0)
*************** read_sleb128 (bfd *abfd, char **p)
*** 473,479 ****
}
static CORE_ADDR
! read_pointer (bfd *abfd, char **p)
{
switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
{
--- 489,495 ----
}
static CORE_ADDR
! read_pointer (bfd * abfd, char **p)
{
switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
{
*************** read_pointer (bfd *abfd, char **p)
*** 486,493 ****
}
}
static CORE_ADDR
! read_encoded_pointer (bfd *abfd, char **p, unsigned char encoding)
{
CORE_ADDR ret;
--- 502,512 ----
}
}
+ /* This functions only reads appropriate amount of data from *p
+ * and returns the resulting value. Calling function must handle
+ * different encoding possibilities itself! */
static CORE_ADDR
! read_encoded_pointer (bfd * abfd, char **p, unsigned char encoding)
{
CORE_ADDR ret;
*************** read_encoded_pointer (bfd *abfd, char **
*** 529,550 ****
"read_encoded_pointer: unknown pointer encoding");
}
! if (ret != 0)
! switch (encoding & 0xf0)
! {
! case DW_EH_PE_absptr:
! break;
! case DW_EH_PE_pcrel:
! ret += (CORE_ADDR) *p;
! break;
! case DW_EH_PE_textrel:
! case DW_EH_PE_datarel:
! case DW_EH_PE_funcrel:
! default:
! internal_error (__FILE__, __LINE__,
! "read_encoded_pointer: unknown pointer encoding");
! }
return ret;
}
--- 548,580 ----
"read_encoded_pointer: unknown pointer encoding");
}
! 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). */
+ enum ptr_encoding
+ pointer_encoding (unsigned char encoding)
+ {
+ int ret;
+
+ if (encoding & DW_EH_PE_indirect)
+ warning ("CFI: Unsupported pointer encoding: DW_EH_PE_indirect");
+
+ switch (encoding & 0x70)
+ {
+ case DW_EH_PE_absptr:
+ case DW_EH_PE_pcrel:
+ case DW_EH_PE_textrel:
+ case DW_EH_PE_datarel:
+ case DW_EH_PE_funcrel:
+ ret = encoding & 0x70;
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "CFI: unknown pointer encoding");
+ }
return ret;
}
*************** read_length (bfd * abfd, char *buf, int
*** 584,591 ****
}
static void
! execute_cfa_program ( struct objfile *objfile, char *insn_ptr, char *insn_end,
! struct context *context, struct frame_state *fs)
{
struct frame_state_regs *unused_rs = NULL;
--- 614,621 ----
}
static void
! execute_cfa_program (struct objfile *objfile, char *insn_ptr, char *insn_end,
! struct context *context, struct frame_state *fs)
{
struct frame_state_regs *unused_rs = NULL;
*************** execute_cfa_program ( struct objfile *ob
*** 604,610 ****
{
reg = insn & 0x3f;
uoffset = read_uleb128 (objfile->obfd, &insn_ptr);
! offset = (long) uoffset * fs->data_align;
fs->regs.reg[reg].how = REG_SAVED_OFFSET;
fs->regs.reg[reg].loc.offset = offset;
}
--- 634,640 ----
{
reg = insn & 0x3f;
uoffset = read_uleb128 (objfile->obfd, &insn_ptr);
! offset = (long) uoffset *fs->data_align;
fs->regs.reg[reg].how = REG_SAVED_OFFSET;
fs->regs.reg[reg].loc.offset = offset;
}
*************** execute_cfa_program ( struct objfile *ob
*** 619,624 ****
--- 649,658 ----
case DW_CFA_set_loc:
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");
+
break;
case DW_CFA_advance_loc1:
*************** frame_state_for (struct context *context
*** 806,818 ****
if (fde == NULL)
return;
!
fs->pc = fde->initial_location;
if (fde->cie_ptr)
! {
cie = fde->cie_ptr;
!
fs->code_align = cie->code_align;
fs->data_align = cie->data_align;
fs->retaddr_column = cie->ra;
--- 840,852 ----
if (fde == NULL)
return;
!
fs->pc = fde->initial_location;
if (fde->cie_ptr)
! {
cie = fde->cie_ptr;
!
fs->code_align = cie->code_align;
fs->data_align = cie->data_align;
fs->retaddr_column = cie->ra;
*************** frame_state_for (struct context *context
*** 823,833 ****
cie->data + cie->data_length, context, fs);
execute_cfa_program (cie->objfile, fde->data,
fde->data + fde->data_length, context, fs);
! }
else
! internal_error (__FILE__, __LINE__,
! "%s(): Internal error: fde->cie_ptr==NULL !",
! __func__);
}
static void
--- 857,866 ----
cie->data + cie->data_length, context, fs);
execute_cfa_program (cie->objfile, fde->data,
fde->data + fde->data_length, context, fs);
! }
else
! internal_error (__FILE__, __LINE__,
! "%s(): Internal error: fde->cie_ptr==NULL !", __func__);
}
static void
*************** get_reg (char *reg, struct context *cont
*** 854,861 ****
REGISTER_RAW_SIZE (regnum));
break;
default:
! internal_error (__FILE__, __LINE__,
! "get_reg: unknown register rule");
}
}
--- 887,893 ----
REGISTER_RAW_SIZE (regnum));
break;
default:
! internal_error (__FILE__, __LINE__, "get_reg: unknown register rule");
}
}
*************** execute_stack_op (struct objfile *objfil
*** 1208,1215 ****
case DW_OP_ne:
result = (LONGEST) first != (LONGEST) second;
break;
! default: /* This label is here just to avoid warning. */
! break;
}
}
break;
--- 1240,1247 ----
case DW_OP_ne:
result = (LONGEST) first != (LONGEST) second;
break;
! default: /* This label is here just to avoid warning. */
! break;
}
}
break;
*************** update_context (struct context *context,
*** 1255,1262 ****
--- 1287,1297 ----
CORE_ADDR cfa;
long i;
+ unwind_tmp_obstack_init ();
+
orig_context = context_alloc ();
context_cpy (orig_context, context);
+
/* Compute this frame's CFA. */
switch (fs->cfa_how)
{
*************** update_context (struct context *context,
*** 1267,1275 ****
case CFA_EXP:
/* ??? No way of knowing what register number is the stack pointer
! to do the same sort of handling as above. Assume that if the
! CFA calculation is so complicated as to require a stack program
! that this will not be a problem. */
{
char *exp = fs->cfa_exp;
ULONGEST len;
--- 1302,1310 ----
case CFA_EXP:
/* ??? No way of knowing what register number is the stack pointer
! to do the same sort of handling as above. Assume that if the
! CFA calculation is so complicated as to require a stack program
! that this will not be a problem. */
{
char *exp = fs->cfa_exp;
ULONGEST len;
*************** compare_fde_unit (const void *a, const v
*** 1371,1409 ****
}
/* Build the cie_chunks and fde_chunks tables from informations
! in .debug_frame section. */
! void
! dwarf2_build_frame_info (struct objfile *objfile)
{
bfd *abfd = objfile->obfd;
char *start = NULL;
char *end = NULL;
! int from_eh = 0;
!
! obstack_init (&unwind_tmp_obstack);
!
! dwarf_frame_buffer = 0;
!
! if (dwarf_frame_offset)
! {
! dwarf_frame_buffer = dwarf2_read_section (objfile,
! dwarf_frame_offset,
! dwarf_frame_size);
!
! start = dwarf_frame_buffer;
! end = dwarf_frame_buffer + dwarf_frame_size;
! }
! else if (dwarf_eh_frame_offset)
! {
! dwarf_frame_buffer = dwarf2_read_section (objfile,
! dwarf_eh_frame_offset,
! dwarf_eh_frame_size);
!
! start = dwarf_frame_buffer;
! end = dwarf_frame_buffer + dwarf_eh_frame_size;
!
! from_eh = 1;
! }
if (start)
{
--- 1406,1451 ----
}
/* Build the cie_chunks and fde_chunks tables from informations
! found in .debug_frame and .eh_frame sections. */
! /* We can handle both of these sections almost in the same way, however there
! are some exceptions:
! - CIE ID is -1 in debug_frame, but 0 in eh_frame
! - eh_frame may contain some more information that are used only by gcc
! (eg. personality pointer, LSDA pointer, ...). Most of them we can ignore.
! - In debug_frame FDE's item cie_id contains offset of it's parent CIE.
! In eh_frame FDE's item cie_id is a relative pointer to the parent CIE.
! Anyway we don't need to bother with this, because we are smart enough
! to keep the pointer to the parent CIE of oncomming FDEs in 'last_cie'.
! - Although debug_frame items can contain Augmentation as well as
! eh_frame ones, I have never seen them non-empty. Thus only in eh_frame
! we can encounter for example non-absolute pointers (Aug. 'R').
! -- mludvig */
! static void
! parse_frame_info (struct objfile *objfile, file_ptr frame_offset,
! unsigned int frame_size, int eh_frame)
{
bfd *abfd = objfile->obfd;
+ asection *curr_section_ptr;
char *start = NULL;
char *end = NULL;
! char *frame_buffer = NULL;
! char *curr_section_name, *aug_data;
! struct cie_unit *last_cie = NULL;
! int last_dup_fde = 0;
! int aug_len, i;
! CORE_ADDR curr_section_vma = 0;
!
! unwind_tmp_obstack_init ();
!
! frame_buffer = dwarf2_read_section (objfile, frame_offset, frame_size);
!
! start = frame_buffer;
! end = frame_buffer + frame_size;
!
! curr_section_name = eh_frame ? ".eh_frame" : ".debug_frame";
! curr_section_ptr = bfd_get_section_by_name (abfd, curr_section_name);
! if (curr_section_ptr)
! curr_section_vma = curr_section_ptr->vma;
if (start)
{
*************** dwarf2_build_frame_info (struct objfile
*** 1411,1419 ****
{
unsigned long length;
ULONGEST cie_id;
! ULONGEST unit_offset = start - dwarf_frame_buffer;
! int bytes_read;
! int dwarf64;
char *block_end;
length = read_initial_length (abfd, start, &bytes_read);
--- 1453,1460 ----
{
unsigned long length;
ULONGEST cie_id;
! ULONGEST unit_offset = start - frame_buffer;
! int bytes_read, dwarf64;
char *block_end;
length = read_initial_length (abfd, start, &bytes_read);
*************** dwarf2_build_frame_info (struct objfile
*** 1421,1430 ****
dwarf64 = (bytes_read == 12);
block_end = start + length;
cie_id = read_length (abfd, start, &bytes_read, dwarf64);
start += bytes_read;
! if ((from_eh && cie_id == 0) || is_cie (cie_id, dwarf64))
{
struct cie_unit *cie = cie_unit_alloc ();
char *aug;
--- 1462,1477 ----
dwarf64 = (bytes_read == 12);
block_end = start + length;
+ if (length == 0)
+ {
+ start = block_end;
+ continue;
+ }
+
cie_id = read_length (abfd, start, &bytes_read, dwarf64);
start += bytes_read;
! if ((eh_frame && cie_id == 0) || is_cie (cie_id, dwarf64))
{
struct cie_unit *cie = cie_unit_alloc ();
char *aug;
*************** dwarf2_build_frame_info (struct objfile
*** 1440,1523 ****
start++; /* version */
cie->augmentation = aug = start;
! while (*start)
! start++;
! start++; /* skip past NUL */
cie->code_align = read_uleb128 (abfd, &start);
cie->data_align = read_sleb128 (abfd, &start);
cie->ra = read_1u (abfd, &start);
if (*aug == 'z')
{
! int xtra = read_uleb128 (abfd, &start);
! start += xtra;
++aug;
}
while (*aug != '\0')
{
if (aug[0] == 'e' && aug[1] == 'h')
{
! start += sizeof (void *);
! aug += 2;
}
else if (aug[0] == 'R')
{
! cie->addr_encoding = *start++;
! aug += 1;
}
! else if (aug[0] == 'P')
{
! CORE_ADDR ptr;
! ptr = read_encoded_pointer (abfd, &start,
! cie->addr_encoding);
! aug += 1;
}
else
! warning ("%s(): unknown augmentation", __func__);
}
! cie->data = start;
! cie->data_length = block_end - start;
}
else
{
struct fde_unit *fde;
struct cie_unit *cie;
! fde_chunks_need_space ();
! fde = fde_unit_alloc ();
! fde_chunks.array[fde_chunks.elems++] = fde;
!
! fde->initial_location = read_pointer (abfd, &start)
! + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
! fde->address_range = read_pointer (abfd, &start);
! cie = cie_chunks;
! while(cie)
! {
! if (cie->objfile == objfile)
{
! if (from_eh && (cie->offset == (unit_offset + bytes_read - cie_id)))
! break;
! if (!from_eh && (cie->offset == cie_id))
! break;
}
! cie = cie->next;
! }
!
! if (!cie)
! error ("%s(): can't find CIE pointer", __func__);
! fde->cie_ptr = cie;
! if (cie->augmentation[0] == 'z')
! read_uleb128 (abfd, &start);
! fde->data = start;
! fde->data_length = block_end - start;
}
start = block_end;
}
--- 1487,1672 ----
start++; /* version */
cie->augmentation = aug = start;
! while (*start++); /* Skips last NULL as well */
cie->code_align = read_uleb128 (abfd, &start);
cie->data_align = read_sleb128 (abfd, &start);
cie->ra = read_1u (abfd, &start);
+ /* Augmentation:
+ z Indicates that a uleb128 is present to size the
+ augmentation section.
+ L Indicates the encoding (and thus presence) of
+ an LSDA pointer in the FDE augmentation.
+ R Indicates a non-default pointer encoding for
+ FDE code pointers.
+ P Indicates the presence of an encoding + language
+ personality routine in the CIE augmentation.
+
+ [This info comes from GCC's dwarf2out.c]
+ */
if (*aug == 'z')
{
! aug_len = read_uleb128 (abfd, &start);
! aug_data = start;
! start += aug_len;
++aug;
}
+ cie->data = start;
+ cie->data_length = block_end - cie->data;
+
while (*aug != '\0')
{
if (aug[0] == 'e' && aug[1] == 'h')
{
! aug_data += sizeof (void *);
! aug++;
}
else if (aug[0] == 'R')
+ cie->addr_encoding = *aug_data++;
+ else if (aug[0] == 'P')
{
! CORE_ADDR pers_addr;
! int pers_addr_enc;
!
! pers_addr_enc = *aug_data++;
! /* We don't need pers_addr value and so we
! don't care about it's encoding. */
! pers_addr = read_encoded_pointer (abfd, &aug_data,
! pers_addr_enc);
}
! else if (aug[0] == 'L' && eh_frame)
{
! int lsda_addr_enc;
!
! /* Perhaps we should save this to CIE for later use?
! Do we need it for something in GDB? */
! lsda_addr_enc = *aug_data++;
}
else
! warning ("CFI warning: unknown augmentation \"%c\""
! " in \"%s\" of\n"
! "\t%s", aug[0], curr_section_name,
! objfile->name);
! aug++;
}
! last_cie = cie;
}
else
{
struct fde_unit *fde;
struct cie_unit *cie;
+ int dup = 0;
+ CORE_ADDR init_loc;
! /* We assume that debug_frame is in order
! CIE,FDE,CIE,FDE,FDE,... and thus the CIE for this FDE
! should be stored in last_cie pointer. If not, we'll
! try to find it by the older way. */
! if (last_cie)
! cie = last_cie;
! else
! {
! warning ("CFI: last_cie == NULL. "
! "Perhaps a malformed %s section in '%s'...?\n",
! curr_section_name, objfile->name);
! cie = cie_chunks;
! while (cie)
! {
! if (cie->objfile == objfile)
! {
! if (eh_frame &&
! (cie->offset ==
! (unit_offset + bytes_read - cie_id)))
! break;
! if (!eh_frame && (cie->offset == cie_id))
! break;
! }
! cie = cie->next;
! }
! if (!cie)
! error ("CFI: can't find CIE pointer");
! }
!
! init_loc = read_encoded_pointer (abfd, &start,
! cie->addr_encoding);
!
! switch (pointer_encoding (cie->addr_encoding))
{
! case PE_absptr:
! break;
! case PE_pcrel:
! /* start-frame_buffer gives offset from
! the beginning of actual section. */
! init_loc += curr_section_vma + start - frame_buffer;
! break;
! default:
! warning ("CFI: Unsupported pointer encoding\n");
}
! /* For relocatable objects we must add an offset telling
! where the section is actually mapped in the memory. */
! init_loc += ANOFFSET (objfile->section_offsets,
! SECT_OFF_TEXT (objfile));
!
! /* If we have both .debug_frame and .eh_frame present in
! a file, we must eliminate duplicate FDEs. For now we'll
! run through all entries in fde_chunks and check it one
! by one. Perhaps in the future we can implement a faster
! searching algorithm. */
! /* eh_frame==2 indicates, that this file has an already
! parsed .debug_frame too. When eh_frame==1 it means, that no
! .debug_frame is present and thus we don't need to check for
! duplicities. eh_frame==0 means, that we parse .debug_frame
! and don't need to care about duplicate FDEs, because
! .debug_frame is parsed first. */
! if (eh_frame == 2)
! for (i = 0; eh_frame == 2 && i < fde_chunks.elems; i++)
! {
! /* We assume that FDEs in .debug_frame and .eh_frame
! have the same order (if they are present, of course).
! If we find a duplicate entry for one FDE and save
! it's index to last_dup_fde it's very likely, that
! we'll find an entry for the following FDE right after
! the previous one. Thus in many cases we'll run this
! loop only once. */
! last_dup_fde = (last_dup_fde + i) % fde_chunks.elems;
! if (fde_chunks.array[last_dup_fde]->initial_location
! == init_loc)
! {
! dup = 1;
! break;
! }
! }
! /* Allocate a new entry only if this FDE isn't a duplicate of
! something we have already seen. */
! if (!dup)
! {
! fde_chunks_need_space ();
! fde = fde_unit_alloc ();
!
! fde_chunks.array[fde_chunks.elems++] = fde;
!
! fde->initial_location = init_loc;
! fde->address_range = read_encoded_pointer (abfd, &start,
! cie->
! addr_encoding);
!
! fde->cie_ptr = cie;
! /* Here we intentionally ignore augmentation data
! from FDE, because we don't need them. */
! if (cie->augmentation[0] == 'z')
! start += read_uleb128 (abfd, &start);
!
! fde->data = start;
! fde->data_length = block_end - start;
! }
}
start = block_end;
}
*************** dwarf2_build_frame_info (struct objfile
*** 1525,1531 ****
sizeof (struct fde_unit *), compare_fde_unit);
}
}
!
/* Return the frame address. */
CORE_ADDR
--- 1674,1703 ----
sizeof (struct fde_unit *), compare_fde_unit);
}
}
!
! /* We must parse both .debug_frame section and .eh_frame because
! * not all frames must be present in both of these sections. */
! void
! dwarf2_build_frame_info (struct objfile *objfile)
! {
! int after_debug_frame = 0;
!
! /* If we have .debug_frame then the parser is called with
! eh_frame==0 for .debug_frame and eh_frame==2 for .eh_frame,
! otherwise it's only called once for .eh_frame with argument
! eh_frame==1. */
!
! if (dwarf_frame_offset)
! {
! parse_frame_info (objfile, dwarf_frame_offset,
! dwarf_frame_size, 0 /* = debug_frame */ );
! after_debug_frame = 1;
! }
!
! if (dwarf_eh_frame_offset)
! parse_frame_info (objfile, dwarf_eh_frame_offset, dwarf_eh_frame_size,
! 1 /* = eh_frame */ + after_debug_frame);
! }
/* Return the frame address. */
CORE_ADDR
*************** cfi_read_fp ()
*** 1535,1540 ****
--- 1707,1714 ----
struct frame_state *fs;
CORE_ADDR cfa;
+ unwind_tmp_obstack_init ();
+
context = context_alloc ();
fs = frame_state_alloc ();
*************** cfi_read_fp ()
*** 1544,1550 ****
--- 1718,1726 ----
update_context (context, fs, 0);
cfa = context->cfa;
+
unwind_tmp_obstack_free ();
+
return cfa;
}
*************** cfi_write_fp (CORE_ADDR val)
*** 1556,1561 ****
--- 1732,1739 ----
struct context *context;
struct frame_state *fs;
+ unwind_tmp_obstack_init ();
+
context = context_alloc ();
fs = frame_state_alloc ();
*************** cfi_frame_chain (struct frame_info *fi)
*** 1603,1608 ****
--- 1781,1788 ----
struct frame_state *fs;
CORE_ADDR cfa;
+ unwind_tmp_obstack_init ();
+
context = context_alloc ();
fs = frame_state_alloc ();
context_cpy (context, UNWIND_CONTEXT (fi));
*************** cfi_frame_chain (struct frame_info *fi)
*** 1619,1625 ****
cfa = context->cfa;
unwind_tmp_obstack_free ();
!
return cfa;
}
--- 1799,1805 ----
cfa = context->cfa;
unwind_tmp_obstack_free ();
!
return cfa;
}
*************** cfi_init_extra_frame_info (int fromleaf,
*** 1639,1644 ****
--- 1819,1826 ----
{
struct frame_state *fs;
+ unwind_tmp_obstack_init ();
+
fs = frame_state_alloc ();
fi->context = frame_obstack_alloc (sizeof (struct context));
UNWIND_CONTEXT (fi)->reg =
*************** cfi_init_extra_frame_info (int fromleaf,
*** 1658,1663 ****
--- 1840,1846 ----
frame_state_for (UNWIND_CONTEXT (fi), fs);
update_context (UNWIND_CONTEXT (fi), fs, 0);
}
+
unwind_tmp_obstack_free ();
}
*************** cfi_get_ra (struct frame_info *fi)
*** 1678,1684 ****
void
cfi_get_saved_register (char *raw_buffer,
int *optimized,
! CORE_ADDR * addrp,
struct frame_info *frame,
int regnum, enum lval_type *lval)
{
--- 1861,1867 ----
void
cfi_get_saved_register (char *raw_buffer,
int *optimized,
! CORE_ADDR *addrp,
struct frame_info *frame,
int regnum, enum lval_type *lval)
{
*************** cfi_virtual_frame_pointer (CORE_ADDR pc,
*** 1764,1769 ****
--- 1947,1954 ----
{
struct context *context;
struct frame_state *fs;
+
+ unwind_tmp_obstack_init ();
context = context_alloc ();
fs = frame_state_alloc ();
Index: x86-64-linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-linux-nat.c,v
retrieving revision 1.5.2.3
diff -c -3 -p -r1.5.2.3 x86-64-linux-nat.c
*** x86-64-linux-nat.c 10 Apr 2002 12:53:44 -0000 1.5.2.3
--- x86-64-linux-nat.c 27 Jun 2002 12:43:04 -0000
***************
*** 25,31 ****
#include "inferior.h"
#include "gdbcore.h"
#include "regcache.h"
- #include "i387-nat.h"
#include "gdb_assert.h"
#include "x86-64-tdep.h"
--- 25,30 ----
*************** fill_gregset (elf_gregset_t * gregsetp,
*** 158,164 ****
for (i = 0; i < x86_64_num_gregs; i++)
if ((regno == -1 || regno == i))
! read_register_gen (i, regp + x86_64_regmap[i]);
}
/* Fetch all general-purpose registers from process/thread TID and
--- 157,163 ----
for (i = 0; i < x86_64_num_gregs; i++)
if ((regno == -1 || regno == i))
! read_register_gen (i, (char *) (regp + x86_64_regmap[i]));
}
/* Fetch all general-purpose registers from process/thread TID and
*************** store_regs (int tid, int regno)
*** 195,217 ****
/* Transfering floating-point registers between GDB, inferiors and cores. */
! /* Fill GDB's register array with the floating-point register values in
! *FPREGSETP. */
void
! supply_fpregset (elf_fpregset_t * fpregsetp)
{
! i387_supply_fxsave ((char *) fpregsetp);
}
! /* Fill register REGNO (if it is a floating-point register) in
! *FPREGSETP with the value in GDB's register array. If REGNO is -1,
! do this for all registers. */
void
! fill_fpregset (elf_fpregset_t * fpregsetp, int regno)
{
! i387_fill_fxsave ((char *) fpregsetp, regno);
}
/* Fetch all floating-point registers from process/thread TID and store
--- 194,266 ----
/* Transfering floating-point registers between GDB, inferiors and cores. */
! static void *
! x86_64_fxsave_offset (elf_fpregset_t * fxsave, int regnum)
! {
! const char *reg_name;
! int reg_index;
!
! gdb_assert (x86_64_num_gregs - 1 < regnum && regnum < x86_64_num_regs);
!
! reg_name = x86_64_register_name (regnum);
!
! if (reg_name[0] == 's' && reg_name[1] == 't')
! {
! reg_index = reg_name[2] - '0';
! return &fxsave->st_space[reg_index * 2];
! }
!
! if (reg_name[0] == 'x' && reg_name[1] == 'm' && reg_name[2] == 'm')
! {
! reg_index = reg_name[3] - '0';
! return &fxsave->xmm_space[reg_index * 4];
! }
!
! if (strcmp (reg_name, "mxcsr") == 0)
! return &fxsave->mxcsr;
!
! return NULL;
! }
!
! /* Fill GDB's register array with the floating-point and SSE register
! values in *FXSAVE. This function masks off any of the reserved
! bits in *FXSAVE. */
void
! supply_fpregset (elf_fpregset_t * fxsave)
{
! int i, reg_st0, reg_mxcsr;
!
! reg_st0 = x86_64_register_number ("st0");
! reg_mxcsr = x86_64_register_number ("mxcsr");
!
! gdb_assert (reg_st0 > 0 && reg_mxcsr > reg_st0);
!
! for (i = reg_st0; i <= reg_mxcsr; i++)
! supply_register (i, x86_64_fxsave_offset (fxsave, i));
}
! /* Fill register REGNUM (if it is a floating-point or SSE register) in
! *FXSAVE with the value in GDB's register array. If REGNUM is -1, do
! this for all registers. This function doesn't touch any of the
! reserved bits in *FXSAVE. */
void
! fill_fpregset (elf_fpregset_t * fxsave, int regnum)
{
! int i, last_regnum = MXCSR_REGNUM;
! void *ptr;
!
! if (gdbarch_tdep (current_gdbarch)->num_xmm_regs == 0)
! last_regnum = FOP_REGNUM;
!
! for (i = FP0_REGNUM; i <= last_regnum; i++)
! if (regnum == -1 || regnum == i)
! {
! ptr = x86_64_fxsave_offset (fxsave, i);
! if (ptr)
! regcache_collect (i, ptr);
! }
}
/* Fetch all floating-point registers from process/thread TID and store
*************** static struct core_fns linux_elf_core_fn
*** 406,417 ****
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
#endif
- /* Record the value of the debug control register. */
- static long debug_control_mirror;
-
- /* Record which address associates with which register. */
- static CORE_ADDR address_lookup[DR_LASTADDR - DR_FIRSTADDR + 1];
-
/* Return the address of register REGNUM. BLOCKEND is the value of
u.u_ar0, which should point to the registers. */
CORE_ADDR
--- 455,460 ----
*************** kernel_u_size (void)
*** 446,449 ****
{
return (sizeof (struct user));
}
-
--- 489,491 ----
Index: x86-64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-tdep.c,v
retrieving revision 1.9.2.5
diff -c -3 -p -r1.9.2.5 x86-64-tdep.c
*** x86-64-tdep.c 7 Jun 2002 12:33:56 -0000 1.9.2.5
--- x86-64-tdep.c 27 Jun 2002 12:43:05 -0000
***************
*** 37,42 ****
--- 37,43 ----
#define RDX_REGNUM 3
#define RDI_REGNUM 5
#define EFLAGS_REGNUM 17
+ #define ST0_REGNUM 22
#define XMM1_REGNUM 39
struct register_info
*************** struct register_info
*** 49,111 ****
/* x86_64_register_raw_size_table[i] is the number of bytes of storage in
GDB's register array occupied by register i. */
static struct register_info x86_64_register_info_table[] = {
! {8, "rax", &builtin_type_int64},
! {8, "rbx", &builtin_type_int64},
! {8, "rcx", &builtin_type_int64},
! {8, "rdx", &builtin_type_int64},
! {8, "rsi", &builtin_type_int64},
! {8, "rdi", &builtin_type_int64},
! {8, "rbp", &builtin_type_void_func_ptr},
! {8, "rsp", &builtin_type_void_func_ptr},
! {8, "r8", &builtin_type_int64},
! {8, "r9", &builtin_type_int64},
! {8, "r10", &builtin_type_int64},
! {8, "r11", &builtin_type_int64},
! {8, "r12", &builtin_type_int64},
! {8, "r13", &builtin_type_int64},
! {8, "r14", &builtin_type_int64},
! {8, "r15", &builtin_type_int64},
! {8, "rip", &builtin_type_void_func_ptr},
! {4, "eflags", &builtin_type_int32},
! {4, "ds", &builtin_type_int32},
! {4, "es", &builtin_type_int32},
! {4, "fs", &builtin_type_int32},
! {4, "gs", &builtin_type_int32},
! {10, "st0", &builtin_type_i387_ext},
! {10, "st1", &builtin_type_i387_ext},
! {10, "st2", &builtin_type_i387_ext},
! {10, "st3", &builtin_type_i387_ext},
! {10, "st4", &builtin_type_i387_ext},
! {10, "st5", &builtin_type_i387_ext},
! {10, "st6", &builtin_type_i387_ext},
! {10, "st7", &builtin_type_i387_ext},
! {4, "fctrl", &builtin_type_int32},
! {4, "fstat", &builtin_type_int32},
! {4, "ftag", &builtin_type_int32},
! {4, "fiseg", &builtin_type_int32},
! {4, "fioff", &builtin_type_int32},
! {4, "foseg", &builtin_type_int32},
! {4, "fooff", &builtin_type_int32},
! {4, "fop", &builtin_type_int32},
! {16, "xmm0", &builtin_type_v4sf},
! {16, "xmm1", &builtin_type_v4sf},
! {16, "xmm2", &builtin_type_v4sf},
! {16, "xmm3", &builtin_type_v4sf},
! {16, "xmm4", &builtin_type_v4sf},
! {16, "xmm5", &builtin_type_v4sf},
! {16, "xmm6", &builtin_type_v4sf},
! {16, "xmm7", &builtin_type_v4sf},
! {16, "xmm8", &builtin_type_v4sf},
! {16, "xmm9", &builtin_type_v4sf},
! {16, "xmm10", &builtin_type_v4sf},
! {16, "xmm11", &builtin_type_v4sf},
! {16, "xmm12", &builtin_type_v4sf},
! {16, "xmm13", &builtin_type_v4sf},
! {16, "xmm14", &builtin_type_v4sf},
! {16, "xmm15", &builtin_type_v4sf},
! {4, "mxcsr", &builtin_type_int32}
};
/* Number of all registers */
#define X86_64_NUM_REGS (sizeof (x86_64_register_info_table) / \
sizeof (x86_64_register_info_table[0]))
--- 50,139 ----
/* x86_64_register_raw_size_table[i] is the number of bytes of storage in
GDB's register array occupied by register i. */
static struct register_info x86_64_register_info_table[] = {
! /* 0 */ {8, "rax", &builtin_type_int64},
! /* 1 */ {8, "rbx", &builtin_type_int64},
! /* 2 */ {8, "rcx", &builtin_type_int64},
! /* 3 */ {8, "rdx", &builtin_type_int64},
! /* 4 */ {8, "rsi", &builtin_type_int64},
! /* 5 */ {8, "rdi", &builtin_type_int64},
! /* 6 */ {8, "rbp", &builtin_type_void_func_ptr},
! /* 7 */ {8, "rsp", &builtin_type_void_func_ptr},
! /* 8 */ {8, "r8", &builtin_type_int64},
! /* 9 */ {8, "r9", &builtin_type_int64},
! /* 10 */ {8, "r10", &builtin_type_int64},
! /* 11 */ {8, "r11", &builtin_type_int64},
! /* 12 */ {8, "r12", &builtin_type_int64},
! /* 13 */ {8, "r13", &builtin_type_int64},
! /* 14 */ {8, "r14", &builtin_type_int64},
! /* 15 */ {8, "r15", &builtin_type_int64},
! /* 16 */ {8, "rip", &builtin_type_void_func_ptr},
! /* 17 */ {4, "eflags", &builtin_type_int32},
! /* 18 */ {4, "ds", &builtin_type_int32},
! /* 19 */ {4, "es", &builtin_type_int32},
! /* 20 */ {4, "fs", &builtin_type_int32},
! /* 21 */ {4, "gs", &builtin_type_int32},
! /* 22 */ {10, "st0", &builtin_type_i387_ext},
! /* 23 */ {10, "st1", &builtin_type_i387_ext},
! /* 24 */ {10, "st2", &builtin_type_i387_ext},
! /* 25 */ {10, "st3", &builtin_type_i387_ext},
! /* 26 */ {10, "st4", &builtin_type_i387_ext},
! /* 27 */ {10, "st5", &builtin_type_i387_ext},
! /* 28 */ {10, "st6", &builtin_type_i387_ext},
! /* 29 */ {10, "st7", &builtin_type_i387_ext},
! /* 30 */ {4, "fctrl", &builtin_type_int32},
! /* 31 */ {4, "fstat", &builtin_type_int32},
! /* 32 */ {4, "ftag", &builtin_type_int32},
! /* 33 */ {4, "fiseg", &builtin_type_int32},
! /* 34 */ {4, "fioff", &builtin_type_int32},
! /* 35 */ {4, "foseg", &builtin_type_int32},
! /* 36 */ {4, "fooff", &builtin_type_int32},
! /* 37 */ {4, "fop", &builtin_type_int32},
! /* 38 */ {16, "xmm0", &builtin_type_v4sf},
! /* 39 */ {16, "xmm1", &builtin_type_v4sf},
! /* 40 */ {16, "xmm2", &builtin_type_v4sf},
! /* 41 */ {16, "xmm3", &builtin_type_v4sf},
! /* 42 */ {16, "xmm4", &builtin_type_v4sf},
! /* 43 */ {16, "xmm5", &builtin_type_v4sf},
! /* 44 */ {16, "xmm6", &builtin_type_v4sf},
! /* 45 */ {16, "xmm7", &builtin_type_v4sf},
! /* 46 */ {16, "xmm8", &builtin_type_v4sf},
! /* 47 */ {16, "xmm9", &builtin_type_v4sf},
! /* 48 */ {16, "xmm10", &builtin_type_v4sf},
! /* 49 */ {16, "xmm11", &builtin_type_v4sf},
! /* 50 */ {16, "xmm12", &builtin_type_v4sf},
! /* 51 */ {16, "xmm13", &builtin_type_v4sf},
! /* 52 */ {16, "xmm14", &builtin_type_v4sf},
! /* 53 */ {16, "xmm15", &builtin_type_v4sf},
! /* 54 */ {4, "mxcsr", &builtin_type_int32}
};
+ /* This array is a mapping from Dwarf-2 register
+ numbering to GDB's one. Dwarf-2 numbering is
+ defined in x86-64 ABI, section 3.6. */
+ static int x86_64_dwarf2gdb_regno_map[] = {
+ 0, 1, 2, 3, /* RAX - RDX */
+ 4, 5, 6, 7, /* RSI, RDI, RBP, RSP */
+ 8, 9, 10, 11, /* R8 - R11 */
+ 12, 13, 14, 15, /* R12 - R15 */
+ -1, /* RA - not mapped */
+ XMM1_REGNUM - 1, XMM1_REGNUM, /* XMM0 ... */
+ XMM1_REGNUM + 1, XMM1_REGNUM + 2,
+ XMM1_REGNUM + 3, XMM1_REGNUM + 4,
+ XMM1_REGNUM + 5, XMM1_REGNUM + 6,
+ XMM1_REGNUM + 7, XMM1_REGNUM + 8,
+ XMM1_REGNUM + 9, XMM1_REGNUM + 10,
+ XMM1_REGNUM + 11, XMM1_REGNUM + 12,
+ XMM1_REGNUM + 13, XMM1_REGNUM + 14, /* ... XMM15 */
+ ST0_REGNUM + 0, ST0_REGNUM + 1, /* ST0 ... */
+ ST0_REGNUM + 2, ST0_REGNUM + 3,
+ ST0_REGNUM + 4, ST0_REGNUM + 5,
+ ST0_REGNUM + 6, ST0_REGNUM + 7 /* ... ST7 */
+ };
+
+ static int x86_64_dwarf2gdb_regno_map_length =
+ sizeof (x86_64_dwarf2gdb_regno_map) /
+ sizeof (x86_64_dwarf2gdb_regno_map[0]);
+
/* Number of all registers */
#define X86_64_NUM_REGS (sizeof (x86_64_register_info_table) / \
sizeof (x86_64_register_info_table[0]))
*************** x86_64_register_convert_to_virtual (int
*** 167,173 ****
char *from, char *to)
{
char buf[12];
! DOUBLEST d;
/* We only support floating-point values. */
if (TYPE_CODE (type) != TYPE_CODE_FLT)
{
--- 195,201 ----
char *from, char *to)
{
char buf[12];
!
/* We only support floating-point values. */
if (TYPE_CODE (type) != TYPE_CODE_FLT)
{
*************** x86_64_register_convert_to_raw (struct t
*** 198,203 ****
--- 226,244 ----
memcpy (to, from, FPU_REG_RAW_SIZE);
}
+ /* Dwarf-2 <-> GDB register numbers mapping. */
+ int
+ x86_64_dwarf2_reg_to_regnum (int dw_reg)
+ {
+ if (dw_reg < 0 || dw_reg > x86_64_dwarf2gdb_regno_map_length)
+ {
+ warning ("Dwarf-2 uses unmapped register #%d\n", dw_reg);
+ return dw_reg;
+ }
+
+ return x86_64_dwarf2gdb_regno_map[dw_reg];
+ }
+
/* This is the variable that is set with "set disassembly-flavour", and
its legitimate values. */
static const char att_flavour[] = "att";
*************** classify_argument (struct type *type,
*** 331,348 ****
case TYPE_CODE_STRUCT:
{
int j;
! for (j = 0; j < type->nfields; ++j)
{
! int num = classify_argument (type->fields[j].type,
subclasses,
! (type->fields[j].loc.bitpos
! + bit_offset) % 256);
if (!num)
return 0;
for (i = 0; i < num; i++)
{
int pos =
! (type->fields[j].loc.bitpos + bit_offset) / 8 / 8;
classes[i + pos] =
merge_classes (subclasses[i], classes[i + pos]);
}
--- 372,390 ----
case TYPE_CODE_STRUCT:
{
int j;
! for (j = 0; j < TYPE_NFIELDS (type); ++j)
{
! int num = classify_argument (TYPE_FIELDS (type)[j].type,
subclasses,
! (TYPE_FIELDS (type)[j].loc.
! bitpos + bit_offset) % 256);
if (!num)
return 0;
for (i = 0; i < num; i++)
{
int pos =
! (TYPE_FIELDS (type)[j].loc.bitpos +
! bit_offset) / 8 / 8;
classes[i + pos] =
merge_classes (subclasses[i], classes[i + pos]);
}
*************** classify_argument (struct type *type,
*** 353,359 ****
{
int num;
! num = classify_argument (type->target_type,
subclasses, bit_offset);
if (!num)
return 0;
--- 395,401 ----
{
int num;
! num = classify_argument (TYPE_TARGET_TYPE (type),
subclasses, bit_offset);
if (!num)
return 0;
*************** classify_argument (struct type *type,
*** 372,381 ****
{
int j;
{
! for (j = 0; j < type->nfields; ++j)
{
int num;
! num = classify_argument (type->fields[j].type,
subclasses, bit_offset);
if (!num)
return 0;
--- 414,423 ----
{
int j;
{
! for (j = 0; j < TYPE_NFIELDS (type); ++j)
{
int num;
! num = classify_argument (TYPE_FIELDS (type)[j].type,
subclasses, bit_offset);
if (!num)
return 0;
*************** classify_argument (struct type *type,
*** 385,390 ****
--- 427,434 ----
}
}
break;
+ default:
+ break;
}
/* Final merger cleanup. */
for (i = 0; i < words; i++)
*************** classify_argument (struct type *type,
*** 447,452 ****
--- 491,498 ----
}
case TYPE_CODE_VOID:
return 0;
+ default: /* Avoid warning. */
+ break;
}
internal_error (__FILE__, __LINE__,
"classify_argument: unknown argument type");
*************** x86_64_push_arguments (int nargs, struct
*** 609,615 ****
static int int_parameter_registers[INT_REGS] = {
5 /* RDI */ , 4 /* RSI */ ,
3 /* RDX */ , 2 /* RCX */ ,
! 8 /* R8 */ , 9 /* R9 */
};
/* XMM0 - XMM15 */
static int sse_parameter_registers[SSE_REGS] = {
--- 655,661 ----
static int int_parameter_registers[INT_REGS] = {
5 /* RDI */ , 4 /* RSI */ ,
3 /* RDX */ , 2 /* RCX */ ,
! 8 /* R8 */ , 9 /* R9 */
};
/* XMM0 - XMM15 */
static int sse_parameter_registers[SSE_REGS] = {
*************** x86_64_store_return_value (struct type *
*** 752,764 ****
}
! static char *
x86_64_register_name (int reg_nr)
{
if (reg_nr < 0 || reg_nr >= X86_64_NUM_REGS)
return NULL;
return x86_64_register_info_table[reg_nr].name;
}
--- 798,821 ----
}
! char *
x86_64_register_name (int reg_nr)
{
if (reg_nr < 0 || reg_nr >= X86_64_NUM_REGS)
return NULL;
return x86_64_register_info_table[reg_nr].name;
}
+
+ int
+ x86_64_register_number (const char *name)
+ {
+ int reg_nr;
+
+ for (reg_nr = 0; reg_nr < X86_64_NUM_REGS; reg_nr++)
+ if (strcmp (name, x86_64_register_info_table[reg_nr].name) == 0)
+ return reg_nr;
+ return -1;
+ }
*************** x86_64_frameless_function_invocation (st
*** 800,809 ****
CORE_ADDR
x86_64_skip_prologue (CORE_ADDR pc)
{
! int i, firstline, currline;
struct symtab_and_line v_sal;
struct symbol *v_function;
! CORE_ADDR salendaddr = 0, endaddr = 0;
/* We will handle only functions beginning with:
55 pushq %rbp
--- 857,866 ----
CORE_ADDR
x86_64_skip_prologue (CORE_ADDR pc)
{
! int i;
struct symtab_and_line v_sal;
struct symbol *v_function;
! CORE_ADDR endaddr;
/* We will handle only functions beginning with:
55 pushq %rbp
*************** x86_64_skip_prologue (CORE_ADDR pc)
*** 817,823 ****
/* First check, whether pc points to pushq %rbp, movq %rsp,%rbp. */
for (i = 0; i < PROLOG_BUFSIZE; i++)
if (prolog_expect[i] != prolog_buf[i])
! return pc; /* ... no, it doesn't. Nothing to skip. */
/* OK, we have found the prologue and want PC of the first
non-prologue instruction. */
--- 874,880 ----
/* First check, whether pc points to pushq %rbp, movq %rsp,%rbp. */
for (i = 0; i < PROLOG_BUFSIZE; i++)
if (prolog_expect[i] != prolog_buf[i])
! return pc; /* ... no, it doesn't. Nothing to skip. */
/* OK, we have found the prologue and want PC of the first
non-prologue instruction. */
*************** x86_64_skip_prologue (CORE_ADDR pc)
*** 831,848 ****
if (!v_function || !v_function->ginfo.value.block || !v_sal.symtab)
return pc;
- firstline = v_sal.line;
- currline = firstline;
- salendaddr = v_sal.end;
endaddr = v_function->ginfo.value.block->endaddr;
for (i = 0; i < v_sal.symtab->linetable->nitems; i++)
! if (v_sal.symtab->linetable->item[i].line > firstline
! && v_sal.symtab->linetable->item[i].pc >= salendaddr
&& v_sal.symtab->linetable->item[i].pc < endaddr)
{
pc = v_sal.symtab->linetable->item[i].pc;
- currline = v_sal.symtab->linetable->item[i].line;
break;
}
--- 888,900 ----
if (!v_function || !v_function->ginfo.value.block || !v_sal.symtab)
return pc;
endaddr = v_function->ginfo.value.block->endaddr;
for (i = 0; i < v_sal.symtab->linetable->nitems; i++)
! if (v_sal.symtab->linetable->item[i].pc >= pc
&& v_sal.symtab->linetable->item[i].pc < endaddr)
{
pc = v_sal.symtab->linetable->item[i].pc;
break;
}
*************** x86_64_breakpoint_from_pc (CORE_ADDR * p
*** 859,865 ****
}
static struct gdbarch *
! i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
struct gdbarch *gdbarch;
struct gdbarch_tdep *tdep;
--- 911,917 ----
}
static struct gdbarch *
! x86_64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
struct gdbarch *gdbarch;
struct gdbarch_tdep *tdep;
*************** i386_gdbarch_init (struct gdbarch_info i
*** 885,891 ****
break;
default:
internal_error (__FILE__, __LINE__,
! "i386_gdbarch_init: unknown machine type");
}
break;
case bfd_mach_i386_i386:
--- 937,943 ----
break;
default:
internal_error (__FILE__, __LINE__,
! "x86_64_gdbarch_init: unknown machine type");
}
break;
case bfd_mach_i386_i386:
*************** i386_gdbarch_init (struct gdbarch_info i
*** 902,913 ****
return arches->gdbarch;
default:
internal_error (__FILE__, __LINE__,
! "i386_gdbarch_init: unknown machine type");
}
break;
default:
internal_error (__FILE__, __LINE__,
! "i386_gdbarch_init: unknown machine type");
}
}
--- 954,965 ----
return arches->gdbarch;
default:
internal_error (__FILE__, __LINE__,
! "x86_64_gdbarch_init: unknown machine type");
}
break;
default:
internal_error (__FILE__, __LINE__,
! "x86_64_gdbarch_init: unknown machine type");
}
}
*************** i386_gdbarch_init (struct gdbarch_info i
*** 927,933 ****
break;
default:
internal_error (__FILE__, __LINE__,
! "i386_gdbarch_init: unknown machine type");
}
set_gdbarch_long_bit (gdbarch, 64);
--- 979,985 ----
break;
default:
internal_error (__FILE__, __LINE__,
! "x86_64_gdbarch_init: unknown machine type");
}
set_gdbarch_long_bit (gdbarch, 64);
*************** i386_gdbarch_init (struct gdbarch_info i
*** 967,973 ****
set_gdbarch_fp0_regnum (gdbarch, X86_64_NUM_GREGS); /* First FPU floating-point register. */
set_gdbarch_read_fp (gdbarch, cfi_read_fp);
- set_gdbarch_write_fp (gdbarch, cfi_write_fp);
/* Discard from the stack the innermost frame, restoring all registers. */
set_gdbarch_pop_frame (gdbarch, x86_64_pop_frame);
--- 1019,1024 ----
*************** i386_gdbarch_init (struct gdbarch_info i
*** 1056,1062 ****
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
! set_gdbarch_breakpoint_from_pc (gdbarch, x86_64_breakpoint_from_pc);
/* Amount PC must be decremented by after a breakpoint. This is often the
--- 1107,1115 ----
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
! set_gdbarch_breakpoint_from_pc (gdbarch,
! (gdbarch_breakpoint_from_pc_ftype *)
! x86_64_breakpoint_from_pc);
/* Amount PC must be decremented by after a breakpoint. This is often the
*************** i386_gdbarch_init (struct gdbarch_info i
*** 1065,1077 ****
/* Use dwarf2 debug frame informations. */
set_gdbarch_dwarf2_build_frame_info (gdbarch, dwarf2_build_frame_info);
return gdbarch;
}
void
_initialize_x86_64_tdep (void)
{
! register_gdbarch_init (bfd_arch_i386, i386_gdbarch_init);
/* Initialize the table saying where each register starts in the
register file. */
--- 1118,1132 ----
/* Use dwarf2 debug frame informations. */
set_gdbarch_dwarf2_build_frame_info (gdbarch, dwarf2_build_frame_info);
+ set_gdbarch_dwarf2_reg_to_regnum (gdbarch, x86_64_dwarf2_reg_to_regnum);
+
return gdbarch;
}
void
_initialize_x86_64_tdep (void)
{
! register_gdbarch_init (bfd_arch_i386, x86_64_gdbarch_init);
/* Initialize the table saying where each register starts in the
register file. */
Index: x86-64-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-tdep.h,v
retrieving revision 1.1.2.1
diff -c -3 -p -r1.1.2.1 x86-64-tdep.h
*** x86-64-tdep.h 27 Mar 2002 17:19:37 -0000 1.1.2.1
--- x86-64-tdep.h 27 Jun 2002 12:43:05 -0000
***************
*** 28,33 ****
--- 28,37 ----
extern int x86_64_num_regs;
extern int x86_64_num_gregs;
+ int x86_64_register_number (const char *name);
+ char *x86_64_register_name (int reg_nr);
+
+
gdbarch_frame_saved_pc_ftype x86_64_linux_frame_saved_pc;
gdbarch_saved_pc_after_call_ftype x86_64_linux_saved_pc_after_call;