gdb
* amd64-tdep.c (amd64_pseudo_register_read_value): Rename from amd64_pseudo_register_read. Change arguments. Call mark_value_bytes_unavailable when needed. (amd64_init_abi): Use set_gdbarch_pseudo_register_read_value, not set_gdbarch_pseudo_register_read. * sentinel-frame.c (sentinel_frame_prev_register): Use regcache_cooked_read_value. * regcache.h (regcache_cooked_read_value): Declare. * regcache.c (regcache_cooked_read_value): New function. (regcache_cooked_read): Call gdbarch_pseudo_register_read_value if available. * i386-tdep.h (i386_pseudo_register_read_value): Declare. (i386_pseudo_register_read): Remove. * i386-tdep.c (i386_pseudo_register_read_into_value): Rename from i386_pseudo_register_read. Change arguments. Call mark_value_bytes_unavailable when needed. (i386_pseudo_register_read_value): New function. (i386_gdbarch_init): Call set_gdbarch_pseudo_register_read_value, not set_gdbarch_pseudo_register_read. * gdbarch.sh (pseudo_register_read_value): New method. * gdbarch.c, gdbarch.h: Rebuild. * findvar.c (value_from_register): Call get_frame_register_value. gdb/testsuite * gdb.dwarf2/typeddwarf.c: XFAIL 'z' on x86-64. * gdb.dwarf2/typeddwarf.exp (xfail-gdb-test): Add arch_pattern argument. * gdb.dwarf2/typeddwarf-amd64.S: New file.
This commit is contained in:
parent
26ac12805d
commit
3543a589b2
15 changed files with 1818 additions and 61 deletions
|
@ -1,3 +1,28 @@
|
|||
2011-07-22 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* amd64-tdep.c (amd64_pseudo_register_read_value): Rename
|
||||
from amd64_pseudo_register_read. Change arguments. Call
|
||||
mark_value_bytes_unavailable when needed.
|
||||
(amd64_init_abi): Use set_gdbarch_pseudo_register_read_value, not
|
||||
set_gdbarch_pseudo_register_read.
|
||||
* sentinel-frame.c (sentinel_frame_prev_register): Use
|
||||
regcache_cooked_read_value.
|
||||
* regcache.h (regcache_cooked_read_value): Declare.
|
||||
* regcache.c (regcache_cooked_read_value): New function.
|
||||
(regcache_cooked_read): Call
|
||||
gdbarch_pseudo_register_read_value if available.
|
||||
* i386-tdep.h (i386_pseudo_register_read_value): Declare.
|
||||
(i386_pseudo_register_read): Remove.
|
||||
* i386-tdep.c (i386_pseudo_register_read_into_value): Rename from
|
||||
i386_pseudo_register_read. Change arguments. Call
|
||||
mark_value_bytes_unavailable when needed.
|
||||
(i386_pseudo_register_read_value): New function.
|
||||
(i386_gdbarch_init): Call set_gdbarch_pseudo_register_read_value,
|
||||
not set_gdbarch_pseudo_register_read.
|
||||
* gdbarch.sh (pseudo_register_read_value): New method.
|
||||
* gdbarch.c, gdbarch.h: Rebuild.
|
||||
* findvar.c (value_from_register): Call get_frame_register_value.
|
||||
|
||||
2011-07-22 Phil Muldoon <pmuldoon@redhat.com>
|
||||
|
||||
* event-top.c (cli_command_loop): Use get_prompt, get_suffix,
|
||||
|
|
|
@ -275,14 +275,21 @@ amd64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
|
|||
return i386_pseudo_register_name (gdbarch, regnum);
|
||||
}
|
||||
|
||||
static enum register_status
|
||||
amd64_pseudo_register_read (struct gdbarch *gdbarch,
|
||||
struct regcache *regcache,
|
||||
int regnum, gdb_byte *buf)
|
||||
static struct value *
|
||||
amd64_pseudo_register_read_value (struct gdbarch *gdbarch,
|
||||
struct regcache *regcache,
|
||||
int regnum)
|
||||
{
|
||||
gdb_byte raw_buf[MAX_REGISTER_SIZE];
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
enum register_status status;
|
||||
struct value *result_value;
|
||||
gdb_byte *buf;
|
||||
|
||||
result_value = allocate_value (register_type (gdbarch, regnum));
|
||||
VALUE_LVAL (result_value) = lval_register;
|
||||
VALUE_REGNUM (result_value) = regnum;
|
||||
buf = value_contents_raw (result_value);
|
||||
|
||||
if (i386_byte_regnum_p (gdbarch, regnum))
|
||||
{
|
||||
|
@ -297,15 +304,19 @@ amd64_pseudo_register_read (struct gdbarch *gdbarch,
|
|||
raw_buf);
|
||||
if (status == REG_VALID)
|
||||
memcpy (buf, raw_buf + 1, 1);
|
||||
else
|
||||
mark_value_bytes_unavailable (result_value, 0,
|
||||
TYPE_LENGTH (value_type (result_value)));
|
||||
}
|
||||
else
|
||||
{
|
||||
status = regcache_raw_read (regcache, gpnum, raw_buf);
|
||||
if (status == REG_VALID)
|
||||
memcpy (buf, raw_buf, 1);
|
||||
else
|
||||
mark_value_bytes_unavailable (result_value, 0,
|
||||
TYPE_LENGTH (value_type (result_value)));
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
else if (i386_dword_regnum_p (gdbarch, regnum))
|
||||
{
|
||||
|
@ -314,11 +325,15 @@ amd64_pseudo_register_read (struct gdbarch *gdbarch,
|
|||
status = regcache_raw_read (regcache, gpnum, raw_buf);
|
||||
if (status == REG_VALID)
|
||||
memcpy (buf, raw_buf, 4);
|
||||
|
||||
return status;
|
||||
else
|
||||
mark_value_bytes_unavailable (result_value, 0,
|
||||
TYPE_LENGTH (value_type (result_value)));
|
||||
}
|
||||
else
|
||||
return i386_pseudo_register_read (gdbarch, regcache, regnum, buf);
|
||||
i386_pseudo_register_read_into_value (gdbarch, regcache, regnum,
|
||||
result_value);
|
||||
|
||||
return result_value;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2494,8 +2509,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
|||
/* Avoid wiring in the MMX registers for now. */
|
||||
tdep->num_mmx_regs = 0;
|
||||
|
||||
set_gdbarch_pseudo_register_read (gdbarch,
|
||||
amd64_pseudo_register_read);
|
||||
set_gdbarch_pseudo_register_read_value (gdbarch,
|
||||
amd64_pseudo_register_read_value);
|
||||
set_gdbarch_pseudo_register_write (gdbarch,
|
||||
amd64_pseudo_register_write);
|
||||
|
||||
|
|
|
@ -625,10 +625,11 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame)
|
|||
struct gdbarch *gdbarch = get_frame_arch (frame);
|
||||
struct type *type1 = check_typedef (type);
|
||||
struct value *v;
|
||||
int optim, unavail, ok;
|
||||
|
||||
if (gdbarch_convert_register_p (gdbarch, regnum, type1))
|
||||
{
|
||||
int optim, unavail, ok;
|
||||
|
||||
/* The ISA/ABI need to something weird when obtaining the
|
||||
specified value from this register. It might need to
|
||||
re-order non-adjacent, starting with REGNUM (see MIPS and
|
||||
|
@ -643,26 +644,27 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame)
|
|||
ok = gdbarch_register_to_value (gdbarch, frame, regnum, type1,
|
||||
value_contents_raw (v), &optim,
|
||||
&unavail);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
if (optim)
|
||||
set_value_optimized_out (v, 1);
|
||||
if (unavail)
|
||||
mark_value_bytes_unavailable (v, 0, TYPE_LENGTH (type));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int len = TYPE_LENGTH (type);
|
||||
struct value *v2;
|
||||
|
||||
/* Construct the value. */
|
||||
v = gdbarch_value_from_register (gdbarch, type, regnum, frame);
|
||||
|
||||
/* Get the data. */
|
||||
ok = get_frame_register_bytes (frame, regnum, value_offset (v), len,
|
||||
value_contents_raw (v),
|
||||
&optim, &unavail);
|
||||
}
|
||||
v2 = get_frame_register_value (frame, regnum);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
if (optim)
|
||||
set_value_optimized_out (v, 1);
|
||||
if (unavail)
|
||||
mark_value_bytes_unavailable (v, 0, TYPE_LENGTH (type));
|
||||
value_contents_copy (v, 0, v2, value_offset (v), len);
|
||||
}
|
||||
|
||||
return v;
|
||||
|
|
|
@ -161,6 +161,7 @@ struct gdbarch
|
|||
gdbarch_write_pc_ftype *write_pc;
|
||||
gdbarch_virtual_frame_pointer_ftype *virtual_frame_pointer;
|
||||
gdbarch_pseudo_register_read_ftype *pseudo_register_read;
|
||||
gdbarch_pseudo_register_read_value_ftype *pseudo_register_read_value;
|
||||
gdbarch_pseudo_register_write_ftype *pseudo_register_write;
|
||||
int num_regs;
|
||||
int num_pseudo_regs;
|
||||
|
@ -313,6 +314,7 @@ struct gdbarch startup_gdbarch =
|
|||
0, /* write_pc */
|
||||
legacy_virtual_frame_pointer, /* virtual_frame_pointer */
|
||||
0, /* pseudo_register_read */
|
||||
0, /* pseudo_register_read_value */
|
||||
0, /* pseudo_register_write */
|
||||
0, /* num_regs */
|
||||
0, /* num_pseudo_regs */
|
||||
|
@ -594,6 +596,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
|||
/* Skip verify of write_pc, has predicate. */
|
||||
/* Skip verify of virtual_frame_pointer, invalid_p == 0 */
|
||||
/* Skip verify of pseudo_register_read, has predicate. */
|
||||
/* Skip verify of pseudo_register_read_value, has predicate. */
|
||||
/* Skip verify of pseudo_register_write, has predicate. */
|
||||
if (gdbarch->num_regs == -1)
|
||||
fprintf_unfiltered (log, "\n\tnum_regs");
|
||||
|
@ -1084,6 +1087,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
|||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: pseudo_register_read = <%s>\n",
|
||||
host_address_to_string (gdbarch->pseudo_register_read));
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: gdbarch_pseudo_register_read_value_p() = %d\n",
|
||||
gdbarch_pseudo_register_read_value_p (gdbarch));
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: pseudo_register_read_value = <%s>\n",
|
||||
host_address_to_string (gdbarch->pseudo_register_read_value));
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: gdbarch_pseudo_register_write_p() = %d\n",
|
||||
gdbarch_pseudo_register_write_p (gdbarch));
|
||||
|
@ -1699,6 +1708,30 @@ set_gdbarch_pseudo_register_read (struct gdbarch *gdbarch,
|
|||
gdbarch->pseudo_register_read = pseudo_register_read;
|
||||
}
|
||||
|
||||
int
|
||||
gdbarch_pseudo_register_read_value_p (struct gdbarch *gdbarch)
|
||||
{
|
||||
gdb_assert (gdbarch != NULL);
|
||||
return gdbarch->pseudo_register_read_value != NULL;
|
||||
}
|
||||
|
||||
struct value *
|
||||
gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum)
|
||||
{
|
||||
gdb_assert (gdbarch != NULL);
|
||||
gdb_assert (gdbarch->pseudo_register_read_value != NULL);
|
||||
if (gdbarch_debug >= 2)
|
||||
fprintf_unfiltered (gdb_stdlog, "gdbarch_pseudo_register_read_value called\n");
|
||||
return gdbarch->pseudo_register_read_value (gdbarch, regcache, cookednum);
|
||||
}
|
||||
|
||||
void
|
||||
set_gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch,
|
||||
gdbarch_pseudo_register_read_value_ftype pseudo_register_read_value)
|
||||
{
|
||||
gdbarch->pseudo_register_read_value = pseudo_register_read_value;
|
||||
}
|
||||
|
||||
int
|
||||
gdbarch_pseudo_register_write_p (struct gdbarch *gdbarch)
|
||||
{
|
||||
|
|
|
@ -216,6 +216,17 @@ typedef enum register_status (gdbarch_pseudo_register_read_ftype) (struct gdbarc
|
|||
extern enum register_status gdbarch_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, gdb_byte *buf);
|
||||
extern void set_gdbarch_pseudo_register_read (struct gdbarch *gdbarch, gdbarch_pseudo_register_read_ftype *pseudo_register_read);
|
||||
|
||||
/* Read a register into a new struct value. If the register is wholly
|
||||
or partly unavailable, this should call mark_value_bytes_unavailable
|
||||
as appropriate. If this is defined, then pseudo_register_read will
|
||||
never be called. */
|
||||
|
||||
extern int gdbarch_pseudo_register_read_value_p (struct gdbarch *gdbarch);
|
||||
|
||||
typedef struct value * (gdbarch_pseudo_register_read_value_ftype) (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum);
|
||||
extern struct value * gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum);
|
||||
extern void set_gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, gdbarch_pseudo_register_read_value_ftype *pseudo_register_read_value);
|
||||
|
||||
extern int gdbarch_pseudo_register_write_p (struct gdbarch *gdbarch);
|
||||
|
||||
typedef void (gdbarch_pseudo_register_write_ftype) (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, const gdb_byte *buf);
|
||||
|
|
|
@ -418,6 +418,11 @@ F:void:write_pc:struct regcache *regcache, CORE_ADDR val:regcache, val
|
|||
m:void:virtual_frame_pointer:CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset:pc, frame_regnum, frame_offset:0:legacy_virtual_frame_pointer::0
|
||||
#
|
||||
M:enum register_status:pseudo_register_read:struct regcache *regcache, int cookednum, gdb_byte *buf:regcache, cookednum, buf
|
||||
# Read a register into a new struct value. If the register is wholly
|
||||
# or partly unavailable, this should call mark_value_bytes_unavailable
|
||||
# as appropriate. If this is defined, then pseudo_register_read will
|
||||
# never be called.
|
||||
M:struct value *:pseudo_register_read_value:struct regcache *regcache, int cookednum:regcache, cookednum
|
||||
M:void:pseudo_register_write:struct regcache *regcache, int cookednum, const gdb_byte *buf:regcache, cookednum, buf
|
||||
#
|
||||
v:int:num_regs:::0:-1
|
||||
|
|
|
@ -2780,12 +2780,19 @@ i386_mmx_regnum_to_fp_regnum (struct regcache *regcache, int regnum)
|
|||
return (I387_ST0_REGNUM (tdep) + fpreg);
|
||||
}
|
||||
|
||||
enum register_status
|
||||
i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
|
||||
int regnum, gdb_byte *buf)
|
||||
/* A helper function for us by i386_pseudo_register_read_value and
|
||||
amd64_pseudo_register_read_value. It does all the work but reads
|
||||
the data into an already-allocated value. */
|
||||
|
||||
void
|
||||
i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
|
||||
struct regcache *regcache,
|
||||
int regnum,
|
||||
struct value *result_value)
|
||||
{
|
||||
gdb_byte raw_buf[MAX_REGISTER_SIZE];
|
||||
enum register_status status;
|
||||
gdb_byte *buf = value_contents_raw (result_value);
|
||||
|
||||
if (i386_mmx_regnum_p (gdbarch, regnum))
|
||||
{
|
||||
|
@ -2794,8 +2801,10 @@ i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
|
|||
/* Extract (always little endian). */
|
||||
status = regcache_raw_read (regcache, fpnum, raw_buf);
|
||||
if (status != REG_VALID)
|
||||
return status;
|
||||
memcpy (buf, raw_buf, register_size (gdbarch, regnum));
|
||||
mark_value_bytes_unavailable (result_value, 0,
|
||||
TYPE_LENGTH (value_type (result_value)));
|
||||
else
|
||||
memcpy (buf, raw_buf, register_size (gdbarch, regnum));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2810,15 +2819,17 @@ i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
|
|||
I387_XMM0_REGNUM (tdep) + regnum,
|
||||
raw_buf);
|
||||
if (status != REG_VALID)
|
||||
return status;
|
||||
memcpy (buf, raw_buf, 16);
|
||||
mark_value_bytes_unavailable (result_value, 0, 16);
|
||||
else
|
||||
memcpy (buf, raw_buf, 16);
|
||||
/* Read upper 128bits. */
|
||||
status = regcache_raw_read (regcache,
|
||||
tdep->ymm0h_regnum + regnum,
|
||||
raw_buf);
|
||||
if (status != REG_VALID)
|
||||
return status;
|
||||
memcpy (buf + 16, raw_buf, 16);
|
||||
mark_value_bytes_unavailable (result_value, 16, 32);
|
||||
else
|
||||
memcpy (buf + 16, raw_buf, 16);
|
||||
}
|
||||
else if (i386_word_regnum_p (gdbarch, regnum))
|
||||
{
|
||||
|
@ -2827,8 +2838,10 @@ i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
|
|||
/* Extract (always little endian). */
|
||||
status = regcache_raw_read (regcache, gpnum, raw_buf);
|
||||
if (status != REG_VALID)
|
||||
return status;
|
||||
memcpy (buf, raw_buf, 2);
|
||||
mark_value_bytes_unavailable (result_value, 0,
|
||||
TYPE_LENGTH (value_type (result_value)));
|
||||
else
|
||||
memcpy (buf, raw_buf, 2);
|
||||
}
|
||||
else if (i386_byte_regnum_p (gdbarch, regnum))
|
||||
{
|
||||
|
@ -2841,8 +2854,9 @@ i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
|
|||
upper registers. */
|
||||
status = regcache_raw_read (regcache, gpnum % 4, raw_buf);
|
||||
if (status != REG_VALID)
|
||||
return status;
|
||||
if (gpnum >= 4)
|
||||
mark_value_bytes_unavailable (result_value, 0,
|
||||
TYPE_LENGTH (value_type (result_value)));
|
||||
else if (gpnum >= 4)
|
||||
memcpy (buf, raw_buf + 1, 1);
|
||||
else
|
||||
memcpy (buf, raw_buf, 1);
|
||||
|
@ -2850,8 +2864,22 @@ i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
|
|||
else
|
||||
internal_error (__FILE__, __LINE__, _("invalid regnum"));
|
||||
}
|
||||
}
|
||||
|
||||
return REG_VALID;
|
||||
static struct value *
|
||||
i386_pseudo_register_read_value (struct gdbarch *gdbarch,
|
||||
struct regcache *regcache,
|
||||
int regnum)
|
||||
{
|
||||
struct value *result;
|
||||
|
||||
result = allocate_value (register_type (gdbarch, regnum));
|
||||
VALUE_LVAL (result) = lval_register;
|
||||
VALUE_REGNUM (result) = regnum;
|
||||
|
||||
i386_pseudo_register_read_into_value (gdbarch, regcache, regnum, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -7333,7 +7361,8 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
frame_base_set_default (gdbarch, &i386_frame_base);
|
||||
|
||||
/* Pseudo registers may be changed by amd64_init_abi. */
|
||||
set_gdbarch_pseudo_register_read (gdbarch, i386_pseudo_register_read);
|
||||
set_gdbarch_pseudo_register_read_value (gdbarch,
|
||||
i386_pseudo_register_read_value);
|
||||
set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write);
|
||||
|
||||
set_tdesc_pseudo_register_type (gdbarch, i386_pseudo_register_type);
|
||||
|
|
|
@ -311,10 +311,11 @@ extern int i386_ymm_regnum_p (struct gdbarch *gdbarch, int regnum);
|
|||
extern const char *i386_pseudo_register_name (struct gdbarch *gdbarch,
|
||||
int regnum);
|
||||
|
||||
extern enum register_status i386_pseudo_register_read (struct gdbarch *gdbarch,
|
||||
struct regcache *regcache,
|
||||
int regnum,
|
||||
gdb_byte *buf);
|
||||
extern void i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
|
||||
struct regcache *regcache,
|
||||
int regnum,
|
||||
struct value *result);
|
||||
|
||||
extern void i386_pseudo_register_write (struct gdbarch *gdbarch,
|
||||
struct regcache *regcache,
|
||||
int regnum, const gdb_byte *buf);
|
||||
|
|
|
@ -709,11 +709,66 @@ regcache_cooked_read (struct regcache *regcache, int regnum, gdb_byte *buf)
|
|||
|
||||
return regcache->register_status[regnum];
|
||||
}
|
||||
else if (gdbarch_pseudo_register_read_value_p (regcache->descr->gdbarch))
|
||||
{
|
||||
struct value *mark, *computed;
|
||||
enum register_status result = REG_VALID;
|
||||
|
||||
mark = value_mark ();
|
||||
|
||||
computed = gdbarch_pseudo_register_read_value (regcache->descr->gdbarch,
|
||||
regcache, regnum);
|
||||
if (value_entirely_available (computed))
|
||||
memcpy (buf, value_contents_raw (computed),
|
||||
regcache->descr->sizeof_register[regnum]);
|
||||
else
|
||||
{
|
||||
memset (buf, 0, regcache->descr->sizeof_register[regnum]);
|
||||
result = REG_UNAVAILABLE;
|
||||
}
|
||||
|
||||
value_free_to_mark (mark);
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
return gdbarch_pseudo_register_read (regcache->descr->gdbarch, regcache,
|
||||
regnum, buf);
|
||||
}
|
||||
|
||||
struct value *
|
||||
regcache_cooked_read_value (struct regcache *regcache, int regnum)
|
||||
{
|
||||
gdb_assert (regnum >= 0);
|
||||
gdb_assert (regnum < regcache->descr->nr_cooked_registers);
|
||||
|
||||
if (regnum < regcache->descr->nr_raw_registers
|
||||
|| (regcache->readonly_p
|
||||
&& regcache->register_status[regnum] != REG_UNKNOWN)
|
||||
|| !gdbarch_pseudo_register_read_value_p (regcache->descr->gdbarch))
|
||||
{
|
||||
struct value *result;
|
||||
|
||||
result = allocate_value (register_type (regcache->descr->gdbarch,
|
||||
regnum));
|
||||
VALUE_LVAL (result) = lval_register;
|
||||
VALUE_REGNUM (result) = regnum;
|
||||
|
||||
/* It is more efficient in general to do this delegation in this
|
||||
direction than in the other one, even though the value-based
|
||||
API is preferred. */
|
||||
if (regcache_cooked_read (regcache, regnum,
|
||||
value_contents_raw (result)) == REG_UNAVAILABLE)
|
||||
mark_value_bytes_unavailable (result, 0,
|
||||
TYPE_LENGTH (value_type (result)));
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
return gdbarch_pseudo_register_read_value (regcache->descr->gdbarch,
|
||||
regcache, regnum);
|
||||
}
|
||||
|
||||
enum register_status
|
||||
regcache_cooked_read_signed (struct regcache *regcache, int regnum,
|
||||
LONGEST *val)
|
||||
|
|
|
@ -104,6 +104,12 @@ enum register_status regcache_cooked_read (struct regcache *regcache,
|
|||
void regcache_cooked_write (struct regcache *regcache, int rawnum,
|
||||
const gdb_byte *buf);
|
||||
|
||||
/* Read register REGNUM from REGCACHE and return a new value. This
|
||||
will call mark_value_bytes_unavailable as appropriate. */
|
||||
|
||||
struct value *regcache_cooked_read_value (struct regcache *regcache,
|
||||
int regnum);
|
||||
|
||||
/* Read a register as a signed/unsigned quantity. */
|
||||
extern enum register_status
|
||||
regcache_cooked_read_signed (struct regcache *regcache,
|
||||
|
|
|
@ -48,25 +48,12 @@ sentinel_frame_prev_register (struct frame_info *this_frame,
|
|||
void **this_prologue_cache,
|
||||
int regnum)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_frame_arch (this_frame);
|
||||
struct frame_unwind_cache *cache = *this_prologue_cache;
|
||||
struct value *value;
|
||||
struct type *regtype = register_type (gdbarch, regnum);
|
||||
|
||||
/* Return the actual value. */
|
||||
value = allocate_value (regtype);
|
||||
VALUE_LVAL (value) = lval_register;
|
||||
VALUE_REGNUM (value) = regnum;
|
||||
value = regcache_cooked_read_value (cache->regcache, regnum);
|
||||
VALUE_FRAME_ID (value) = get_frame_id (this_frame);
|
||||
|
||||
/* Use the regcache_cooked_read() method so that it, on the fly,
|
||||
constructs either a raw or pseudo register from the raw
|
||||
register cache. */
|
||||
if (regcache_cooked_read (cache->regcache,
|
||||
regnum,
|
||||
value_contents_raw (value)) == REG_UNAVAILABLE)
|
||||
mark_value_bytes_unavailable (value, 0, TYPE_LENGTH (regtype));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2011-07-22 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* gdb.dwarf2/typeddwarf.c: XFAIL 'z' on x86-64.
|
||||
* gdb.dwarf2/typeddwarf.exp (xfail-gdb-test): Add arch_pattern
|
||||
argument.
|
||||
* gdb.dwarf2/typeddwarf-amd64.S: New file.
|
||||
|
||||
2011-07-21 Matt Rice <ratmice@gmail.com>
|
||||
|
||||
* gdb.threads/Makefile.in: Avoid globbing corethreads.exp
|
||||
|
|
1568
gdb/testsuite/gdb.dwarf2/typeddwarf-amd64.S
Normal file
1568
gdb/testsuite/gdb.dwarf2/typeddwarf-amd64.S
Normal file
File diff suppressed because it is too large
Load diff
|
@ -25,7 +25,7 @@ f1 (double a, double b, double c, float d, float e, int f, unsigned int g, long
|
|||
double w = d / 4.0; /* { dg-final { gdb-test 29 "w" "1" } } */
|
||||
double x = a + b + 1.0; /* { dg-final { gdb-test 29 "x" "4" } } */
|
||||
double y = b + c + 2.0; /* { dg-final { gdb-test 29 "y" "7" } } */
|
||||
float z = d + e + 3.0f; /* { dg-final { gdb-test 29 "z" "12" } } */
|
||||
float z = d + e + 3.0f; /* { dg-final { xfail-gdb-test 29 "z" "12" "x86_64-*-*"} } */
|
||||
vv++;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,12 +22,16 @@ if ![dwarf2_support] {
|
|||
return 0
|
||||
}
|
||||
|
||||
# This test can only be run on x86 targets.
|
||||
if { ![is_x86_like_target] } {
|
||||
# This test can only be run on x86 and amd64 targets.
|
||||
if { [is_x86_like_target] } {
|
||||
set sfile ${test}.S
|
||||
} elseif {[istarget "x86_64-*-*"]} {
|
||||
set sfile ${test}-amd64.S
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
|
||||
if { [prepare_for_testing "${test}.exp" "${test}" ${test}.S {nodebug additional_flags=-nostdlib}] } {
|
||||
if { [prepare_for_testing "${test}.exp" "${test}" ${sfile} {nodebug additional_flags=-nostdlib}] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
|
@ -45,10 +49,19 @@ proc gdb-test {line var value} {
|
|||
lappend tests($line) [list $var $value 0]
|
||||
}
|
||||
|
||||
proc xfail-gdb-test {line var value} {
|
||||
# Add an XFAIL'd test. If ARCH_PATTERN is given, and does not match
|
||||
# the target, then the test is simply added and not XFAIL'd.
|
||||
proc xfail-gdb-test {line var value {arch_pattern ""}} {
|
||||
global tests
|
||||
|
||||
lappend tests($line) [list $var $value 1]
|
||||
set flag 1
|
||||
if {$arch_pattern != ""} {
|
||||
if {! [istarget $arch_pattern]} {
|
||||
set flag 0
|
||||
}
|
||||
}
|
||||
|
||||
lappend tests($line) [list $var $value $flag]
|
||||
}
|
||||
|
||||
proc scan_gdb_tests {} {
|
||||
|
|
Loading…
Add table
Reference in a new issue