mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-21 01:12:32 +08:00
2012-03-01 Pedro Alves <palves@redhat.com>
PR gdb/13767 gdb/ * frame.c (read_frame_register_unsigned): New. * frame.h (read_frame_register_unsigned): Declare. * i387-tdep.c (print_i387_status_word): New parameter `status_p'. Handle it. (print_i387_control_word): New parameter `control_p'. Handle it. (i387_print_float_info): Handle unavailable float registers. gdb/testsuite/ * gdb.trace/unavailable.exp (gdb_unavailable_floats): New. (gdb_collect_globals_test): Call it.
This commit is contained in:
parent
d3dc44a619
commit
ad5f7d6ef7
@ -1,3 +1,14 @@
|
||||
2012-03-01 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/13767
|
||||
|
||||
* frame.c (read_frame_register_unsigned): New.
|
||||
* frame.h (read_frame_register_unsigned): Declare.
|
||||
* i387-tdep.c (print_i387_status_word): New parameter `status_p'.
|
||||
Handle it.
|
||||
(print_i387_control_word): New parameter `control_p'. Handle it.
|
||||
(i387_print_float_info): Handle unavailable float registers.
|
||||
|
||||
2012-03-01 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* linespec.c (decode_line_2): Sort the list of methods
|
||||
|
20
gdb/frame.c
20
gdb/frame.c
@ -1031,6 +1031,26 @@ get_frame_register_unsigned (struct frame_info *frame, int regnum)
|
||||
return frame_unwind_register_unsigned (frame->next, regnum);
|
||||
}
|
||||
|
||||
int
|
||||
read_frame_register_unsigned (struct frame_info *frame, int regnum,
|
||||
ULONGEST *val)
|
||||
{
|
||||
struct value *regval = get_frame_register_value (frame, regnum);
|
||||
|
||||
if (!value_optimized_out (regval)
|
||||
&& value_entirely_available (regval))
|
||||
{
|
||||
struct gdbarch *gdbarch = get_frame_arch (frame);
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||
int size = register_size (gdbarch, VALUE_REGNUM (regval));
|
||||
|
||||
*val = extract_unsigned_integer (value_contents (regval), size, byte_order);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
put_frame_register (struct frame_info *frame, int regnum,
|
||||
const gdb_byte *buf)
|
||||
|
@ -500,6 +500,13 @@ extern ULONGEST frame_unwind_register_unsigned (struct frame_info *frame,
|
||||
extern ULONGEST get_frame_register_unsigned (struct frame_info *frame,
|
||||
int regnum);
|
||||
|
||||
/* Read a a register from this, or unwind a register from the next
|
||||
frame. Note that the read_frame methods are wrappers to
|
||||
get_frame_register_value, that do not throw if the result is
|
||||
optimized out or unavailable. */
|
||||
|
||||
extern int read_frame_register_unsigned (struct frame_info *frame,
|
||||
int regnum, ULONGEST *val);
|
||||
|
||||
/* Get the value of the register that belongs to this FRAME. This
|
||||
function is a wrapper to the call sequence ``frame_register_unwind
|
||||
|
172
gdb/i387-tdep.c
172
gdb/i387-tdep.c
@ -113,13 +113,21 @@ print_i387_ext (struct gdbarch *gdbarch,
|
||||
fputs_filtered (" Unsupported", file);
|
||||
}
|
||||
|
||||
/* Print the status word STATUS. */
|
||||
/* Print the status word STATUS. If STATUS_P is false, then STATUS
|
||||
was unavailable. */
|
||||
|
||||
static void
|
||||
print_i387_status_word (unsigned int status, struct ui_file *file)
|
||||
print_i387_status_word (int status_p,
|
||||
unsigned int status, struct ui_file *file)
|
||||
{
|
||||
fprintf_filtered (file, "Status Word: %s",
|
||||
hex_string_custom (status, 4));
|
||||
fprintf_filtered (file, "Status Word: ");
|
||||
if (!status_p)
|
||||
{
|
||||
fprintf_filtered (file, "%s\n", _("<unavailable>"));
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf_filtered (file, "%s", hex_string_custom (status, 4));
|
||||
fputs_filtered (" ", file);
|
||||
fprintf_filtered (file, " %s", (status & 0x0001) ? "IE" : " ");
|
||||
fprintf_filtered (file, " %s", (status & 0x0002) ? "DE" : " ");
|
||||
@ -143,13 +151,21 @@ print_i387_status_word (unsigned int status, struct ui_file *file)
|
||||
" TOP: %d\n", ((status >> 11) & 7));
|
||||
}
|
||||
|
||||
/* Print the control word CONTROL. */
|
||||
/* Print the control word CONTROL. If CONTROL_P is false, then
|
||||
CONTROL was unavailable. */
|
||||
|
||||
static void
|
||||
print_i387_control_word (unsigned int control, struct ui_file *file)
|
||||
print_i387_control_word (int control_p,
|
||||
unsigned int control, struct ui_file *file)
|
||||
{
|
||||
fprintf_filtered (file, "Control Word: %s",
|
||||
hex_string_custom (control, 4));
|
||||
fprintf_filtered (file, "Control Word: ");
|
||||
if (!control_p)
|
||||
{
|
||||
fprintf_filtered (file, "%s\n", _("<unavailable>"));
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf_filtered (file, "%s", hex_string_custom (control, 4));
|
||||
fputs_filtered (" ", file);
|
||||
fprintf_filtered (file, " %s", (control & 0x0001) ? "IM" : " ");
|
||||
fprintf_filtered (file, " %s", (control & 0x0002) ? "DM" : " ");
|
||||
@ -205,81 +221,119 @@ i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
|
||||
ULONGEST fctrl;
|
||||
int fctrl_p;
|
||||
ULONGEST fstat;
|
||||
int fstat_p;
|
||||
ULONGEST ftag;
|
||||
int ftag_p;
|
||||
ULONGEST fiseg;
|
||||
int fiseg_p;
|
||||
ULONGEST fioff;
|
||||
int fioff_p;
|
||||
ULONGEST foseg;
|
||||
int foseg_p;
|
||||
ULONGEST fooff;
|
||||
int fooff_p;
|
||||
ULONGEST fop;
|
||||
int fop_p;
|
||||
int fpreg;
|
||||
int fpreg_p;
|
||||
int top;
|
||||
int top_p;
|
||||
|
||||
gdb_assert (gdbarch == get_frame_arch (frame));
|
||||
|
||||
fctrl = get_frame_register_unsigned (frame, I387_FCTRL_REGNUM (tdep));
|
||||
fstat = get_frame_register_unsigned (frame, I387_FSTAT_REGNUM (tdep));
|
||||
ftag = get_frame_register_unsigned (frame, I387_FTAG_REGNUM (tdep));
|
||||
fiseg = get_frame_register_unsigned (frame, I387_FISEG_REGNUM (tdep));
|
||||
fioff = get_frame_register_unsigned (frame, I387_FIOFF_REGNUM (tdep));
|
||||
foseg = get_frame_register_unsigned (frame, I387_FOSEG_REGNUM (tdep));
|
||||
fooff = get_frame_register_unsigned (frame, I387_FOOFF_REGNUM (tdep));
|
||||
fop = get_frame_register_unsigned (frame, I387_FOP_REGNUM (tdep));
|
||||
fctrl_p = read_frame_register_unsigned (frame,
|
||||
I387_FCTRL_REGNUM (tdep), &fctrl);
|
||||
fstat_p = read_frame_register_unsigned (frame,
|
||||
I387_FSTAT_REGNUM (tdep), &fstat);
|
||||
ftag_p = read_frame_register_unsigned (frame,
|
||||
I387_FTAG_REGNUM (tdep), &ftag);
|
||||
fiseg_p = read_frame_register_unsigned (frame,
|
||||
I387_FISEG_REGNUM (tdep), &fiseg);
|
||||
fioff_p = read_frame_register_unsigned (frame,
|
||||
I387_FIOFF_REGNUM (tdep), &fioff);
|
||||
foseg_p = read_frame_register_unsigned (frame,
|
||||
I387_FOSEG_REGNUM (tdep), &foseg);
|
||||
fooff_p = read_frame_register_unsigned (frame,
|
||||
I387_FOOFF_REGNUM (tdep), &fooff);
|
||||
fop_p = read_frame_register_unsigned (frame,
|
||||
I387_FOP_REGNUM (tdep), &fop);
|
||||
|
||||
top = ((fstat >> 11) & 7);
|
||||
|
||||
for (fpreg = 7; fpreg >= 0; fpreg--)
|
||||
if (fstat_p)
|
||||
{
|
||||
gdb_byte raw[I386_MAX_REGISTER_SIZE];
|
||||
int tag = (ftag >> (fpreg * 2)) & 3;
|
||||
int i;
|
||||
top = ((fstat >> 11) & 7);
|
||||
|
||||
fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg);
|
||||
|
||||
switch (tag)
|
||||
for (fpreg = 7; fpreg >= 0; fpreg--)
|
||||
{
|
||||
case 0:
|
||||
fputs_filtered ("Valid ", file);
|
||||
break;
|
||||
case 1:
|
||||
fputs_filtered ("Zero ", file);
|
||||
break;
|
||||
case 2:
|
||||
fputs_filtered ("Special ", file);
|
||||
break;
|
||||
case 3:
|
||||
fputs_filtered ("Empty ", file);
|
||||
break;
|
||||
struct value *regval;
|
||||
int regnum;
|
||||
int i;
|
||||
int tag = -1;
|
||||
|
||||
fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg);
|
||||
|
||||
if (ftag_p)
|
||||
{
|
||||
tag = (ftag >> (fpreg * 2)) & 3;
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case 0:
|
||||
fputs_filtered ("Valid ", file);
|
||||
break;
|
||||
case 1:
|
||||
fputs_filtered ("Zero ", file);
|
||||
break;
|
||||
case 2:
|
||||
fputs_filtered ("Special ", file);
|
||||
break;
|
||||
case 3:
|
||||
fputs_filtered ("Empty ", file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
fputs_filtered ("Unknown ", file);
|
||||
|
||||
regnum = (fpreg + 8 - top) % 8 + I387_ST0_REGNUM (tdep);
|
||||
regval = get_frame_register_value (frame, regnum);
|
||||
|
||||
if (value_entirely_available (regval))
|
||||
{
|
||||
const char *raw = value_contents (regval);
|
||||
|
||||
fputs_filtered ("0x", file);
|
||||
for (i = 9; i >= 0; i--)
|
||||
fprintf_filtered (file, "%02x", raw[i]);
|
||||
|
||||
if (tag != -1 && tag != 3)
|
||||
print_i387_ext (gdbarch, raw, file);
|
||||
}
|
||||
else
|
||||
fprintf_filtered (file, "%s", _("<unavailable>"));
|
||||
|
||||
fputs_filtered ("\n", file);
|
||||
}
|
||||
|
||||
get_frame_register (frame,
|
||||
(fpreg + 8 - top) % 8 + I387_ST0_REGNUM (tdep),
|
||||
raw);
|
||||
|
||||
fputs_filtered ("0x", file);
|
||||
for (i = 9; i >= 0; i--)
|
||||
fprintf_filtered (file, "%02x", raw[i]);
|
||||
|
||||
if (tag != 3)
|
||||
print_i387_ext (gdbarch, raw, file);
|
||||
|
||||
fputs_filtered ("\n", file);
|
||||
}
|
||||
|
||||
fputs_filtered ("\n", file);
|
||||
|
||||
print_i387_status_word (fstat, file);
|
||||
print_i387_control_word (fctrl, file);
|
||||
print_i387_status_word (fstat_p, fstat, file);
|
||||
print_i387_control_word (fctrl_p, fctrl, file);
|
||||
fprintf_filtered (file, "Tag Word: %s\n",
|
||||
hex_string_custom (ftag, 4));
|
||||
ftag_p ? hex_string_custom (ftag, 4) : _("<unavailable>"));
|
||||
fprintf_filtered (file, "Instruction Pointer: %s:",
|
||||
hex_string_custom (fiseg, 2));
|
||||
fprintf_filtered (file, "%s\n", hex_string_custom (fioff, 8));
|
||||
fiseg_p ? hex_string_custom (fiseg, 2) : _("<unavailable>"));
|
||||
fprintf_filtered (file, "%s\n",
|
||||
fioff_p ? hex_string_custom (fioff, 8) : _("<unavailable>"));
|
||||
fprintf_filtered (file, "Operand Pointer: %s:",
|
||||
hex_string_custom (foseg, 2));
|
||||
fprintf_filtered (file, "%s\n", hex_string_custom (fooff, 8));
|
||||
foseg_p ? hex_string_custom (foseg, 2) : _("<unavailable>"));
|
||||
fprintf_filtered (file, "%s\n",
|
||||
fooff_p ? hex_string_custom (fooff, 8) : _("<unavailable>"));
|
||||
fprintf_filtered (file, "Opcode: %s\n",
|
||||
hex_string_custom (fop ? (fop | 0xd800) : 0, 4));
|
||||
fop_p
|
||||
? (hex_string_custom (fop ? (fop | 0xd800) : 0, 4))
|
||||
: _("<unavailable>"));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,3 +1,10 @@
|
||||
2012-03-01 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/13767
|
||||
|
||||
* gdb.trace/unavailable.exp (gdb_unavailable_floats): New.
|
||||
(gdb_collect_globals_test): Call it.
|
||||
|
||||
2012-03-01 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* gdb.cp/method2.exp: Output of overload menu is now
|
||||
|
@ -305,6 +305,39 @@ proc gdb_unavailable_registers_test { } { with_test_prefix "unavailable register
|
||||
gdb_test "tfind none" "#0 end .*" "cease trace debugging"
|
||||
}}
|
||||
|
||||
proc gdb_unavailable_floats { } {
|
||||
global gdb_prompt
|
||||
|
||||
with_test_prefix "unavailable floats" {
|
||||
prepare_for_trace_test
|
||||
|
||||
# We'll simply re-use the globals_test_function for this test
|
||||
gdb_test "trace globals_test_func" \
|
||||
"Tracepoint \[0-9\]+ at .*" \
|
||||
"set tracepoint"
|
||||
|
||||
# Collect nothing.
|
||||
|
||||
# Begin the test.
|
||||
run_trace_experiment globals_test_func
|
||||
|
||||
# Necessarily target specific.
|
||||
if {[istarget "x86_64-*-*"] || [istarget i?86-*]} {
|
||||
send_gdb "info float\n"
|
||||
gdb_expect_list "info float" ".*$gdb_prompt $" {
|
||||
"Status Word: <unavailable>"
|
||||
"Control Word: <unavailable>"
|
||||
"Tag Word: <unavailable>"
|
||||
"Instruction Pointer: <unavailable>:<unavailable>"
|
||||
"Operand Pointer: <unavailable>:<unavailable>"
|
||||
"Opcode: <unavailable>"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "tfind none" "#0 end .*" "cease trace debugging"
|
||||
}
|
||||
}
|
||||
|
||||
proc gdb_collect_globals_test { } { with_test_prefix "collect globals" {
|
||||
global ws
|
||||
global cr
|
||||
@ -547,6 +580,7 @@ proc gdb_collect_globals_test { } { with_test_prefix "collect globals" {
|
||||
proc gdb_trace_collection_test {} {
|
||||
gdb_collect_globals_test
|
||||
gdb_unavailable_registers_test
|
||||
gdb_unavailable_floats
|
||||
|
||||
gdb_collect_args_test
|
||||
gdb_collect_locals_test local_test_func "auto locals"
|
||||
|
Loading…
Reference in New Issue
Block a user