From 8da614df6415a7aa01ba8ebf74acef32183266c4 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 6 Aug 2010 19:02:15 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 15 +++++++++++++++ gdb/dwarf2-frame.c | 28 ++++++++++++++++------------ gdb/gdbarch.c | 25 +++++++++++++++++++++++++ gdb/gdbarch.h | 21 +++++++++++++++++++-- gdb/gdbarch.sh | 19 +++++++++++++++++-- gdb/xstormy16-tdep.c | 1 + 6 files changed, 93 insertions(+), 16 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f821a1f6081..8771977c930 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,18 @@ +2010-08-06 Corinna Vinschen + + * 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 Code cleanup. diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index a027b0206ce..d7d8b9734e7 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 103abcb66c9..4ff9f542c7b 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 */ @@ -867,6 +871,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) fprintf_unfiltered (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)); @@ -1555,6 +1562,24 @@ set_gdbarch_addr_bit (struct gdbarch *gdbarch, gdbarch->addr_bit = addr_bit; } +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) { diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index d2b0e5afec8..f6c7ce81aef 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 49022e50c5a..10f9477b6fc 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 9e62d87eefb..a59534926f9 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); -- 2.30.2