X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Ffindvar.c;h=3d5d3f3a7295213d820581d51fe288c05a439514;hb=bcb3dc3d553e30a82bfab16b7cc3da7e4e416203;hp=5be4abf727dbd06adcb144b1732a82023709f850;hpb=d3efc286977aa8469ca4ba9a1aaf0a396fb460dc;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/findvar.c b/gdb/findvar.c index 5be4abf727..3d5d3f3a72 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -1,7 +1,7 @@ /* Find a variable's value in memory, for GDB, the GNU debugger. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003 Free Software + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -263,7 +263,7 @@ value_of_register (int regnum, struct frame_info *frame) char raw_buffer[MAX_REGISTER_SIZE]; enum lval_type lval; - /* User registers lie completly outside of the range of normal + /* User registers lie completely outside of the range of normal registers. Catch them early so that the target never sees them. */ if (regnum >= NUM_REGS + NUM_PSEUDO_REGS) return value_of_user_reg (regnum, frame); @@ -282,23 +282,8 @@ value_of_register (int regnum, struct frame_info *frame) reg_val = allocate_value (register_type (current_gdbarch, regnum)); - /* Convert raw data to virtual format if necessary. */ - - if (DEPRECATED_REGISTER_CONVERTIBLE (regnum)) - { - DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL (regnum, register_type (current_gdbarch, regnum), - raw_buffer, VALUE_CONTENTS_RAW (reg_val)); - } - else if (DEPRECATED_REGISTER_RAW_SIZE (regnum) == DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum)) - memcpy (VALUE_CONTENTS_RAW (reg_val), raw_buffer, - DEPRECATED_REGISTER_RAW_SIZE (regnum)); - else - internal_error (__FILE__, __LINE__, - "Register \"%s\" (%d) has conflicting raw (%d) and virtual (%d) size", - REGISTER_NAME (regnum), - regnum, - DEPRECATED_REGISTER_RAW_SIZE (regnum), - DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum)); + memcpy (VALUE_CONTENTS_RAW (reg_val), raw_buffer, + register_size (current_gdbarch, regnum)); VALUE_LVAL (reg_val) = lval; VALUE_ADDRESS (reg_val) = addr; VALUE_REGNO (reg_val) = regnum; @@ -617,7 +602,30 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame) struct value *v = allocate_value (type); CHECK_TYPEDEF (type); - if (CONVERT_REGISTER_P (regnum, type)) + if (TYPE_LENGTH (type) == 0) + { + /* It doesn't matter much what we return for this: since the + length is zero, it could be anything. But if allowed to see + a zero-length type, the register-finding loop below will set + neither mem_stor nor reg_stor, and then report an internal + error. + + Zero-length types can legitimately arise from declarations + like 'struct {}' (a GCC extension, not valid ISO C). GDB may + also create them when it finds bogus debugging information; + for example, in GCC 2.95.4 and binutils 2.11.93.0.2, the + STABS BINCL->EXCL compression process can create bad type + numbers. GDB reads these as TYPE_CODE_UNDEF types, with zero + length. (That bug is actually the only known way to get a + zero-length value allocated to a register --- which is what + it takes to make it here.) + + We'll just attribute the value to the original register. */ + VALUE_LVAL (v) = lval_register; + VALUE_ADDRESS (v) = regnum; + VALUE_REGNO (v) = regnum; + } + else if (CONVERT_REGISTER_P (regnum, type)) { /* The ISA/ABI need to something weird when obtaining the specified value from this register. It might need to @@ -647,7 +655,7 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame) /* Copy all of the data out, whereever it may be. */ for (local_regnum = regnum, value_bytes_copied = 0; value_bytes_copied < len; - (value_bytes_copied += DEPRECATED_REGISTER_RAW_SIZE (local_regnum), + (value_bytes_copied += register_size (current_gdbarch, local_regnum), ++local_regnum)) { int realnum; @@ -713,9 +721,9 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame) some fiddling with the last register copied here for little endian machines. */ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG - && len < DEPRECATED_REGISTER_RAW_SIZE (regnum)) + && len < register_size (current_gdbarch, regnum)) /* Big-endian, and we want less than full size. */ - VALUE_OFFSET (v) = DEPRECATED_REGISTER_RAW_SIZE (regnum) - len; + VALUE_OFFSET (v) = register_size (current_gdbarch, regnum) - len; else VALUE_OFFSET (v) = 0; memcpy (VALUE_CONTENTS_RAW (v), value_bytes + VALUE_OFFSET (v), len);