aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog15
-rw-r--r--gdb/dwarf2-frame.c28
-rw-r--r--gdb/gdbarch.c25
-rw-r--r--gdb/gdbarch.h21
-rwxr-xr-xgdb/gdbarch.sh19
-rw-r--r--gdb/xstormy16-tdep.c1
6 files changed, 93 insertions, 16 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index f821a1f..8771977 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,18 @@
+2010-08-06 Corinna Vinschen <vinschen@redhat.com>
+
+ * dwarf2-frame.c (struct dwarf2_cie): Add ptr_size member.
+ Throughout, call read_encoded_value with ptr_size rather than addr_size.
+ (decode_frame_entry_1): Remove redundant setting of
+ addr_size. Call gdbarch_dwarf2_addr_size rather than gdbarch_ptr_bit
+ to determine addr_size in Dwarf versions < 4. Set ptr_size dependent
+ on examined frame section. Add comment to explain why.
+ * gdbarch.sh (dwarf2_addr_size): Define as variable. Add lengthy
+ comment to explain usage.
+ * gdbarch.c: Regenerate.
+ * gdbarch.h: Regenerate.
+
+ * xstormy16-tdep.c (xstormy16_gdbarch_init): Set dwarf2_addr_size to 4.
+
2010-08-06 Jan Kratochvil <jan.kratochvil@redhat.com>
Code cleanup.
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index a027b02..d7d8b97 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -77,6 +77,9 @@ struct dwarf2_cie
/* Target address size in bytes. */
int addr_size;
+ /* Target pointer size in bytes. */
+ int ptr_size;
+
/* True if a 'z' augmentation existed. */
unsigned char saw_z_augmentation;
@@ -452,7 +455,7 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr,
{
case DW_CFA_set_loc:
fs->pc = read_encoded_value (fde->cie->unit, fde->cie->encoding,
- fde->cie->addr_size, insn_ptr,
+ fde->cie->ptr_size, insn_ptr,
&bytes_read, fde->initial_location);
/* Apply the objfile offset for relocatable objects. */
fs->pc += ANOFFSET (fde->cie->unit->objfile->section_offsets,
@@ -1732,13 +1735,6 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p,
depends on the target address size. */
cie->encoding = DW_EH_PE_absptr;
- /* The target address size. For .eh_frame FDEs this is considered
- equal to the size of a target pointer. For .dwarf_frame FDEs,
- this is supposed to be the target address size from the associated
- CU header. FIXME: We do not have a good way to determine the
- latter. Always use the target pointer size for now. */
- cie->addr_size = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT;
-
/* We'll determine the final value later, but we need to
initialize it conservatively. */
cie->signal_frame = 0;
@@ -1779,9 +1775,17 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p,
}
else
{
- cie->addr_size = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT;
+ cie->addr_size = gdbarch_dwarf2_addr_size (gdbarch);
cie->segment_size = 0;
}
+ /* Address values in .eh_frame sections are defined to have the
+ target's pointer size. Watchout: This breaks frame info for
+ targets with pointer size < address size, unless a .debug_frame
+ section exists as well. */
+ if (eh_frame_p)
+ cie->ptr_size = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT;
+ else
+ cie->ptr_size = cie->addr_size;
cie->code_alignment_factor =
read_unsigned_leb128 (unit->abfd, buf, &bytes_read);
@@ -1841,7 +1845,7 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p,
{
/* Skip. Avoid indirection since we throw away the result. */
gdb_byte encoding = (*buf++) & ~DW_EH_PE_indirect;
- read_encoded_value (unit, encoding, cie->addr_size,
+ read_encoded_value (unit, encoding, cie->ptr_size,
buf, &bytes_read, 0);
buf += bytes_read;
augmentation++;
@@ -1907,13 +1911,13 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p,
gdb_assert (fde->cie != NULL);
fde->initial_location =
- read_encoded_value (unit, fde->cie->encoding, fde->cie->addr_size,
+ read_encoded_value (unit, fde->cie->encoding, fde->cie->ptr_size,
buf, &bytes_read, 0);
buf += bytes_read;
fde->address_range =
read_encoded_value (unit, fde->cie->encoding & 0x0f,
- fde->cie->addr_size, buf, &bytes_read, 0);
+ fde->cie->ptr_size, buf, &bytes_read, 0);
buf += bytes_read;
/* A 'z' augmentation in the CIE implies the presence of an
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 103abcb..4ff9f54 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -155,6 +155,7 @@ struct gdbarch
const struct floatformat ** long_double_format;
int ptr_bit;
int addr_bit;
+ int dwarf2_addr_size;
int char_signed;
gdbarch_read_pc_ftype *read_pc;
gdbarch_write_pc_ftype *write_pc;
@@ -305,6 +306,7 @@ struct gdbarch startup_gdbarch =
0, /* long_double_format */
8 * sizeof (void*), /* ptr_bit */
8 * sizeof (void*), /* addr_bit */
+ sizeof (void*), /* dwarf2_addr_size */
1, /* char_signed */
0, /* read_pc */
0, /* write_pc */
@@ -582,6 +584,8 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of ptr_bit, invalid_p == 0 */
if (gdbarch->addr_bit == 0)
gdbarch->addr_bit = gdbarch_ptr_bit (gdbarch);
+ if (gdbarch->dwarf2_addr_size == 0)
+ gdbarch->dwarf2_addr_size = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT;
if (gdbarch->char_signed == -1)
gdbarch->char_signed = 1;
/* Skip verify of read_pc, has predicate */
@@ -868,6 +872,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
"gdbarch_dump: dummy_id = <%s>\n",
host_address_to_string (gdbarch->dummy_id));
fprintf_unfiltered (file,
+ "gdbarch_dump: dwarf2_addr_size = %s\n",
+ plongest (gdbarch->dwarf2_addr_size));
+ fprintf_unfiltered (file,
"gdbarch_dump: dwarf2_reg_to_regnum = <%s>\n",
host_address_to_string (gdbarch->dwarf2_reg_to_regnum));
fprintf_unfiltered (file,
@@ -1556,6 +1563,24 @@ set_gdbarch_addr_bit (struct gdbarch *gdbarch,
}
int
+gdbarch_dwarf2_addr_size (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Check variable changed from pre-default. */
+ gdb_assert (gdbarch->dwarf2_addr_size != 0);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_dwarf2_addr_size called\n");
+ return gdbarch->dwarf2_addr_size;
+}
+
+void
+set_gdbarch_dwarf2_addr_size (struct gdbarch *gdbarch,
+ int dwarf2_addr_size)
+{
+ gdbarch->dwarf2_addr_size = dwarf2_addr_size;
+}
+
+int
gdbarch_char_signed (struct gdbarch *gdbarch)
{
gdb_assert (gdbarch != NULL);
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index d2b0e5a..f6c7ce8 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -154,8 +154,8 @@ extern void set_gdbarch_long_double_format (struct gdbarch *gdbarch, const struc
/ addr_bit will be set from it.
If gdbarch_ptr_bit and gdbarch_addr_bit are different, you'll probably
- also need to set gdbarch_pointer_to_address and gdbarch_address_to_pointer
- as well.
+ also need to set gdbarch_dwarf2_addr_size, gdbarch_pointer_to_address and
+ gdbarch_address_to_pointer as well.
ptr_bit is the size of a pointer on the target */
@@ -167,6 +167,23 @@ extern void set_gdbarch_ptr_bit (struct gdbarch *gdbarch, int ptr_bit);
extern int gdbarch_addr_bit (struct gdbarch *gdbarch);
extern void set_gdbarch_addr_bit (struct gdbarch *gdbarch, int addr_bit);
+/* dwarf2_addr_size is the target address size as used in the Dwarf debug
+ info. For .debug_frame FDEs, this is supposed to be the target address
+ size from the associated CU header, and which is equivalent to the
+ DWARF2_ADDR_SIZE as defined by the target specific GCC back-end.
+ Unfortunately there is no good way to determine this value. Therefore
+ dwarf2_addr_size simply defaults to the target pointer size.
+
+ dwarf2_addr_size is not used for .eh_frame FDEs, which are generally
+ defined using the target's pointer size so far.
+
+ Note that dwarf2_addr_size only needs to be redefined by a target if the
+ GCC back-end defines a DWARF2_ADDR_SIZE other than the target pointer size,
+ and if Dwarf versions < 4 need to be supported. */
+
+extern int gdbarch_dwarf2_addr_size (struct gdbarch *gdbarch);
+extern void set_gdbarch_dwarf2_addr_size (struct gdbarch *gdbarch, int dwarf2_addr_size);
+
/* One if `char' acts like `signed char', zero if `unsigned char'. */
extern int gdbarch_char_signed (struct gdbarch *gdbarch);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 49022e5..10f9477 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -384,14 +384,29 @@ v:const struct floatformat **:long_double_format:::::floatformats_ieee_double::p
# / addr_bit will be set from it.
#
# If gdbarch_ptr_bit and gdbarch_addr_bit are different, you'll probably
-# also need to set gdbarch_pointer_to_address and gdbarch_address_to_pointer
-# as well.
+# also need to set gdbarch_dwarf2_addr_size, gdbarch_pointer_to_address and
+# gdbarch_address_to_pointer as well.
#
# ptr_bit is the size of a pointer on the target
v:int:ptr_bit:::8 * sizeof (void*):gdbarch->int_bit::0
# addr_bit is the size of a target address as represented in gdb
v:int:addr_bit:::8 * sizeof (void*):0:gdbarch_ptr_bit (gdbarch):
#
+# dwarf2_addr_size is the target address size as used in the Dwarf debug
+# info. For .debug_frame FDEs, this is supposed to be the target address
+# size from the associated CU header, and which is equivalent to the
+# DWARF2_ADDR_SIZE as defined by the target specific GCC back-end.
+# Unfortunately there is no good way to determine this value. Therefore
+# dwarf2_addr_size simply defaults to the target pointer size.
+#
+# dwarf2_addr_size is not used for .eh_frame FDEs, which are generally
+# defined using the target's pointer size so far.
+#
+# Note that dwarf2_addr_size only needs to be redefined by a target if the
+# GCC back-end defines a DWARF2_ADDR_SIZE other than the target pointer size,
+# and if Dwarf versions < 4 need to be supported.
+v:int:dwarf2_addr_size:::sizeof (void*):0:gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT:
+#
# One if \`char' acts like \`signed char', zero if \`unsigned char'.
v:int:char_signed:::1:-1:1
#
diff --git a/gdb/xstormy16-tdep.c b/gdb/xstormy16-tdep.c
index 9e62d87..a595349 100644
--- a/gdb/xstormy16-tdep.c
+++ b/gdb/xstormy16-tdep.c
@@ -809,6 +809,7 @@ xstormy16_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_dwarf2_addr_size (gdbarch, 4);
set_gdbarch_address_to_pointer (gdbarch, xstormy16_address_to_pointer);
set_gdbarch_pointer_to_address (gdbarch, xstormy16_pointer_to_address);