* RFC: partially available registers
@ 2011-07-13 20:17 Tom Tromey
2011-07-14 4:24 ` Daniel Jacobowitz
0 siblings, 1 reply; 28+ messages in thread
From: Tom Tromey @ 2011-07-13 20:17 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2243 bytes --]
I have a test case (I've attached the C source) which exhibits bad
behavior in gdb on x86-64:
(gdb) b 30
Breakpoint 1 at 0x400463: file typeddwarf.c, line 30.
(gdb) r
Starting program: /tmp/t
Breakpoint 1, f1 (a=<unavailable>, b=<unavailable>, c=<unavailable>,
d=<unavailable>, e=<unavailable>, f=6, g=7, h=8, i=9) at typeddwarf.c:30
30 }
(gdb) p s
$1 = <unavailable>
However, 's' is not really unavailable:
(gdb) info addr s
Symbol "s" is a complex DWARF expression:
0: DW_OP_GNU_regval_type<double [0x2d]> [$xmm2]
3: DW_OP_GNU_convert<long int [0x42]>
5: DW_OP_GNU_convert<0>
7: DW_OP_stack_value
.
(gdb) p (long) $xmm2.v2_double[0]
$3 = 3
The issue here is that DWARF uses the same register numbers for the XMM
and YMM registers, and in this case the high parts of the YMM registers
are unavailable. This causes the special code in
i386_pseudo_register_read for YMM to return REG_UNAVAILABLE.
This patch fixes the problem by letting an arch register a new
pseudo_register_read_value method, which is responsible for constructing
a struct value for the register. This gives us a chance to mark
just some bits unavailable.
With the modified gdb, the test works:
(gdb) b 30
Breakpoint 1 at 0x400463: file typeddwarf.c, line 30.
(gdb) r
Starting program: /tmp/t
Breakpoint 1, f1 (a=1, b=2, c=3, d=4, e=5, f=6, g=7, h=8, i=9)
at typeddwarf.c:30
30 }
(gdb) p s
$1 = 3
I would appreciate feedback on this patch.
I considered several other approaches:
* Put the XCR0 bits into the regcache. This would let us dynamically
decide whether to return the XMM or YMM register. This seemed to mean
treating XCR0 as a real register (which AFAICT it is not, right now),
which meant also gdbserver changes.
* Rather than a way to return values, have a different API, say one
where gdb requests the first N bytes of a register. This may still be
cleaner, I am not sure. Optionally this could be the only way,
meaning a patch touching most existing callers.
I don't think this patch yet hits all the spots I would need to change.
E.g., "print $ymm2" shows all fields as <unavailable>, but that is
incorrect.
I'll turn the test case into part of the patch when I finalize this
change.
Tom
[-- Attachment #2: typeddwarf.c --]
[-- Type: text/plain, Size: 3763 bytes --]
/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
/* { dg-options "-g" } */
typedef __SIZE_TYPE__ size_t;
volatile int vv;
extern void *memcpy (void *, const void *, size_t);
__attribute__((noinline, noclone)) void
f1 (double a, double b, double c, float d, float e, int f, unsigned int g, long long h, unsigned long long i)
{
double j = d; /* { dg-final { gdb-test 29 "j" "4" } } */
long long l; /* { dg-final { gdb-test 29 "l" "4616189618054758400" } } */
memcpy (&l, &j, sizeof (l));
long long m; /* { dg-final { gdb-test 29 "m" "4613937818241073152" } } */
memcpy (&m, &c, sizeof (l));
float n = i; /* { dg-final { gdb-test 29 "n" "9" } } */
double o = h; /* { dg-final { gdb-test 29 "o" "8" } } */
float p = g; /* { dg-final { gdb-test 29 "p" "7" } } */
double q = f; /* { dg-final { gdb-test 29 "q" "6" } } */
unsigned long long r = a; /* { dg-final { gdb-test 29 "r" "1" } } */
long long s = c; /* { dg-final { gdb-test 29 "s" "3" } } */
unsigned t = d; /* { dg-final { gdb-test 29 "t" "4" } } */
int u = b; /* { dg-final { gdb-test 29 "u" "2" } } */
float v = a; /* { dg-final { gdb-test 29 "v" "1" } } */
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" } } */
vv++;
}
__attribute__((noinline, noclone)) void
f2 (double a, double b, double c, float d, float e, int f, unsigned int g, long long h, unsigned long long i)
{
double j = d; /* { dg-final { gdb-test 53 "j" "4" } } */
long long l; /* { dg-final { gdb-test 53 "l" "4616189618054758400" } } */
memcpy (&l, &j, sizeof (l));
long long m; /* { dg-final { gdb-test 53 "m" "4613937818241073152" } } */
memcpy (&m, &c, sizeof (l));
float n = i; /* { dg-final { gdb-test 53 "n" "9" } } */
double o = h; /* { dg-final { gdb-test 53 "o" "8" } } */
float p = g; /* { dg-final { gdb-test 53 "p" "7" } } */
double q = f; /* { dg-final { gdb-test 53 "q" "6" } } */
unsigned long long r = a; /* { dg-final { gdb-test 53 "r" "1" } } */
long long s = c; /* { dg-final { gdb-test 53 "s" "3" } } */
unsigned t = d; /* { dg-final { gdb-test 53 "t" "4" } } */
int u = b; /* { dg-final { gdb-test 53 "u" "2" } } */
float v = a; /* { dg-final { gdb-test 53 "v" "1" } } */
double w = d / 4.0; /* { dg-final { gdb-test 53 "w" "1" } } */
double x = a + b - 3 + 1.0e20;/* { dg-final { gdb-test 53 "x" "1e+20" } } */
double y = b + c * 7.0; /* { dg-final { gdb-test 53 "y" "23" } } */
float z = d + e + 3.0f; /* { dg-final { gdb-test 53 "z" "12" } } */
vv++;
vv = a;
vv = b;
vv = c;
vv = d;
vv = e;
vv = f;
vv = g;
vv = h;
vv = i;
vv = j;
}
__attribute__((noinline, noclone)) void
f3 (long long a, int b, long long c, unsigned d)
{
long long w = (a > d) ? a : d;/* { dg-final { gdb-test 73 "w" "4" } } */
long long x = a + b + 7; /* { dg-final { gdb-test 73 "x" "10" } } */
long long y = c + d + 0x912345678LL;/* { dg-final { gdb-test 73 "y" "38960125567" } } */
int z = (x + y); /* { dg-final { gdb-test 73 "z" "305419913" } } */
vv++;
}
__attribute__((noinline, noclone)) void
f4 (_Decimal32 a, _Decimal64 b, _Decimal128 c)
{
_Decimal32 w = a * 8.0DF + 6.0DF;/* { dg-final { gdb-test 82 "(int)w" "70" } } */
_Decimal64 x = b / 8.0DD - 6.0DD;/* { dg-final { gdb-test 82 "(int)x" "-4" } } */
_Decimal128 y = -c / 8.0DL; /* { dg-final { gdb-test 82 "(int)y" "-8" } } */
vv++;
}
int
main ()
{
f1 (1.0, 2.0, 3.0, 4.0f, 5.0f, 6, 7, 8, 9);
f2 (1.0, 2.0, 3.0, 4.0f, 5.0f, 6, 7, 8, 9);
f3 (1, 2, 3, 4);
f4 (8.0DF, 16.0DD, 64.0DL);
return 0;
}
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: the patch --]
[-- Type: text/x-patch, Size: 11893 bytes --]
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4062bf9..b404878 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,20 @@
2011-07-13 Tom Tromey <tromey@redhat.com>
+ * sentinel-frame.c (sentinel_frame_prev_register): Use
+ regcache_cooked_read_into_value.
+ * regcache.h (regcache_cooked_read_into_value): Declare.
+ * regcache.c (regcache_cooked_read_into_value): New function.
+ * i386-tdep.h (i386_pseudo_register_read_value): Declare.
+ * i386-tdep.c (i386_pseudo_register_read_value): New function.
+ (i386_gdbarch_init): Call set_gdbarch_pseudo_register_read_value.
+ * gdbarch.sh (pseudo_register_read_value): New method.
+ * gdbarch.c, gdbarch.h: Rebuild.
+ * findvar.c (value_from_register): Call get_frame_register_value.
+ * amd64-tdep.c (amd64_init_abi): Call
+ set_gdbarch_pseudo_register_read_value.
+
+2011-07-13 Tom Tromey <tromey@redhat.com>
+
* dwarf2expr.c (execute_stack_op) <DW_OP_GNU_regval_type>: Use
value_from_contents for final conversion.
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index de62ac7..c728b53 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -2496,6 +2496,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_pseudo_register_read (gdbarch,
amd64_pseudo_register_read);
+ set_gdbarch_pseudo_register_read_value (gdbarch,
+ i386_pseudo_register_read_value);
set_gdbarch_pseudo_register_write (gdbarch,
amd64_pseudo_register_write);
diff --git a/gdb/findvar.c b/gdb/findvar.c
index a700c02..59e86ef 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -647,14 +647,16 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame)
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);
+
+ value_contents_copy (v, 0, v2, 0, len);
+ ok = 1;
}
if (!ok)
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 1e65c17..0c1bcf0 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -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");
@@ -1085,6 +1088,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *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));
fprintf_unfiltered (file,
@@ -1700,6 +1709,30 @@ set_gdbarch_pseudo_register_read (struct gdbarch *gdbarch,
}
int
+gdbarch_pseudo_register_read_value_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->pseudo_register_read_value != NULL;
+}
+
+int
+gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, struct value *result)
+{
+ 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, result);
+}
+
+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)
{
gdb_assert (gdbarch != NULL);
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 50221d7..5f99ded 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -216,6 +216,12 @@ 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);
+extern int gdbarch_pseudo_register_read_value_p (struct gdbarch *gdbarch);
+
+typedef int (gdbarch_pseudo_register_read_value_ftype) (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, struct value *result);
+extern int gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, struct value *result);
+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);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index a628f8c..1e2ad53 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -418,6 +418,7 @@ 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
+M:int:pseudo_register_read_value:struct regcache *regcache, int cookednum, struct value *result:regcache, cookednum, result
M:void:pseudo_register_write:struct regcache *regcache, int cookednum, const gdb_byte *buf:regcache, cookednum, buf
#
v:int:num_regs:::0:-1
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 366d0fa..7a16b4a 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -2854,6 +2854,47 @@ i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
return REG_VALID;
}
+int
+i386_pseudo_register_read_value (struct gdbarch *gdbarch,
+ struct regcache *regcache,
+ int regnum,
+ struct value *result)
+{
+ gdb_byte raw_buf[MAX_REGISTER_SIZE];
+ gdb_byte *buf;
+ struct gdbarch_tdep *tdep;
+ enum register_status status;
+
+ if (!i386_ymm_regnum_p (gdbarch, regnum))
+ return 0;
+
+ tdep = gdbarch_tdep (gdbarch);
+ buf = value_contents_raw (result);
+
+ regnum -= tdep->ymm0_regnum;
+
+ /* Extract (always little endian). Read lower 128bits. */
+ status = regcache_raw_read (regcache,
+ I387_XMM0_REGNUM (tdep) + regnum,
+ raw_buf);
+
+ if (status != REG_VALID)
+ mark_value_bytes_unavailable (result, 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)
+ mark_value_bytes_unavailable (result, 16, 32);
+ else
+ memcpy (buf + 16, raw_buf, 16);
+
+ return 1;
+}
+
void
i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
int regnum, const gdb_byte *buf)
@@ -7334,6 +7375,8 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* 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);
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index 7fc719c..97fa258 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -315,6 +315,12 @@ extern enum register_status i386_pseudo_register_read (struct gdbarch *gdbarch,
struct regcache *regcache,
int regnum,
gdb_byte *buf);
+
+extern int i386_pseudo_register_read_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);
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 41f218d..2ddcd4c 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -714,6 +714,23 @@ regcache_cooked_read (struct regcache *regcache, int regnum, gdb_byte *buf)
regnum, buf);
}
+void
+regcache_cooked_read_into_value (struct regcache *regcache, int regnum,
+ struct value *result)
+{
+ gdb_assert (regnum >= 0);
+ gdb_assert (regnum < regcache->descr->nr_cooked_registers);
+ if (!gdbarch_pseudo_register_read_value_p (regcache->descr->gdbarch)
+ || !gdbarch_pseudo_register_read_value (regcache->descr->gdbarch,
+ regcache, regnum, result))
+ {
+ if (regcache_cooked_read (regcache, regnum,
+ value_contents_raw (result)) == REG_UNAVAILABLE)
+ mark_value_bytes_unavailable (result, 0,
+ TYPE_LENGTH (value_type (result)));
+ }
+}
+
enum register_status
regcache_cooked_read_signed (struct regcache *regcache, int regnum,
LONGEST *val)
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 3708c86..01ee30b 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -104,6 +104,9 @@ enum register_status regcache_cooked_read (struct regcache *regcache,
void regcache_cooked_write (struct regcache *regcache, int rawnum,
const gdb_byte *buf);
+void regcache_cooked_read_into_value (struct regcache *regcache, int regnum,
+ struct value *result);
+
/* Read a register as a signed/unsigned quantity. */
extern enum register_status
regcache_cooked_read_signed (struct regcache *regcache,
diff --git a/gdb/sentinel-frame.c b/gdb/sentinel-frame.c
index 6c2f3e0..53d82ba 100644
--- a/gdb/sentinel-frame.c
+++ b/gdb/sentinel-frame.c
@@ -62,10 +62,7 @@ sentinel_frame_prev_register (struct frame_info *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));
+ regcache_cooked_read_into_value (cache->regcache, regnum, value);
return value;
}
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-13 20:17 RFC: partially available registers Tom Tromey
@ 2011-07-14 4:24 ` Daniel Jacobowitz
2011-07-15 20:52 ` Tom Tromey
0 siblings, 1 reply; 28+ messages in thread
From: Daniel Jacobowitz @ 2011-07-14 4:24 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
I'm too stale to properly review this patch, but I have some comments.
On Wed, Jul 13, 2011 at 1:44 PM, Tom Tromey <tromey@redhat.com> wrote:
> This patch fixes the problem by letting an arch register a new
> pseudo_register_read_value method, which is responsible for constructing
> a struct value for the register. This gives us a chance to mark
> just some bits unavailable.
I think this is the right approach. We should move more towards
values, not away; in particular, I do not prefer this alternative:
> * Rather than a way to return values, have a different API, say one
> where gdb requests the first N bytes of a register.
As for the patch itself:
* Some documentation on the gdbarch method would be nice, in
particular, the return value. Does 0 mean "not a pseudo"?
* Stale comment in sentinel_frame_prev_register.
* I am not happy about having to implement both
gdbarch_pseudo_register_read and gdbarch_pseudo_register_read_value,
depending on which regcache read function was called. So for a final
version, is it practical to push this down and only call the value
version if it is registered? That means implementing the existing
regcache read in terms of the new one, instead of the other way
around.
--
Thanks,
Daniel
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-14 4:24 ` Daniel Jacobowitz
@ 2011-07-15 20:52 ` Tom Tromey
2011-07-18 4:15 ` Daniel Jacobowitz
` (2 more replies)
0 siblings, 3 replies; 28+ messages in thread
From: Tom Tromey @ 2011-07-15 20:52 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
>>>>> "Daniel" == Daniel Jacobowitz <drow@false.org> writes:
Daniel> As for the patch itself:
Daniel> * Some documentation on the gdbarch method would be nice, in
Daniel> particular, the return value. Does 0 mean "not a pseudo"?
Yeah, I left that out for the initial change, but I think I shouldn't
have.
I find gdbarch.sh very hard to read. Does anybody else?
Daniel> * I am not happy about having to implement both
Daniel> gdbarch_pseudo_register_read and gdbarch_pseudo_register_read_value,
Daniel> depending on which regcache read function was called. So for a final
Daniel> version, is it practical to push this down and only call the value
Daniel> version if it is registered? That means implementing the existing
Daniel> regcache read in terms of the new one, instead of the other way
Daniel> around.
I will look at it. Thanks for looking at this.
Tom
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-15 20:52 ` Tom Tromey
@ 2011-07-18 4:15 ` Daniel Jacobowitz
2011-07-20 20:14 ` Pedro Alves
2011-07-20 18:49 ` Sergio Durigan Junior
2011-07-20 20:46 ` Tom Tromey
2 siblings, 1 reply; 28+ messages in thread
From: Daniel Jacobowitz @ 2011-07-18 4:15 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
On Fri, Jul 15, 2011 at 4:48 PM, Tom Tromey <tromey@redhat.com> wrote:
>>>>>> "Daniel" == Daniel Jacobowitz <drow@false.org> writes:
>
> Daniel> As for the patch itself:
> Daniel> * Some documentation on the gdbarch method would be nice, in
> Daniel> particular, the return value. Does 0 mean "not a pseudo"?
>
> Yeah, I left that out for the initial change, but I think I shouldn't
> have.
>
> I find gdbarch.sh very hard to read. Does anybody else?
Incredibly. Someone please flip us to C++ and use a normal construct
for this...
--
Thanks,
Daniel
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-15 20:52 ` Tom Tromey
2011-07-18 4:15 ` Daniel Jacobowitz
@ 2011-07-20 18:49 ` Sergio Durigan Junior
2011-07-20 20:46 ` Tom Tromey
2 siblings, 0 replies; 28+ messages in thread
From: Sergio Durigan Junior @ 2011-07-20 18:49 UTC (permalink / raw)
To: Tom Tromey; +Cc: Daniel Jacobowitz, gdb-patches
Tom Tromey <tromey@redhat.com> writes:
> I find gdbarch.sh very hard to read. Does anybody else?
FWIW, me too (remembering the `catch syscall' days...).
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-18 4:15 ` Daniel Jacobowitz
@ 2011-07-20 20:14 ` Pedro Alves
0 siblings, 0 replies; 28+ messages in thread
From: Pedro Alves @ 2011-07-20 20:14 UTC (permalink / raw)
To: gdb-patches; +Cc: Daniel Jacobowitz, Tom Tromey
On Sunday 17 July 2011 21:26:17, Daniel Jacobowitz wrote:
> On Fri, Jul 15, 2011 at 4:48 PM, Tom Tromey <tromey@redhat.com> wrote:
> >>>>>> "Daniel" == Daniel Jacobowitz <drow@false.org> writes:
> >
> > Daniel> As for the patch itself:
> > Daniel> * Some documentation on the gdbarch method would be nice, in
> > Daniel> particular, the return value. Does 0 mean "not a pseudo"?
> >
> > Yeah, I left that out for the initial change, but I think I shouldn't
> > have.
> >
> > I find gdbarch.sh very hard to read. Does anybody else?
>
> Incredibly. Someone please flip us to C++ and use a normal construct
> for this...
Hey, gcc flipped this week. We're running behind already. :-)
--
Pedro Alves
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-15 20:52 ` Tom Tromey
2011-07-18 4:15 ` Daniel Jacobowitz
2011-07-20 18:49 ` Sergio Durigan Junior
@ 2011-07-20 20:46 ` Tom Tromey
2011-07-20 20:53 ` Tom Tromey
` (2 more replies)
2 siblings, 3 replies; 28+ messages in thread
From: Tom Tromey @ 2011-07-20 20:46 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Daniel> * I am not happy about having to implement both
Daniel> gdbarch_pseudo_register_read and gdbarch_pseudo_register_read_value,
Daniel> depending on which regcache read function was called. So for a final
Daniel> version, is it practical to push this down and only call the value
Daniel> version if it is registered? That means implementing the existing
Daniel> regcache read in terms of the new one, instead of the other way
Daniel> around.
Tom> I will look at it. Thanks for looking at this.
I looked into this, and I changed some things, but I did not change it
completely.
One thing I did change is that I made pseudo_register_read_into_value a
full replacement for pseudo_register_read. A target should either
define one or the other. I switched i386 and amd64 to the _value form.
I didn't rewrite regcache_cooked_read in terms of
regcache_cooked_read_into_value, because that is less efficient than
the reverse.
Tom
2011-07-20 Tom Tromey <tromey@redhat.com>
* amd64-tdep.c (amd64_pseudo_register_read_into_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_into_value.
* regcache.h (regcache_cooked_read_into_value): Declare.
* regcache.c (regcache_cooked_read_into_value): New function.
(regcache_cooked_read): Call
gdbarch_pseudo_register_read_into_value if available.
* i386-tdep.h (i386_pseudo_register_read_into_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_gdbarch_init): Call
set_gdbarch_pseudo_register_read_into_value, not
set_gdbarch_pseudo_register_read.
* gdbarch.sh (pseudo_register_read_into_value): New method.
* gdbarch.c, gdbarch.h: Rebuild.
* findvar.c (value_from_register): Call get_frame_register_value.
2011-07-20 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.
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index de62ac7..9a55f01 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -275,11 +275,13 @@ 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 void
+amd64_pseudo_register_read_into_value (struct gdbarch *gdbarch,
+ struct regcache *regcache,
+ int regnum,
+ struct value *result_value)
{
+ gdb_byte *buf = value_contents_raw (result_value);
gdb_byte raw_buf[MAX_REGISTER_SIZE];
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
enum register_status status;
@@ -297,15 +299,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 +320,13 @@ 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);
}
static void
@@ -2494,8 +2502,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_into_value (gdbarch,
+ amd64_pseudo_register_read_into_value);
set_gdbarch_pseudo_register_write (gdbarch,
amd64_pseudo_register_write);
diff --git a/gdb/findvar.c b/gdb/findvar.c
index a700c02..59e86ef 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -647,14 +647,16 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame)
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);
+
+ value_contents_copy (v, 0, v2, 0, len);
+ ok = 1;
}
if (!ok)
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 1e65c17..31b341a 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -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_into_value_ftype *pseudo_register_read_into_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_into_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_into_value, has predicate. */
/* Skip verify of pseudo_register_write, has predicate. */
if (gdbarch->num_regs == -1)
fprintf_unfiltered (log, "\n\tnum_regs");
@@ -1085,6 +1088,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *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_into_value_p() = %d\n",
+ gdbarch_pseudo_register_read_into_value_p (gdbarch));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: pseudo_register_read_into_value = <%s>\n",
+ host_address_to_string (gdbarch->pseudo_register_read_into_value));
+ fprintf_unfiltered (file,
"gdbarch_dump: gdbarch_pseudo_register_write_p() = %d\n",
gdbarch_pseudo_register_write_p (gdbarch));
fprintf_unfiltered (file,
@@ -1700,6 +1709,30 @@ set_gdbarch_pseudo_register_read (struct gdbarch *gdbarch,
}
int
+gdbarch_pseudo_register_read_into_value_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->pseudo_register_read_into_value != NULL;
+}
+
+void
+gdbarch_pseudo_register_read_into_value (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, struct value *result)
+{
+ gdb_assert (gdbarch != NULL);
+ gdb_assert (gdbarch->pseudo_register_read_into_value != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_pseudo_register_read_into_value called\n");
+ gdbarch->pseudo_register_read_into_value (gdbarch, regcache, cookednum, result);
+}
+
+void
+set_gdbarch_pseudo_register_read_into_value (struct gdbarch *gdbarch,
+ gdbarch_pseudo_register_read_into_value_ftype pseudo_register_read_into_value)
+{
+ gdbarch->pseudo_register_read_into_value = pseudo_register_read_into_value;
+}
+
+int
gdbarch_pseudo_register_write_p (struct gdbarch *gdbarch)
{
gdb_assert (gdbarch != NULL);
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 50221d7..bf4f03d 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -216,6 +216,18 @@ 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 struct value. The value is already
+ allocated, only its contents must be updated. 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_into_value_p (struct gdbarch *gdbarch);
+
+typedef void (gdbarch_pseudo_register_read_into_value_ftype) (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, struct value *result);
+extern void gdbarch_pseudo_register_read_into_value (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, struct value *result);
+extern void set_gdbarch_pseudo_register_read_into_value (struct gdbarch *gdbarch, gdbarch_pseudo_register_read_into_value_ftype *pseudo_register_read_into_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);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index a628f8c..b8d2de8 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -418,6 +418,12 @@ 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 struct value. The value is already
+# allocated, only its contents must be updated. 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:void:pseudo_register_read_into_value:struct regcache *regcache, int cookednum, struct value *result:regcache, cookednum, result
M:void:pseudo_register_write:struct regcache *regcache, int cookednum, const gdb_byte *buf:regcache, cookednum, buf
#
v:int:num_regs:::0:-1
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 366d0fa..aa81303 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -2780,12 +2780,15 @@ 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)
+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 +2797,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 +2815,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 +2834,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 +2850,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 +2860,6 @@ i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
else
internal_error (__FILE__, __LINE__, _("invalid regnum"));
}
-
- return REG_VALID;
}
void
@@ -7333,7 +7341,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_into_value (gdbarch,
+ i386_pseudo_register_read_into_value);
set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write);
set_tdesc_pseudo_register_type (gdbarch, i386_pseudo_register_type);
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index 7fc719c..de11f68 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -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);
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 41f218d..258e8a6 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -709,11 +709,62 @@ regcache_cooked_read (struct regcache *regcache, int regnum, gdb_byte *buf)
return regcache->register_status[regnum];
}
+ else if (gdbarch_pseudo_register_read_into_value_p (regcache->descr->gdbarch))
+ {
+ struct value *mark, *computed;
+ enum register_status result = REG_VALID;
+
+ mark = value_mark ();
+ computed = allocate_value (register_type (regcache->descr->gdbarch,
+ regnum));
+ VALUE_LVAL (computed) = lval_register;
+ VALUE_REGNUM (computed) = regnum;
+
+ gdbarch_pseudo_register_read_into_value (regcache->descr->gdbarch,
+ regcache, regnum, computed);
+ 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);
}
+void
+regcache_cooked_read_into_value (struct regcache *regcache, int regnum,
+ struct value *result)
+{
+ 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_into_value_p (regcache->descr->gdbarch))
+ {
+ /* 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)));
+ }
+ else
+ gdbarch_pseudo_register_read_into_value (regcache->descr->gdbarch,
+ regcache, regnum, result);
+}
+
enum register_status
regcache_cooked_read_signed (struct regcache *regcache, int regnum,
LONGEST *val)
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 3708c86..417575c 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -104,6 +104,13 @@ 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 into an already-allocated value,
+ RESULT. This will fill in the contents of RESULT and, if
+ necessary, call mark_value_bytes_unavailable as appropriate. */
+
+void regcache_cooked_read_into_value (struct regcache *regcache, int regnum,
+ struct value *result);
+
/* Read a register as a signed/unsigned quantity. */
extern enum register_status
regcache_cooked_read_signed (struct regcache *regcache,
diff --git a/gdb/sentinel-frame.c b/gdb/sentinel-frame.c
index 6c2f3e0..86814af 100644
--- a/gdb/sentinel-frame.c
+++ b/gdb/sentinel-frame.c
@@ -59,13 +59,7 @@ sentinel_frame_prev_register (struct frame_info *this_frame,
VALUE_REGNUM (value) = 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));
+ regcache_cooked_read_into_value (cache->regcache, regnum, value);
return value;
}
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf-amd64.S b/gdb/testsuite/gdb.dwarf2/typeddwarf-amd64.S
new file mode 100644
index 0000000..f97357a
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf-amd64.S
@@ -0,0 +1,1568 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* This source file was generated from typeddwarf.c using the following
+ command line:
+
+ gcc -S -g -O2 typeddwarf.c -o typeddwarf-amd64.S
+
+*/
+
+
+ .file "typeddwarf.c"
+ .text
+.Ltext0:
+ .globl f1
+ .type f1, @function
+f1:
+.LFB0:
+ .file 1 "typeddwarf.c"
+ .loc 1 10 0
+ .cfi_startproc
+.LVL0:
+ .loc 1 29 0
+ movl vv(%rip), %eax
+ addl $1, %eax
+ movl %eax, vv(%rip)
+ .loc 1 30 0
+ ret
+ .cfi_endproc
+.LFE0:
+ .size f1, .-f1
+ .globl f2
+ .type f2, @function
+f2:
+.LFB1:
+ .loc 1 34 0
+ .cfi_startproc
+.LVL1:
+ .loc 1 53 0
+ movl vv(%rip), %eax
+ addl $1, %eax
+ movl %eax, vv(%rip)
+ .loc 1 54 0
+ cvttsd2si %xmm0, %eax
+ movl %eax, vv(%rip)
+ .loc 1 55 0
+ cvttsd2si %xmm1, %eax
+ movl %eax, vv(%rip)
+ .loc 1 56 0
+ cvttsd2si %xmm2, %eax
+ movl %eax, vv(%rip)
+ .loc 1 57 0
+ cvttss2si %xmm3, %eax
+ movl %eax, vv(%rip)
+ .loc 1 58 0
+ cvttss2si %xmm4, %r8d
+ movl %r8d, vv(%rip)
+ .loc 1 59 0
+ movl %edi, vv(%rip)
+ .loc 1 60 0
+ movl %esi, vv(%rip)
+ .loc 1 61 0
+ movl %edx, vv(%rip)
+ .loc 1 62 0
+ movl %ecx, vv(%rip)
+ .loc 1 63 0
+ movl %eax, vv(%rip)
+ .loc 1 64 0
+ ret
+ .cfi_endproc
+.LFE1:
+ .size f2, .-f2
+ .globl f3
+ .type f3, @function
+f3:
+.LFB2:
+ .loc 1 68 0
+ .cfi_startproc
+.LVL2:
+ .loc 1 73 0
+ movl vv(%rip), %eax
+ addl $1, %eax
+ movl %eax, vv(%rip)
+ .loc 1 74 0
+ ret
+ .cfi_endproc
+.LFE2:
+ .size f3, .-f3
+ .globl f4
+ .type f4, @function
+f4:
+.LFB3:
+ .loc 1 78 0
+ .cfi_startproc
+.LVL3:
+ .loc 1 82 0
+ movl vv(%rip), %eax
+ addl $1, %eax
+ movl %eax, vv(%rip)
+ .loc 1 83 0
+ ret
+ .cfi_endproc
+.LFE3:
+ .size f4, .-f4
+ .globl _start
+ .type _start, @function
+_start:
+.LFB4:
+ .loc 1 87 0
+ .cfi_startproc
+ subq $8, %rsp
+.LCFI0:
+ .cfi_def_cfa_offset 16
+ .loc 1 88 0
+ movl $9, %ecx
+ movl $8, %edx
+ movl $7, %esi
+ movl $6, %edi
+ movss .LC2(%rip), %xmm4
+ movss .LC3(%rip), %xmm3
+ movsd .LC0(%rip), %xmm2
+ movsd .LC1(%rip), %xmm1
+ movsd .LC4(%rip), %xmm0
+ call f1
+.LVL4:
+ .loc 1 89 0
+ movl $9, %ecx
+ movl $8, %edx
+ movl $7, %esi
+ movl $6, %edi
+ movss .LC2(%rip), %xmm4
+ movss .LC3(%rip), %xmm3
+ movsd .LC0(%rip), %xmm2
+ movsd .LC1(%rip), %xmm1
+ movsd .LC4(%rip), %xmm0
+ call f2
+.LVL5:
+ .loc 1 90 0
+ movl $4, %ecx
+ movl $3, %edx
+ movl $2, %esi
+ movl $1, %edi
+ call f3
+.LVL6:
+ .loc 1 91 0
+ movdqa .LC5(%rip), %xmm2
+ movq .LC6(%rip), %xmm1
+ movd .LC7(%rip), %xmm0
+ call f4
+.LVL7:
+ .loc 1 93 0
+ movl $0, %eax
+ addq $8, %rsp
+.LCFI1:
+ .cfi_def_cfa_offset 8
+ ret
+ .cfi_endproc
+.LFE4:
+ .size _start, .-_start
+ .comm vv,4,4
+ .section .rodata.cst8,"aM",@progbits,8
+ .align 8
+.LC0:
+ .long 0
+ .long 1074266112
+ .align 8
+.LC1:
+ .long 0
+ .long 1073741824
+ .section .rodata.cst4,"aM",@progbits,4
+ .align 4
+.LC2:
+ .long 1084227584
+ .align 4
+.LC3:
+ .long 1082130432
+ .section .rodata.cst8
+ .align 8
+.LC4:
+ .long 0
+ .long 1072693248
+ .section .rodata.cst16,"aM",@progbits,16
+ .align 16
+.LC5:
+ .quad 640
+ .quad 3476215962376601600
+ .section .rodata.cst8
+ .align 8
+.LC6:
+ .quad 3575858104132173984
+ .section .rodata.cst4
+ .align 4
+.LC7:
+ .long 838860880
+ .text
+.Letext0:
+ .section .debug_info,"",@progbits
+.Ldebug_info0:
+ .long 0x6c4
+ .value 0x2
+ .long .Ldebug_abbrev0
+ .byte 0x8
+ .uleb128 0x1
+ .long .LASF8
+ .byte 0x1
+ .long .LASF9
+ .long .LASF10
+ .quad .Ltext0
+ .quad .Letext0
+ .long .Ldebug_line0
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0x4
+ .long .LASF0
+ .uleb128 0x2
+ .byte 0x4
+ .byte 0x4
+ .long .LASF1
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0x7
+ .long .LASF2
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0x5
+ .long .LASF3
+ .uleb128 0x2
+ .byte 0x4
+ .byte 0x7
+ .long .LASF4
+ .uleb128 0x3
+ .byte 0x4
+ .byte 0x5
+ .string "int"
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0xf
+ .long .LASF5
+ .uleb128 0x2
+ .byte 0x4
+ .byte 0xf
+ .long .LASF6
+ .uleb128 0x2
+ .byte 0x10
+ .byte 0xf
+ .long .LASF7
+ .uleb128 0x4
+ .byte 0x1
+ .string "f1"
+ .byte 0x1
+ .byte 0x9
+ .byte 0x1
+ .quad .LFB0
+ .quad .LFE0
+ .byte 0x2
+ .byte 0x77
+ .sleb128 8
+ .byte 0x1
+ .long 0x22b
+ .uleb128 0x5
+ .string "a"
+ .byte 0x1
+ .byte 0x9
+ .long 0x2d
+ .byte 0x1
+ .byte 0x61
+ .uleb128 0x5
+ .string "b"
+ .byte 0x1
+ .byte 0x9
+ .long 0x2d
+ .byte 0x1
+ .byte 0x62
+ .uleb128 0x5
+ .string "c"
+ .byte 0x1
+ .byte 0x9
+ .long 0x2d
+ .byte 0x1
+ .byte 0x63
+ .uleb128 0x5
+ .string "d"
+ .byte 0x1
+ .byte 0x9
+ .long 0x34
+ .byte 0x1
+ .byte 0x64
+ .uleb128 0x5
+ .string "e"
+ .byte 0x1
+ .byte 0x9
+ .long 0x34
+ .byte 0x1
+ .byte 0x65
+ .uleb128 0x5
+ .string "f"
+ .byte 0x1
+ .byte 0x9
+ .long 0x50
+ .byte 0x1
+ .byte 0x55
+ .uleb128 0x5
+ .string "g"
+ .byte 0x1
+ .byte 0x9
+ .long 0x49
+ .byte 0x1
+ .byte 0x54
+ .uleb128 0x5
+ .string "h"
+ .byte 0x1
+ .byte 0x9
+ .long 0x22b
+ .byte 0x1
+ .byte 0x51
+ .uleb128 0x5
+ .string "i"
+ .byte 0x1
+ .byte 0x9
+ .long 0x232
+ .byte 0x1
+ .byte 0x52
+ .uleb128 0x6
+ .string "j"
+ .byte 0x1
+ .byte 0xb
+ .long 0x2d
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "l"
+ .byte 0x1
+ .byte 0xc
+ .long 0x22b
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0xf9
+ .uleb128 0x3b
+ .byte 0x9f
+ .uleb128 0x6
+ .string "m"
+ .byte 0x1
+ .byte 0xe
+ .long 0x22b
+ .byte 0x1
+ .byte 0x63
+ .uleb128 0x6
+ .string "n"
+ .byte 0x1
+ .byte 0x10
+ .long 0x34
+ .byte 0x7
+ .byte 0x72
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x3b
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "o"
+ .byte 0x1
+ .byte 0x11
+ .long 0x2d
+ .byte 0x7
+ .byte 0x71
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x42
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "p"
+ .byte 0x1
+ .byte 0x12
+ .long 0x34
+ .byte 0x7
+ .byte 0x74
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x49
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "q"
+ .byte 0x1
+ .byte 0x13
+ .long 0x2d
+ .byte 0x7
+ .byte 0x75
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x50
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "r"
+ .byte 0x1
+ .byte 0x14
+ .long 0x232
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x3b
+ .byte 0x9f
+ .uleb128 0x6
+ .string "s"
+ .byte 0x1
+ .byte 0x15
+ .long 0x22b
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x13
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x42
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "t"
+ .byte 0x1
+ .byte 0x16
+ .long 0x49
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x49
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "u"
+ .byte 0x1
+ .byte 0x17
+ .long 0x50
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x50
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "v"
+ .byte 0x1
+ .byte 0x18
+ .long 0x34
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "w"
+ .byte 0x1
+ .byte 0x19
+ .long 0x2d
+ .byte 0x12
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x3fd00000
+ .byte 0x1e
+ .byte 0x9f
+ .uleb128 0x6
+ .string "x"
+ .byte 0x1
+ .byte 0x1a
+ .long 0x2d
+ .byte 0x14
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0x22
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x3ff00000
+ .byte 0x22
+ .byte 0x9f
+ .uleb128 0x6
+ .string "y"
+ .byte 0x1
+ .byte 0x1b
+ .long 0x2d
+ .byte 0x14
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0xf5
+ .uleb128 0x13
+ .uleb128 0x2d
+ .byte 0x22
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40000000
+ .byte 0x22
+ .byte 0x9f
+ .uleb128 0x6
+ .string "z"
+ .byte 0x1
+ .byte 0x1c
+ .long 0x34
+ .byte 0x12
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf3
+ .uleb128 0x3
+ .byte 0xf5
+ .uleb128 0x15
+ .uleb128 0x34
+ .byte 0x22
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40400000
+ .byte 0x22
+ .byte 0x9f
+ .byte 0
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0x5
+ .long .LASF11
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0x7
+ .long .LASF12
+ .uleb128 0x4
+ .byte 0x1
+ .string "f2"
+ .byte 0x1
+ .byte 0x21
+ .byte 0x1
+ .quad .LFB1
+ .quad .LFE1
+ .byte 0x2
+ .byte 0x77
+ .sleb128 8
+ .byte 0x1
+ .long 0x402
+ .uleb128 0x5
+ .string "a"
+ .byte 0x1
+ .byte 0x21
+ .long 0x2d
+ .byte 0x1
+ .byte 0x61
+ .uleb128 0x5
+ .string "b"
+ .byte 0x1
+ .byte 0x21
+ .long 0x2d
+ .byte 0x1
+ .byte 0x62
+ .uleb128 0x5
+ .string "c"
+ .byte 0x1
+ .byte 0x21
+ .long 0x2d
+ .byte 0x1
+ .byte 0x63
+ .uleb128 0x5
+ .string "d"
+ .byte 0x1
+ .byte 0x21
+ .long 0x34
+ .byte 0x1
+ .byte 0x64
+ .uleb128 0x5
+ .string "e"
+ .byte 0x1
+ .byte 0x21
+ .long 0x34
+ .byte 0x1
+ .byte 0x65
+ .uleb128 0x5
+ .string "f"
+ .byte 0x1
+ .byte 0x21
+ .long 0x50
+ .byte 0x1
+ .byte 0x55
+ .uleb128 0x5
+ .string "g"
+ .byte 0x1
+ .byte 0x21
+ .long 0x49
+ .byte 0x1
+ .byte 0x54
+ .uleb128 0x5
+ .string "h"
+ .byte 0x1
+ .byte 0x21
+ .long 0x22b
+ .byte 0x1
+ .byte 0x51
+ .uleb128 0x5
+ .string "i"
+ .byte 0x1
+ .byte 0x21
+ .long 0x232
+ .byte 0x1
+ .byte 0x52
+ .uleb128 0x6
+ .string "j"
+ .byte 0x1
+ .byte 0x23
+ .long 0x2d
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "l"
+ .byte 0x1
+ .byte 0x24
+ .long 0x22b
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0xf9
+ .uleb128 0x3b
+ .byte 0x9f
+ .uleb128 0x6
+ .string "m"
+ .byte 0x1
+ .byte 0x26
+ .long 0x22b
+ .byte 0x1
+ .byte 0x63
+ .uleb128 0x6
+ .string "n"
+ .byte 0x1
+ .byte 0x28
+ .long 0x34
+ .byte 0x7
+ .byte 0x72
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x3b
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "o"
+ .byte 0x1
+ .byte 0x29
+ .long 0x2d
+ .byte 0x7
+ .byte 0x71
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x42
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "p"
+ .byte 0x1
+ .byte 0x2a
+ .long 0x34
+ .byte 0x7
+ .byte 0x74
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x49
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "q"
+ .byte 0x1
+ .byte 0x2b
+ .long 0x2d
+ .byte 0x7
+ .byte 0x75
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x50
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "r"
+ .byte 0x1
+ .byte 0x2c
+ .long 0x232
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x3b
+ .byte 0x9f
+ .uleb128 0x6
+ .string "s"
+ .byte 0x1
+ .byte 0x2d
+ .long 0x22b
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x13
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x42
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "t"
+ .byte 0x1
+ .byte 0x2e
+ .long 0x49
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x49
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "u"
+ .byte 0x1
+ .byte 0x2f
+ .long 0x50
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x50
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "v"
+ .byte 0x1
+ .byte 0x30
+ .long 0x34
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "w"
+ .byte 0x1
+ .byte 0x31
+ .long 0x2d
+ .byte 0x12
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x3fd00000
+ .byte 0x1e
+ .byte 0x9f
+ .uleb128 0x6
+ .string "x"
+ .byte 0x1
+ .byte 0x32
+ .long 0x2d
+ .byte 0x20
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0x22
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40080000
+ .byte 0x1c
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0x78b58c40
+ .long 0x4415af1d
+ .byte 0x22
+ .byte 0x9f
+ .uleb128 0x6
+ .string "y"
+ .byte 0x1
+ .byte 0x33
+ .long 0x2d
+ .byte 0x14
+ .byte 0xf5
+ .uleb128 0x13
+ .uleb128 0x2d
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x401c0000
+ .byte 0x1e
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0x22
+ .byte 0x9f
+ .uleb128 0x6
+ .string "z"
+ .byte 0x1
+ .byte 0x34
+ .long 0x34
+ .byte 0x10
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf5
+ .uleb128 0x15
+ .uleb128 0x34
+ .byte 0x22
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40400000
+ .byte 0x22
+ .byte 0x9f
+ .byte 0
+ .uleb128 0x4
+ .byte 0x1
+ .string "f3"
+ .byte 0x1
+ .byte 0x43
+ .byte 0x1
+ .quad .LFB2
+ .quad .LFE2
+ .byte 0x2
+ .byte 0x77
+ .sleb128 8
+ .byte 0x1
+ .long 0x4cd
+ .uleb128 0x5
+ .string "a"
+ .byte 0x1
+ .byte 0x43
+ .long 0x22b
+ .byte 0x1
+ .byte 0x55
+ .uleb128 0x5
+ .string "b"
+ .byte 0x1
+ .byte 0x43
+ .long 0x50
+ .byte 0x1
+ .byte 0x54
+ .uleb128 0x5
+ .string "c"
+ .byte 0x1
+ .byte 0x43
+ .long 0x22b
+ .byte 0x1
+ .byte 0x51
+ .uleb128 0x5
+ .string "d"
+ .byte 0x1
+ .byte 0x43
+ .long 0x49
+ .byte 0x1
+ .byte 0x52
+ .uleb128 0x6
+ .string "w"
+ .byte 0x1
+ .byte 0x45
+ .long 0x22b
+ .byte 0x14
+ .byte 0x72
+ .sleb128 0
+ .byte 0xc
+ .long 0xffffffff
+ .byte 0x1a
+ .byte 0x12
+ .byte 0x75
+ .sleb128 0
+ .byte 0x16
+ .byte 0x14
+ .byte 0x2b
+ .byte 0x28
+ .value 0x1
+ .byte 0x16
+ .byte 0x13
+ .byte 0x9f
+ .uleb128 0x6
+ .string "x"
+ .byte 0x1
+ .byte 0x46
+ .long 0x22b
+ .byte 0xe
+ .byte 0x74
+ .sleb128 0
+ .byte 0x8
+ .byte 0x20
+ .byte 0x24
+ .byte 0x8
+ .byte 0x20
+ .byte 0x26
+ .byte 0x75
+ .sleb128 0
+ .byte 0x22
+ .byte 0x23
+ .uleb128 0x7
+ .byte 0x9f
+ .uleb128 0x6
+ .string "y"
+ .byte 0x1
+ .byte 0x47
+ .long 0x22b
+ .byte 0x13
+ .byte 0x72
+ .sleb128 0
+ .byte 0xc
+ .long 0xffffffff
+ .byte 0x1a
+ .byte 0x71
+ .sleb128 0
+ .byte 0x22
+ .byte 0x23
+ .uleb128 0x912345678
+ .byte 0x9f
+ .uleb128 0x6
+ .string "z"
+ .byte 0x1
+ .byte 0x48
+ .long 0x50
+ .byte 0x21
+ .byte 0x74
+ .sleb128 0
+ .byte 0x8
+ .byte 0x20
+ .byte 0x24
+ .byte 0x8
+ .byte 0x20
+ .byte 0x26
+ .byte 0x75
+ .sleb128 0
+ .byte 0x22
+ .byte 0x23
+ .uleb128 0x7
+ .byte 0x72
+ .sleb128 0
+ .byte 0xc
+ .long 0xffffffff
+ .byte 0x1a
+ .byte 0x71
+ .sleb128 0
+ .byte 0x22
+ .byte 0x23
+ .uleb128 0x912345678
+ .byte 0x22
+ .byte 0x9f
+ .byte 0
+ .uleb128 0x4
+ .byte 0x1
+ .string "f4"
+ .byte 0x1
+ .byte 0x4d
+ .byte 0x1
+ .quad .LFB3
+ .quad .LFE3
+ .byte 0x2
+ .byte 0x77
+ .sleb128 8
+ .byte 0x1
+ .long 0x576
+ .uleb128 0x5
+ .string "a"
+ .byte 0x1
+ .byte 0x4d
+ .long 0x5e
+ .byte 0x1
+ .byte 0x61
+ .uleb128 0x5
+ .string "b"
+ .byte 0x1
+ .byte 0x4d
+ .long 0x57
+ .byte 0x1
+ .byte 0x62
+ .uleb128 0x5
+ .string "c"
+ .byte 0x1
+ .byte 0x4d
+ .long 0x65
+ .byte 0x1
+ .byte 0x63
+ .uleb128 0x6
+ .string "w"
+ .byte 0x1
+ .byte 0x4f
+ .long 0x5e
+ .byte 0x14
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x5e
+ .byte 0xf4
+ .uleb128 0x5e
+ .byte 0x4
+ .long 0x32000050
+ .byte 0x1e
+ .byte 0xf4
+ .uleb128 0x5e
+ .byte 0x4
+ .long 0x3200003c
+ .byte 0x22
+ .byte 0x9f
+ .uleb128 0x6
+ .string "x"
+ .byte 0x1
+ .byte 0x50
+ .long 0x57
+ .byte 0x1c
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x57
+ .byte 0xf4
+ .uleb128 0x57
+ .byte 0x8
+ .long 0x50
+ .long 0x31a00000
+ .byte 0x1b
+ .byte 0xf4
+ .uleb128 0x57
+ .byte 0x8
+ .long 0x3c
+ .long 0x31a00000
+ .byte 0x1c
+ .byte 0x9f
+ .uleb128 0x6
+ .string "y"
+ .byte 0x1
+ .byte 0x51
+ .long 0x65
+ .byte 0x19
+ .byte 0xf5
+ .uleb128 0x13
+ .uleb128 0x65
+ .byte 0x1f
+ .byte 0xf4
+ .uleb128 0x65
+ .byte 0x10
+ .long 0x50
+ .long 0
+ .long 0
+ .long 0x303e0000
+ .byte 0x1b
+ .byte 0x9f
+ .byte 0
+ .uleb128 0x7
+ .byte 0x1
+ .long .LASF13
+ .byte 0x1
+ .byte 0x56
+ .long 0x50
+ .quad .LFB4
+ .quad .LFE4
+ .long .LLST0
+ .byte 0x1
+ .long 0x6a1
+ .uleb128 0x8
+ .quad .LVL4
+ .long 0x6c
+ .long 0x604
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x61
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x3ff00000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x62
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40000000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x63
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40080000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x64
+ .byte 0x7
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40800000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x65
+ .byte 0x7
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40a00000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x55
+ .byte 0x1
+ .byte 0x36
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x54
+ .byte 0x1
+ .byte 0x37
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x51
+ .byte 0x1
+ .byte 0x38
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x52
+ .byte 0x1
+ .byte 0x39
+ .byte 0
+ .uleb128 0x8
+ .quad .LVL5
+ .long 0x239
+ .long 0x66d
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x61
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x3ff00000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x62
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40000000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x63
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40080000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x64
+ .byte 0x7
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40800000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x65
+ .byte 0x7
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40a00000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x55
+ .byte 0x1
+ .byte 0x36
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x54
+ .byte 0x1
+ .byte 0x37
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x51
+ .byte 0x1
+ .byte 0x38
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x52
+ .byte 0x1
+ .byte 0x39
+ .byte 0
+ .uleb128 0x8
+ .quad .LVL6
+ .long 0x402
+ .long 0x693
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x55
+ .byte 0x1
+ .byte 0x31
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x54
+ .byte 0x1
+ .byte 0x32
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x51
+ .byte 0x1
+ .byte 0x33
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x52
+ .byte 0x1
+ .byte 0x34
+ .byte 0
+ .uleb128 0xa
+ .quad .LVL7
+ .long 0x4cd
+ .byte 0
+ .uleb128 0xb
+ .string "vv"
+ .byte 0x1
+ .byte 0x5
+ .long 0x6ad
+ .byte 0x1
+ .byte 0x1
+ .uleb128 0xc
+ .long 0x50
+ .uleb128 0xd
+ .string "vv"
+ .byte 0x1
+ .byte 0x5
+ .long 0x6ad
+ .byte 0x1
+ .byte 0x9
+ .byte 0x3
+ .quad vv
+ .byte 0
+ .section .debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+ .uleb128 0x1
+ .uleb128 0x11
+ .byte 0x1
+ .uleb128 0x25
+ .uleb128 0xe
+ .uleb128 0x13
+ .uleb128 0xb
+ .uleb128 0x3
+ .uleb128 0xe
+ .uleb128 0x1b
+ .uleb128 0xe
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x12
+ .uleb128 0x1
+ .uleb128 0x10
+ .uleb128 0x6
+ .byte 0
+ .byte 0
+ .uleb128 0x2
+ .uleb128 0x24
+ .byte 0
+ .uleb128 0xb
+ .uleb128 0xb
+ .uleb128 0x3e
+ .uleb128 0xb
+ .uleb128 0x3
+ .uleb128 0xe
+ .byte 0
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x24
+ .byte 0
+ .uleb128 0xb
+ .uleb128 0xb
+ .uleb128 0x3e
+ .uleb128 0xb
+ .uleb128 0x3
+ .uleb128 0x8
+ .byte 0
+ .byte 0
+ .uleb128 0x4
+ .uleb128 0x2e
+ .byte 0x1
+ .uleb128 0x3f
+ .uleb128 0xc
+ .uleb128 0x3
+ .uleb128 0x8
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x27
+ .uleb128 0xc
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x12
+ .uleb128 0x1
+ .uleb128 0x40
+ .uleb128 0xa
+ .uleb128 0x2117
+ .uleb128 0xc
+ .uleb128 0x1
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0x5
+ .uleb128 0x5
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x8
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x2
+ .uleb128 0xa
+ .byte 0
+ .byte 0
+ .uleb128 0x6
+ .uleb128 0x34
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x8
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x2
+ .uleb128 0xa
+ .byte 0
+ .byte 0
+ .uleb128 0x7
+ .uleb128 0x2e
+ .byte 0x1
+ .uleb128 0x3f
+ .uleb128 0xc
+ .uleb128 0x3
+ .uleb128 0xe
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x12
+ .uleb128 0x1
+ .uleb128 0x40
+ .uleb128 0x6
+ .uleb128 0x2117
+ .uleb128 0xc
+ .uleb128 0x1
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0x8
+ .uleb128 0x4109
+ .byte 0x1
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x31
+ .uleb128 0x13
+ .uleb128 0x1
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0x9
+ .uleb128 0x410a
+ .byte 0
+ .uleb128 0x2
+ .uleb128 0xa
+ .uleb128 0x2111
+ .uleb128 0xa
+ .byte 0
+ .byte 0
+ .uleb128 0xa
+ .uleb128 0x4109
+ .byte 0
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x31
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0xb
+ .uleb128 0x34
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x8
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x3f
+ .uleb128 0xc
+ .uleb128 0x3c
+ .uleb128 0xc
+ .byte 0
+ .byte 0
+ .uleb128 0xc
+ .uleb128 0x35
+ .byte 0
+ .uleb128 0x49
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0xd
+ .uleb128 0x34
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x8
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x3f
+ .uleb128 0xc
+ .uleb128 0x2
+ .uleb128 0xa
+ .byte 0
+ .byte 0
+ .byte 0
+ .section .debug_loc,"",@progbits
+.Ldebug_loc0:
+.LLST0:
+ .quad .LFB4-.Ltext0
+ .quad .LCFI0-.Ltext0
+ .value 0x2
+ .byte 0x77
+ .sleb128 8
+ .quad .LCFI0-.Ltext0
+ .quad .LCFI1-.Ltext0
+ .value 0x2
+ .byte 0x77
+ .sleb128 16
+ .quad .LCFI1-.Ltext0
+ .quad .LFE4-.Ltext0
+ .value 0x2
+ .byte 0x77
+ .sleb128 8
+ .quad 0
+ .quad 0
+ .section .debug_aranges,"",@progbits
+ .long 0x2c
+ .value 0x2
+ .long .Ldebug_info0
+ .byte 0x8
+ .byte 0
+ .value 0
+ .value 0
+ .quad .Ltext0
+ .quad .Letext0-.Ltext0
+ .quad 0
+ .quad 0
+ .section .debug_line,"",@progbits
+.Ldebug_line0:
+ .section .debug_str,"MS",@progbits,1
+.LASF4:
+ .string "unsigned int"
+.LASF6:
+ .string "_Decimal32"
+.LASF7:
+ .string "_Decimal128"
+.LASF2:
+ .string "long unsigned int"
+.LASF12:
+ .string "long long unsigned int"
+.LASF5:
+ .string "_Decimal64"
+.LASF13:
+ .string "main"
+.LASF3:
+ .string "long int"
+.LASF10:
+ .string "/tmp"
+.LASF0:
+ .string "double"
+.LASF11:
+ .string "long long int"
+.LASF1:
+ .string "float"
+.LASF8:
+ .string "GNU C 4.7.0 20110708 (experimental) [trunk revision 176048]"
+.LASF9:
+ .string "typeddwarf.c"
+ .ident "GCC: (GNU) 4.7.0 20110708 (experimental) [trunk revision 176048]"
+ .section .note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.c b/gdb/testsuite/gdb.dwarf2/typeddwarf.c
index e5f7d67..40497da 100644
--- a/gdb/testsuite/gdb.dwarf2/typeddwarf.c
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.c
@@ -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++;
}
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.exp b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
index e6a420a..36a17e5 100644
--- a/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
@@ -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 {} {
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-20 20:46 ` Tom Tromey
@ 2011-07-20 20:53 ` Tom Tromey
2011-07-24 13:48 ` Mark Kettenis
2011-07-21 5:23 ` Ulrich Weigand
2011-07-22 14:30 ` Pedro Alves
2 siblings, 1 reply; 28+ messages in thread
From: Tom Tromey @ 2011-07-20 20:53 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Tom> I looked into this, and I changed some things, but I did not change it
Tom> completely.
I forgot to mention -- please comment. In the absence of comments I
will commit this version.
Tom
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-20 20:46 ` Tom Tromey
2011-07-20 20:53 ` Tom Tromey
@ 2011-07-21 5:23 ` Ulrich Weigand
2011-07-21 20:27 ` Tom Tromey
2011-07-22 14:30 ` Pedro Alves
2 siblings, 1 reply; 28+ messages in thread
From: Ulrich Weigand @ 2011-07-21 5:23 UTC (permalink / raw)
To: Tom Tromey; +Cc: Daniel Jacobowitz, gdb-patches
Tom Tromey wrote:
> 2011-07-20 Tom Tromey <tromey@redhat.com>
>
> * amd64-tdep.c (amd64_pseudo_register_read_into_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_into_value.
> * regcache.h (regcache_cooked_read_into_value): Declare.
> * regcache.c (regcache_cooked_read_into_value): New function.
> (regcache_cooked_read): Call
> gdbarch_pseudo_register_read_into_value if available.
> * i386-tdep.h (i386_pseudo_register_read_into_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_gdbarch_init): Call
> set_gdbarch_pseudo_register_read_into_value, not
> set_gdbarch_pseudo_register_read.
> * gdbarch.sh (pseudo_register_read_into_value): New method.
> * gdbarch.c, gdbarch.h: Rebuild.
> * findvar.c (value_from_register): Call get_frame_register_value.
I'm not completely happy about the "read into value" style interface;
this leaves unclear just how the value passed into that interface is
supposed to have been set up. Should the callback have to cope with
different types (or even lengths), value offset, or more complex
value properties like enclosing type? Apparently not -- the actual
callback implementations of your don't attempt to with (or even
check for!) any of that, they just blindly assume the value has been
set up as they expect.
I'd prefer an interface that simply *returns* a value, which then the
callback would be free to set up as desired. This would also be much
more in line with all the other interfaces that produce values ...
> @@ -647,14 +647,16 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame)
> 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);
> +
> + value_contents_copy (v, 0, v2, 0, len);
> + ok = 1;
> }
This seems to introduce a bug by ignoring value_offset (v).
If v is of a smaller type than the full register width, only
the appropriate bytes of v2 (which do not always start at the
beginning, in particular on big-endian machines) ought to be
copied over to v.
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-21 5:23 ` Ulrich Weigand
@ 2011-07-21 20:27 ` Tom Tromey
2011-07-22 13:48 ` Ulrich Weigand
0 siblings, 1 reply; 28+ messages in thread
From: Tom Tromey @ 2011-07-21 20:27 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: Daniel Jacobowitz, gdb-patches
>>>>> "Ulrich" == Ulrich Weigand <uweigand@de.ibm.com> writes:
Ulrich> I'd prefer an interface that simply *returns* a value, which then the
Ulrich> callback would be free to set up as desired. This would also be much
Ulrich> more in line with all the other interfaces that produce values ...
No problem.
FWIW, I was mostly following the existing code and existing gdbarch
methods, like gdbarch_value_from_register.
I think a decent project would be to consolidate this new method,
gdbarch_convert_register, and gdbarch_value_from_register into a single
approach.
Ulrich> This seems to introduce a bug by ignoring value_offset (v).
Ulrich> If v is of a smaller type than the full register width, only
Ulrich> the appropriate bytes of v2 (which do not always start at the
Ulrich> beginning, in particular on big-endian machines) ought to be
Ulrich> copied over to v.
Thanks.
What do you think of the appended?
Tom
2011-07-21 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-21 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.
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index de62ac7..051fb13 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -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);
diff --git a/gdb/findvar.c b/gdb/findvar.c
index a700c02..af22a01 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -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, value_offset (v), v2, 0, len);
}
return v;
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 1e65c17..600cce6 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -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");
@@ -1085,6 +1088,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *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));
fprintf_unfiltered (file,
@@ -1700,6 +1709,30 @@ set_gdbarch_pseudo_register_read (struct gdbarch *gdbarch,
}
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)
{
gdb_assert (gdbarch != NULL);
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 50221d7..7619581 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -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);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index a628f8c..61094fb 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -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
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 366d0fa..5fb2efb 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -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"));
}
+}
+
+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 REG_VALID;
+ 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);
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index 7fc719c..de11f68 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -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);
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 41f218d..0af93e8 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -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)
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 3708c86..7f7dc10 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -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,
diff --git a/gdb/sentinel-frame.c b/gdb/sentinel-frame.c
index 6c2f3e0..5d018bd 100644
--- a/gdb/sentinel-frame.c
+++ b/gdb/sentinel-frame.c
@@ -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;
}
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf-amd64.S b/gdb/testsuite/gdb.dwarf2/typeddwarf-amd64.S
new file mode 100644
index 0000000..f97357a
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf-amd64.S
@@ -0,0 +1,1568 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* This source file was generated from typeddwarf.c using the following
+ command line:
+
+ gcc -S -g -O2 typeddwarf.c -o typeddwarf-amd64.S
+
+*/
+
+
+ .file "typeddwarf.c"
+ .text
+.Ltext0:
+ .globl f1
+ .type f1, @function
+f1:
+.LFB0:
+ .file 1 "typeddwarf.c"
+ .loc 1 10 0
+ .cfi_startproc
+.LVL0:
+ .loc 1 29 0
+ movl vv(%rip), %eax
+ addl $1, %eax
+ movl %eax, vv(%rip)
+ .loc 1 30 0
+ ret
+ .cfi_endproc
+.LFE0:
+ .size f1, .-f1
+ .globl f2
+ .type f2, @function
+f2:
+.LFB1:
+ .loc 1 34 0
+ .cfi_startproc
+.LVL1:
+ .loc 1 53 0
+ movl vv(%rip), %eax
+ addl $1, %eax
+ movl %eax, vv(%rip)
+ .loc 1 54 0
+ cvttsd2si %xmm0, %eax
+ movl %eax, vv(%rip)
+ .loc 1 55 0
+ cvttsd2si %xmm1, %eax
+ movl %eax, vv(%rip)
+ .loc 1 56 0
+ cvttsd2si %xmm2, %eax
+ movl %eax, vv(%rip)
+ .loc 1 57 0
+ cvttss2si %xmm3, %eax
+ movl %eax, vv(%rip)
+ .loc 1 58 0
+ cvttss2si %xmm4, %r8d
+ movl %r8d, vv(%rip)
+ .loc 1 59 0
+ movl %edi, vv(%rip)
+ .loc 1 60 0
+ movl %esi, vv(%rip)
+ .loc 1 61 0
+ movl %edx, vv(%rip)
+ .loc 1 62 0
+ movl %ecx, vv(%rip)
+ .loc 1 63 0
+ movl %eax, vv(%rip)
+ .loc 1 64 0
+ ret
+ .cfi_endproc
+.LFE1:
+ .size f2, .-f2
+ .globl f3
+ .type f3, @function
+f3:
+.LFB2:
+ .loc 1 68 0
+ .cfi_startproc
+.LVL2:
+ .loc 1 73 0
+ movl vv(%rip), %eax
+ addl $1, %eax
+ movl %eax, vv(%rip)
+ .loc 1 74 0
+ ret
+ .cfi_endproc
+.LFE2:
+ .size f3, .-f3
+ .globl f4
+ .type f4, @function
+f4:
+.LFB3:
+ .loc 1 78 0
+ .cfi_startproc
+.LVL3:
+ .loc 1 82 0
+ movl vv(%rip), %eax
+ addl $1, %eax
+ movl %eax, vv(%rip)
+ .loc 1 83 0
+ ret
+ .cfi_endproc
+.LFE3:
+ .size f4, .-f4
+ .globl _start
+ .type _start, @function
+_start:
+.LFB4:
+ .loc 1 87 0
+ .cfi_startproc
+ subq $8, %rsp
+.LCFI0:
+ .cfi_def_cfa_offset 16
+ .loc 1 88 0
+ movl $9, %ecx
+ movl $8, %edx
+ movl $7, %esi
+ movl $6, %edi
+ movss .LC2(%rip), %xmm4
+ movss .LC3(%rip), %xmm3
+ movsd .LC0(%rip), %xmm2
+ movsd .LC1(%rip), %xmm1
+ movsd .LC4(%rip), %xmm0
+ call f1
+.LVL4:
+ .loc 1 89 0
+ movl $9, %ecx
+ movl $8, %edx
+ movl $7, %esi
+ movl $6, %edi
+ movss .LC2(%rip), %xmm4
+ movss .LC3(%rip), %xmm3
+ movsd .LC0(%rip), %xmm2
+ movsd .LC1(%rip), %xmm1
+ movsd .LC4(%rip), %xmm0
+ call f2
+.LVL5:
+ .loc 1 90 0
+ movl $4, %ecx
+ movl $3, %edx
+ movl $2, %esi
+ movl $1, %edi
+ call f3
+.LVL6:
+ .loc 1 91 0
+ movdqa .LC5(%rip), %xmm2
+ movq .LC6(%rip), %xmm1
+ movd .LC7(%rip), %xmm0
+ call f4
+.LVL7:
+ .loc 1 93 0
+ movl $0, %eax
+ addq $8, %rsp
+.LCFI1:
+ .cfi_def_cfa_offset 8
+ ret
+ .cfi_endproc
+.LFE4:
+ .size _start, .-_start
+ .comm vv,4,4
+ .section .rodata.cst8,"aM",@progbits,8
+ .align 8
+.LC0:
+ .long 0
+ .long 1074266112
+ .align 8
+.LC1:
+ .long 0
+ .long 1073741824
+ .section .rodata.cst4,"aM",@progbits,4
+ .align 4
+.LC2:
+ .long 1084227584
+ .align 4
+.LC3:
+ .long 1082130432
+ .section .rodata.cst8
+ .align 8
+.LC4:
+ .long 0
+ .long 1072693248
+ .section .rodata.cst16,"aM",@progbits,16
+ .align 16
+.LC5:
+ .quad 640
+ .quad 3476215962376601600
+ .section .rodata.cst8
+ .align 8
+.LC6:
+ .quad 3575858104132173984
+ .section .rodata.cst4
+ .align 4
+.LC7:
+ .long 838860880
+ .text
+.Letext0:
+ .section .debug_info,"",@progbits
+.Ldebug_info0:
+ .long 0x6c4
+ .value 0x2
+ .long .Ldebug_abbrev0
+ .byte 0x8
+ .uleb128 0x1
+ .long .LASF8
+ .byte 0x1
+ .long .LASF9
+ .long .LASF10
+ .quad .Ltext0
+ .quad .Letext0
+ .long .Ldebug_line0
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0x4
+ .long .LASF0
+ .uleb128 0x2
+ .byte 0x4
+ .byte 0x4
+ .long .LASF1
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0x7
+ .long .LASF2
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0x5
+ .long .LASF3
+ .uleb128 0x2
+ .byte 0x4
+ .byte 0x7
+ .long .LASF4
+ .uleb128 0x3
+ .byte 0x4
+ .byte 0x5
+ .string "int"
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0xf
+ .long .LASF5
+ .uleb128 0x2
+ .byte 0x4
+ .byte 0xf
+ .long .LASF6
+ .uleb128 0x2
+ .byte 0x10
+ .byte 0xf
+ .long .LASF7
+ .uleb128 0x4
+ .byte 0x1
+ .string "f1"
+ .byte 0x1
+ .byte 0x9
+ .byte 0x1
+ .quad .LFB0
+ .quad .LFE0
+ .byte 0x2
+ .byte 0x77
+ .sleb128 8
+ .byte 0x1
+ .long 0x22b
+ .uleb128 0x5
+ .string "a"
+ .byte 0x1
+ .byte 0x9
+ .long 0x2d
+ .byte 0x1
+ .byte 0x61
+ .uleb128 0x5
+ .string "b"
+ .byte 0x1
+ .byte 0x9
+ .long 0x2d
+ .byte 0x1
+ .byte 0x62
+ .uleb128 0x5
+ .string "c"
+ .byte 0x1
+ .byte 0x9
+ .long 0x2d
+ .byte 0x1
+ .byte 0x63
+ .uleb128 0x5
+ .string "d"
+ .byte 0x1
+ .byte 0x9
+ .long 0x34
+ .byte 0x1
+ .byte 0x64
+ .uleb128 0x5
+ .string "e"
+ .byte 0x1
+ .byte 0x9
+ .long 0x34
+ .byte 0x1
+ .byte 0x65
+ .uleb128 0x5
+ .string "f"
+ .byte 0x1
+ .byte 0x9
+ .long 0x50
+ .byte 0x1
+ .byte 0x55
+ .uleb128 0x5
+ .string "g"
+ .byte 0x1
+ .byte 0x9
+ .long 0x49
+ .byte 0x1
+ .byte 0x54
+ .uleb128 0x5
+ .string "h"
+ .byte 0x1
+ .byte 0x9
+ .long 0x22b
+ .byte 0x1
+ .byte 0x51
+ .uleb128 0x5
+ .string "i"
+ .byte 0x1
+ .byte 0x9
+ .long 0x232
+ .byte 0x1
+ .byte 0x52
+ .uleb128 0x6
+ .string "j"
+ .byte 0x1
+ .byte 0xb
+ .long 0x2d
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "l"
+ .byte 0x1
+ .byte 0xc
+ .long 0x22b
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0xf9
+ .uleb128 0x3b
+ .byte 0x9f
+ .uleb128 0x6
+ .string "m"
+ .byte 0x1
+ .byte 0xe
+ .long 0x22b
+ .byte 0x1
+ .byte 0x63
+ .uleb128 0x6
+ .string "n"
+ .byte 0x1
+ .byte 0x10
+ .long 0x34
+ .byte 0x7
+ .byte 0x72
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x3b
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "o"
+ .byte 0x1
+ .byte 0x11
+ .long 0x2d
+ .byte 0x7
+ .byte 0x71
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x42
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "p"
+ .byte 0x1
+ .byte 0x12
+ .long 0x34
+ .byte 0x7
+ .byte 0x74
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x49
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "q"
+ .byte 0x1
+ .byte 0x13
+ .long 0x2d
+ .byte 0x7
+ .byte 0x75
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x50
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "r"
+ .byte 0x1
+ .byte 0x14
+ .long 0x232
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x3b
+ .byte 0x9f
+ .uleb128 0x6
+ .string "s"
+ .byte 0x1
+ .byte 0x15
+ .long 0x22b
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x13
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x42
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "t"
+ .byte 0x1
+ .byte 0x16
+ .long 0x49
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x49
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "u"
+ .byte 0x1
+ .byte 0x17
+ .long 0x50
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x50
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "v"
+ .byte 0x1
+ .byte 0x18
+ .long 0x34
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "w"
+ .byte 0x1
+ .byte 0x19
+ .long 0x2d
+ .byte 0x12
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x3fd00000
+ .byte 0x1e
+ .byte 0x9f
+ .uleb128 0x6
+ .string "x"
+ .byte 0x1
+ .byte 0x1a
+ .long 0x2d
+ .byte 0x14
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0x22
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x3ff00000
+ .byte 0x22
+ .byte 0x9f
+ .uleb128 0x6
+ .string "y"
+ .byte 0x1
+ .byte 0x1b
+ .long 0x2d
+ .byte 0x14
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0xf5
+ .uleb128 0x13
+ .uleb128 0x2d
+ .byte 0x22
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40000000
+ .byte 0x22
+ .byte 0x9f
+ .uleb128 0x6
+ .string "z"
+ .byte 0x1
+ .byte 0x1c
+ .long 0x34
+ .byte 0x12
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf3
+ .uleb128 0x3
+ .byte 0xf5
+ .uleb128 0x15
+ .uleb128 0x34
+ .byte 0x22
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40400000
+ .byte 0x22
+ .byte 0x9f
+ .byte 0
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0x5
+ .long .LASF11
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0x7
+ .long .LASF12
+ .uleb128 0x4
+ .byte 0x1
+ .string "f2"
+ .byte 0x1
+ .byte 0x21
+ .byte 0x1
+ .quad .LFB1
+ .quad .LFE1
+ .byte 0x2
+ .byte 0x77
+ .sleb128 8
+ .byte 0x1
+ .long 0x402
+ .uleb128 0x5
+ .string "a"
+ .byte 0x1
+ .byte 0x21
+ .long 0x2d
+ .byte 0x1
+ .byte 0x61
+ .uleb128 0x5
+ .string "b"
+ .byte 0x1
+ .byte 0x21
+ .long 0x2d
+ .byte 0x1
+ .byte 0x62
+ .uleb128 0x5
+ .string "c"
+ .byte 0x1
+ .byte 0x21
+ .long 0x2d
+ .byte 0x1
+ .byte 0x63
+ .uleb128 0x5
+ .string "d"
+ .byte 0x1
+ .byte 0x21
+ .long 0x34
+ .byte 0x1
+ .byte 0x64
+ .uleb128 0x5
+ .string "e"
+ .byte 0x1
+ .byte 0x21
+ .long 0x34
+ .byte 0x1
+ .byte 0x65
+ .uleb128 0x5
+ .string "f"
+ .byte 0x1
+ .byte 0x21
+ .long 0x50
+ .byte 0x1
+ .byte 0x55
+ .uleb128 0x5
+ .string "g"
+ .byte 0x1
+ .byte 0x21
+ .long 0x49
+ .byte 0x1
+ .byte 0x54
+ .uleb128 0x5
+ .string "h"
+ .byte 0x1
+ .byte 0x21
+ .long 0x22b
+ .byte 0x1
+ .byte 0x51
+ .uleb128 0x5
+ .string "i"
+ .byte 0x1
+ .byte 0x21
+ .long 0x232
+ .byte 0x1
+ .byte 0x52
+ .uleb128 0x6
+ .string "j"
+ .byte 0x1
+ .byte 0x23
+ .long 0x2d
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "l"
+ .byte 0x1
+ .byte 0x24
+ .long 0x22b
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0xf9
+ .uleb128 0x3b
+ .byte 0x9f
+ .uleb128 0x6
+ .string "m"
+ .byte 0x1
+ .byte 0x26
+ .long 0x22b
+ .byte 0x1
+ .byte 0x63
+ .uleb128 0x6
+ .string "n"
+ .byte 0x1
+ .byte 0x28
+ .long 0x34
+ .byte 0x7
+ .byte 0x72
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x3b
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "o"
+ .byte 0x1
+ .byte 0x29
+ .long 0x2d
+ .byte 0x7
+ .byte 0x71
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x42
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "p"
+ .byte 0x1
+ .byte 0x2a
+ .long 0x34
+ .byte 0x7
+ .byte 0x74
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x49
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "q"
+ .byte 0x1
+ .byte 0x2b
+ .long 0x2d
+ .byte 0x7
+ .byte 0x75
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x50
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "r"
+ .byte 0x1
+ .byte 0x2c
+ .long 0x232
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x3b
+ .byte 0x9f
+ .uleb128 0x6
+ .string "s"
+ .byte 0x1
+ .byte 0x2d
+ .long 0x22b
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x13
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x42
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "t"
+ .byte 0x1
+ .byte 0x2e
+ .long 0x49
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x49
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "u"
+ .byte 0x1
+ .byte 0x2f
+ .long 0x50
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x50
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "v"
+ .byte 0x1
+ .byte 0x30
+ .long 0x34
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "w"
+ .byte 0x1
+ .byte 0x31
+ .long 0x2d
+ .byte 0x12
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x3fd00000
+ .byte 0x1e
+ .byte 0x9f
+ .uleb128 0x6
+ .string "x"
+ .byte 0x1
+ .byte 0x32
+ .long 0x2d
+ .byte 0x20
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0x22
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40080000
+ .byte 0x1c
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0x78b58c40
+ .long 0x4415af1d
+ .byte 0x22
+ .byte 0x9f
+ .uleb128 0x6
+ .string "y"
+ .byte 0x1
+ .byte 0x33
+ .long 0x2d
+ .byte 0x14
+ .byte 0xf5
+ .uleb128 0x13
+ .uleb128 0x2d
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x401c0000
+ .byte 0x1e
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0x22
+ .byte 0x9f
+ .uleb128 0x6
+ .string "z"
+ .byte 0x1
+ .byte 0x34
+ .long 0x34
+ .byte 0x10
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf5
+ .uleb128 0x15
+ .uleb128 0x34
+ .byte 0x22
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40400000
+ .byte 0x22
+ .byte 0x9f
+ .byte 0
+ .uleb128 0x4
+ .byte 0x1
+ .string "f3"
+ .byte 0x1
+ .byte 0x43
+ .byte 0x1
+ .quad .LFB2
+ .quad .LFE2
+ .byte 0x2
+ .byte 0x77
+ .sleb128 8
+ .byte 0x1
+ .long 0x4cd
+ .uleb128 0x5
+ .string "a"
+ .byte 0x1
+ .byte 0x43
+ .long 0x22b
+ .byte 0x1
+ .byte 0x55
+ .uleb128 0x5
+ .string "b"
+ .byte 0x1
+ .byte 0x43
+ .long 0x50
+ .byte 0x1
+ .byte 0x54
+ .uleb128 0x5
+ .string "c"
+ .byte 0x1
+ .byte 0x43
+ .long 0x22b
+ .byte 0x1
+ .byte 0x51
+ .uleb128 0x5
+ .string "d"
+ .byte 0x1
+ .byte 0x43
+ .long 0x49
+ .byte 0x1
+ .byte 0x52
+ .uleb128 0x6
+ .string "w"
+ .byte 0x1
+ .byte 0x45
+ .long 0x22b
+ .byte 0x14
+ .byte 0x72
+ .sleb128 0
+ .byte 0xc
+ .long 0xffffffff
+ .byte 0x1a
+ .byte 0x12
+ .byte 0x75
+ .sleb128 0
+ .byte 0x16
+ .byte 0x14
+ .byte 0x2b
+ .byte 0x28
+ .value 0x1
+ .byte 0x16
+ .byte 0x13
+ .byte 0x9f
+ .uleb128 0x6
+ .string "x"
+ .byte 0x1
+ .byte 0x46
+ .long 0x22b
+ .byte 0xe
+ .byte 0x74
+ .sleb128 0
+ .byte 0x8
+ .byte 0x20
+ .byte 0x24
+ .byte 0x8
+ .byte 0x20
+ .byte 0x26
+ .byte 0x75
+ .sleb128 0
+ .byte 0x22
+ .byte 0x23
+ .uleb128 0x7
+ .byte 0x9f
+ .uleb128 0x6
+ .string "y"
+ .byte 0x1
+ .byte 0x47
+ .long 0x22b
+ .byte 0x13
+ .byte 0x72
+ .sleb128 0
+ .byte 0xc
+ .long 0xffffffff
+ .byte 0x1a
+ .byte 0x71
+ .sleb128 0
+ .byte 0x22
+ .byte 0x23
+ .uleb128 0x912345678
+ .byte 0x9f
+ .uleb128 0x6
+ .string "z"
+ .byte 0x1
+ .byte 0x48
+ .long 0x50
+ .byte 0x21
+ .byte 0x74
+ .sleb128 0
+ .byte 0x8
+ .byte 0x20
+ .byte 0x24
+ .byte 0x8
+ .byte 0x20
+ .byte 0x26
+ .byte 0x75
+ .sleb128 0
+ .byte 0x22
+ .byte 0x23
+ .uleb128 0x7
+ .byte 0x72
+ .sleb128 0
+ .byte 0xc
+ .long 0xffffffff
+ .byte 0x1a
+ .byte 0x71
+ .sleb128 0
+ .byte 0x22
+ .byte 0x23
+ .uleb128 0x912345678
+ .byte 0x22
+ .byte 0x9f
+ .byte 0
+ .uleb128 0x4
+ .byte 0x1
+ .string "f4"
+ .byte 0x1
+ .byte 0x4d
+ .byte 0x1
+ .quad .LFB3
+ .quad .LFE3
+ .byte 0x2
+ .byte 0x77
+ .sleb128 8
+ .byte 0x1
+ .long 0x576
+ .uleb128 0x5
+ .string "a"
+ .byte 0x1
+ .byte 0x4d
+ .long 0x5e
+ .byte 0x1
+ .byte 0x61
+ .uleb128 0x5
+ .string "b"
+ .byte 0x1
+ .byte 0x4d
+ .long 0x57
+ .byte 0x1
+ .byte 0x62
+ .uleb128 0x5
+ .string "c"
+ .byte 0x1
+ .byte 0x4d
+ .long 0x65
+ .byte 0x1
+ .byte 0x63
+ .uleb128 0x6
+ .string "w"
+ .byte 0x1
+ .byte 0x4f
+ .long 0x5e
+ .byte 0x14
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x5e
+ .byte 0xf4
+ .uleb128 0x5e
+ .byte 0x4
+ .long 0x32000050
+ .byte 0x1e
+ .byte 0xf4
+ .uleb128 0x5e
+ .byte 0x4
+ .long 0x3200003c
+ .byte 0x22
+ .byte 0x9f
+ .uleb128 0x6
+ .string "x"
+ .byte 0x1
+ .byte 0x50
+ .long 0x57
+ .byte 0x1c
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x57
+ .byte 0xf4
+ .uleb128 0x57
+ .byte 0x8
+ .long 0x50
+ .long 0x31a00000
+ .byte 0x1b
+ .byte 0xf4
+ .uleb128 0x57
+ .byte 0x8
+ .long 0x3c
+ .long 0x31a00000
+ .byte 0x1c
+ .byte 0x9f
+ .uleb128 0x6
+ .string "y"
+ .byte 0x1
+ .byte 0x51
+ .long 0x65
+ .byte 0x19
+ .byte 0xf5
+ .uleb128 0x13
+ .uleb128 0x65
+ .byte 0x1f
+ .byte 0xf4
+ .uleb128 0x65
+ .byte 0x10
+ .long 0x50
+ .long 0
+ .long 0
+ .long 0x303e0000
+ .byte 0x1b
+ .byte 0x9f
+ .byte 0
+ .uleb128 0x7
+ .byte 0x1
+ .long .LASF13
+ .byte 0x1
+ .byte 0x56
+ .long 0x50
+ .quad .LFB4
+ .quad .LFE4
+ .long .LLST0
+ .byte 0x1
+ .long 0x6a1
+ .uleb128 0x8
+ .quad .LVL4
+ .long 0x6c
+ .long 0x604
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x61
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x3ff00000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x62
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40000000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x63
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40080000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x64
+ .byte 0x7
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40800000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x65
+ .byte 0x7
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40a00000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x55
+ .byte 0x1
+ .byte 0x36
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x54
+ .byte 0x1
+ .byte 0x37
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x51
+ .byte 0x1
+ .byte 0x38
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x52
+ .byte 0x1
+ .byte 0x39
+ .byte 0
+ .uleb128 0x8
+ .quad .LVL5
+ .long 0x239
+ .long 0x66d
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x61
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x3ff00000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x62
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40000000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x63
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40080000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x64
+ .byte 0x7
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40800000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x65
+ .byte 0x7
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40a00000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x55
+ .byte 0x1
+ .byte 0x36
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x54
+ .byte 0x1
+ .byte 0x37
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x51
+ .byte 0x1
+ .byte 0x38
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x52
+ .byte 0x1
+ .byte 0x39
+ .byte 0
+ .uleb128 0x8
+ .quad .LVL6
+ .long 0x402
+ .long 0x693
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x55
+ .byte 0x1
+ .byte 0x31
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x54
+ .byte 0x1
+ .byte 0x32
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x51
+ .byte 0x1
+ .byte 0x33
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x52
+ .byte 0x1
+ .byte 0x34
+ .byte 0
+ .uleb128 0xa
+ .quad .LVL7
+ .long 0x4cd
+ .byte 0
+ .uleb128 0xb
+ .string "vv"
+ .byte 0x1
+ .byte 0x5
+ .long 0x6ad
+ .byte 0x1
+ .byte 0x1
+ .uleb128 0xc
+ .long 0x50
+ .uleb128 0xd
+ .string "vv"
+ .byte 0x1
+ .byte 0x5
+ .long 0x6ad
+ .byte 0x1
+ .byte 0x9
+ .byte 0x3
+ .quad vv
+ .byte 0
+ .section .debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+ .uleb128 0x1
+ .uleb128 0x11
+ .byte 0x1
+ .uleb128 0x25
+ .uleb128 0xe
+ .uleb128 0x13
+ .uleb128 0xb
+ .uleb128 0x3
+ .uleb128 0xe
+ .uleb128 0x1b
+ .uleb128 0xe
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x12
+ .uleb128 0x1
+ .uleb128 0x10
+ .uleb128 0x6
+ .byte 0
+ .byte 0
+ .uleb128 0x2
+ .uleb128 0x24
+ .byte 0
+ .uleb128 0xb
+ .uleb128 0xb
+ .uleb128 0x3e
+ .uleb128 0xb
+ .uleb128 0x3
+ .uleb128 0xe
+ .byte 0
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x24
+ .byte 0
+ .uleb128 0xb
+ .uleb128 0xb
+ .uleb128 0x3e
+ .uleb128 0xb
+ .uleb128 0x3
+ .uleb128 0x8
+ .byte 0
+ .byte 0
+ .uleb128 0x4
+ .uleb128 0x2e
+ .byte 0x1
+ .uleb128 0x3f
+ .uleb128 0xc
+ .uleb128 0x3
+ .uleb128 0x8
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x27
+ .uleb128 0xc
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x12
+ .uleb128 0x1
+ .uleb128 0x40
+ .uleb128 0xa
+ .uleb128 0x2117
+ .uleb128 0xc
+ .uleb128 0x1
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0x5
+ .uleb128 0x5
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x8
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x2
+ .uleb128 0xa
+ .byte 0
+ .byte 0
+ .uleb128 0x6
+ .uleb128 0x34
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x8
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x2
+ .uleb128 0xa
+ .byte 0
+ .byte 0
+ .uleb128 0x7
+ .uleb128 0x2e
+ .byte 0x1
+ .uleb128 0x3f
+ .uleb128 0xc
+ .uleb128 0x3
+ .uleb128 0xe
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x12
+ .uleb128 0x1
+ .uleb128 0x40
+ .uleb128 0x6
+ .uleb128 0x2117
+ .uleb128 0xc
+ .uleb128 0x1
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0x8
+ .uleb128 0x4109
+ .byte 0x1
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x31
+ .uleb128 0x13
+ .uleb128 0x1
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0x9
+ .uleb128 0x410a
+ .byte 0
+ .uleb128 0x2
+ .uleb128 0xa
+ .uleb128 0x2111
+ .uleb128 0xa
+ .byte 0
+ .byte 0
+ .uleb128 0xa
+ .uleb128 0x4109
+ .byte 0
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x31
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0xb
+ .uleb128 0x34
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x8
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x3f
+ .uleb128 0xc
+ .uleb128 0x3c
+ .uleb128 0xc
+ .byte 0
+ .byte 0
+ .uleb128 0xc
+ .uleb128 0x35
+ .byte 0
+ .uleb128 0x49
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0xd
+ .uleb128 0x34
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x8
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x3f
+ .uleb128 0xc
+ .uleb128 0x2
+ .uleb128 0xa
+ .byte 0
+ .byte 0
+ .byte 0
+ .section .debug_loc,"",@progbits
+.Ldebug_loc0:
+.LLST0:
+ .quad .LFB4-.Ltext0
+ .quad .LCFI0-.Ltext0
+ .value 0x2
+ .byte 0x77
+ .sleb128 8
+ .quad .LCFI0-.Ltext0
+ .quad .LCFI1-.Ltext0
+ .value 0x2
+ .byte 0x77
+ .sleb128 16
+ .quad .LCFI1-.Ltext0
+ .quad .LFE4-.Ltext0
+ .value 0x2
+ .byte 0x77
+ .sleb128 8
+ .quad 0
+ .quad 0
+ .section .debug_aranges,"",@progbits
+ .long 0x2c
+ .value 0x2
+ .long .Ldebug_info0
+ .byte 0x8
+ .byte 0
+ .value 0
+ .value 0
+ .quad .Ltext0
+ .quad .Letext0-.Ltext0
+ .quad 0
+ .quad 0
+ .section .debug_line,"",@progbits
+.Ldebug_line0:
+ .section .debug_str,"MS",@progbits,1
+.LASF4:
+ .string "unsigned int"
+.LASF6:
+ .string "_Decimal32"
+.LASF7:
+ .string "_Decimal128"
+.LASF2:
+ .string "long unsigned int"
+.LASF12:
+ .string "long long unsigned int"
+.LASF5:
+ .string "_Decimal64"
+.LASF13:
+ .string "main"
+.LASF3:
+ .string "long int"
+.LASF10:
+ .string "/tmp"
+.LASF0:
+ .string "double"
+.LASF11:
+ .string "long long int"
+.LASF1:
+ .string "float"
+.LASF8:
+ .string "GNU C 4.7.0 20110708 (experimental) [trunk revision 176048]"
+.LASF9:
+ .string "typeddwarf.c"
+ .ident "GCC: (GNU) 4.7.0 20110708 (experimental) [trunk revision 176048]"
+ .section .note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.c b/gdb/testsuite/gdb.dwarf2/typeddwarf.c
index e5f7d67..40497da 100644
--- a/gdb/testsuite/gdb.dwarf2/typeddwarf.c
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.c
@@ -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++;
}
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.exp b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
index e6a420a..36a17e5 100644
--- a/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
@@ -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 {} {
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-21 20:27 ` Tom Tromey
@ 2011-07-22 13:48 ` Ulrich Weigand
2011-07-22 15:42 ` Tom Tromey
0 siblings, 1 reply; 28+ messages in thread
From: Ulrich Weigand @ 2011-07-22 13:48 UTC (permalink / raw)
To: Tom Tromey; +Cc: Daniel Jacobowitz, gdb-patches
Tom Tromey wrote:
> FWIW, I was mostly following the existing code and existing gdbarch
> methods, like gdbarch_value_from_register.
This looks good to me, thanks.
> I think a decent project would be to consolidate this new method,
> gdbarch_convert_register, and gdbarch_value_from_register into a single
> approach.
Agreed. I actually had a patchset a while ago that would get rid of
gdbarch_convert_register, but that was never quite completed ...
I'll have to see to get this done at some point.
> 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, value_offset (v), v2, 0, len);
This still looks wrong, I think. It should be:
value_contents_copy (v, 0, v2, value_offset (v), len);
(v2 is the full register. value_offset (v) specifies at which byte of
that full register contents the contents of v start ...)
The rest looks good to me.
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-20 20:46 ` Tom Tromey
2011-07-20 20:53 ` Tom Tromey
2011-07-21 5:23 ` Ulrich Weigand
@ 2011-07-22 14:30 ` Pedro Alves
2011-07-22 15:40 ` Tom Tromey
2 siblings, 1 reply; 28+ messages in thread
From: Pedro Alves @ 2011-07-22 14:30 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey, Daniel Jacobowitz
Hi Tom,
On Wednesday 20 July 2011 21:14:08, Tom Tromey wrote:
> 2011-07-20 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.
I get:
# of expected passes 39
with an unpatched gdb (x86-64-linux), same as with patched gdb.
Is that expected?
--
Pedro Alves
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-22 14:30 ` Pedro Alves
@ 2011-07-22 15:40 ` Tom Tromey
2011-07-22 19:10 ` Pedro Alves
0 siblings, 1 reply; 28+ messages in thread
From: Tom Tromey @ 2011-07-22 15:40 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches, Daniel Jacobowitz
>>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:
Pedro> # of expected passes 39
Pedro> with an unpatched gdb (x86-64-linux), same as with patched gdb.
Pedro> Is that expected?
It definitely fails for me with unpatched gdb.
Does your machine have AVX? I believe it will only fail on an
AVX-capable machine.
Tom
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-22 13:48 ` Ulrich Weigand
@ 2011-07-22 15:42 ` Tom Tromey
0 siblings, 0 replies; 28+ messages in thread
From: Tom Tromey @ 2011-07-22 15:42 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: Daniel Jacobowitz, gdb-patches
>>>>> "Ulrich" == Ulrich Weigand <uweigand@de.ibm.com> writes:
Ulrich> This still looks wrong, I think. It should be:
Ulrich> value_contents_copy (v, 0, v2, value_offset (v), len);
Ulrich> (v2 is the full register. value_offset (v) specifies at which byte of
Ulrich> that full register contents the contents of v start ...)
Thanks again.
I'm checking in the appended, which has this change.
Tom
2011-07-21 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-21 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.
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index de62ac7..051fb13 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -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);
diff --git a/gdb/findvar.c b/gdb/findvar.c
index a700c02..69dc5a0 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -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;
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 1e65c17..600cce6 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -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");
@@ -1085,6 +1088,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *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));
fprintf_unfiltered (file,
@@ -1700,6 +1709,30 @@ set_gdbarch_pseudo_register_read (struct gdbarch *gdbarch,
}
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)
{
gdb_assert (gdbarch != NULL);
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 50221d7..7619581 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -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);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index a628f8c..61094fb 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -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
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 366d0fa..5fb2efb 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -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"));
}
+}
+
+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 REG_VALID;
+ 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);
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index 7fc719c..de11f68 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -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);
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 41f218d..0af93e8 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -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)
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 3708c86..7f7dc10 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -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,
diff --git a/gdb/sentinel-frame.c b/gdb/sentinel-frame.c
index 6c2f3e0..5d018bd 100644
--- a/gdb/sentinel-frame.c
+++ b/gdb/sentinel-frame.c
@@ -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;
}
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf-amd64.S b/gdb/testsuite/gdb.dwarf2/typeddwarf-amd64.S
new file mode 100644
index 0000000..f97357a
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf-amd64.S
@@ -0,0 +1,1568 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* This source file was generated from typeddwarf.c using the following
+ command line:
+
+ gcc -S -g -O2 typeddwarf.c -o typeddwarf-amd64.S
+
+*/
+
+
+ .file "typeddwarf.c"
+ .text
+.Ltext0:
+ .globl f1
+ .type f1, @function
+f1:
+.LFB0:
+ .file 1 "typeddwarf.c"
+ .loc 1 10 0
+ .cfi_startproc
+.LVL0:
+ .loc 1 29 0
+ movl vv(%rip), %eax
+ addl $1, %eax
+ movl %eax, vv(%rip)
+ .loc 1 30 0
+ ret
+ .cfi_endproc
+.LFE0:
+ .size f1, .-f1
+ .globl f2
+ .type f2, @function
+f2:
+.LFB1:
+ .loc 1 34 0
+ .cfi_startproc
+.LVL1:
+ .loc 1 53 0
+ movl vv(%rip), %eax
+ addl $1, %eax
+ movl %eax, vv(%rip)
+ .loc 1 54 0
+ cvttsd2si %xmm0, %eax
+ movl %eax, vv(%rip)
+ .loc 1 55 0
+ cvttsd2si %xmm1, %eax
+ movl %eax, vv(%rip)
+ .loc 1 56 0
+ cvttsd2si %xmm2, %eax
+ movl %eax, vv(%rip)
+ .loc 1 57 0
+ cvttss2si %xmm3, %eax
+ movl %eax, vv(%rip)
+ .loc 1 58 0
+ cvttss2si %xmm4, %r8d
+ movl %r8d, vv(%rip)
+ .loc 1 59 0
+ movl %edi, vv(%rip)
+ .loc 1 60 0
+ movl %esi, vv(%rip)
+ .loc 1 61 0
+ movl %edx, vv(%rip)
+ .loc 1 62 0
+ movl %ecx, vv(%rip)
+ .loc 1 63 0
+ movl %eax, vv(%rip)
+ .loc 1 64 0
+ ret
+ .cfi_endproc
+.LFE1:
+ .size f2, .-f2
+ .globl f3
+ .type f3, @function
+f3:
+.LFB2:
+ .loc 1 68 0
+ .cfi_startproc
+.LVL2:
+ .loc 1 73 0
+ movl vv(%rip), %eax
+ addl $1, %eax
+ movl %eax, vv(%rip)
+ .loc 1 74 0
+ ret
+ .cfi_endproc
+.LFE2:
+ .size f3, .-f3
+ .globl f4
+ .type f4, @function
+f4:
+.LFB3:
+ .loc 1 78 0
+ .cfi_startproc
+.LVL3:
+ .loc 1 82 0
+ movl vv(%rip), %eax
+ addl $1, %eax
+ movl %eax, vv(%rip)
+ .loc 1 83 0
+ ret
+ .cfi_endproc
+.LFE3:
+ .size f4, .-f4
+ .globl _start
+ .type _start, @function
+_start:
+.LFB4:
+ .loc 1 87 0
+ .cfi_startproc
+ subq $8, %rsp
+.LCFI0:
+ .cfi_def_cfa_offset 16
+ .loc 1 88 0
+ movl $9, %ecx
+ movl $8, %edx
+ movl $7, %esi
+ movl $6, %edi
+ movss .LC2(%rip), %xmm4
+ movss .LC3(%rip), %xmm3
+ movsd .LC0(%rip), %xmm2
+ movsd .LC1(%rip), %xmm1
+ movsd .LC4(%rip), %xmm0
+ call f1
+.LVL4:
+ .loc 1 89 0
+ movl $9, %ecx
+ movl $8, %edx
+ movl $7, %esi
+ movl $6, %edi
+ movss .LC2(%rip), %xmm4
+ movss .LC3(%rip), %xmm3
+ movsd .LC0(%rip), %xmm2
+ movsd .LC1(%rip), %xmm1
+ movsd .LC4(%rip), %xmm0
+ call f2
+.LVL5:
+ .loc 1 90 0
+ movl $4, %ecx
+ movl $3, %edx
+ movl $2, %esi
+ movl $1, %edi
+ call f3
+.LVL6:
+ .loc 1 91 0
+ movdqa .LC5(%rip), %xmm2
+ movq .LC6(%rip), %xmm1
+ movd .LC7(%rip), %xmm0
+ call f4
+.LVL7:
+ .loc 1 93 0
+ movl $0, %eax
+ addq $8, %rsp
+.LCFI1:
+ .cfi_def_cfa_offset 8
+ ret
+ .cfi_endproc
+.LFE4:
+ .size _start, .-_start
+ .comm vv,4,4
+ .section .rodata.cst8,"aM",@progbits,8
+ .align 8
+.LC0:
+ .long 0
+ .long 1074266112
+ .align 8
+.LC1:
+ .long 0
+ .long 1073741824
+ .section .rodata.cst4,"aM",@progbits,4
+ .align 4
+.LC2:
+ .long 1084227584
+ .align 4
+.LC3:
+ .long 1082130432
+ .section .rodata.cst8
+ .align 8
+.LC4:
+ .long 0
+ .long 1072693248
+ .section .rodata.cst16,"aM",@progbits,16
+ .align 16
+.LC5:
+ .quad 640
+ .quad 3476215962376601600
+ .section .rodata.cst8
+ .align 8
+.LC6:
+ .quad 3575858104132173984
+ .section .rodata.cst4
+ .align 4
+.LC7:
+ .long 838860880
+ .text
+.Letext0:
+ .section .debug_info,"",@progbits
+.Ldebug_info0:
+ .long 0x6c4
+ .value 0x2
+ .long .Ldebug_abbrev0
+ .byte 0x8
+ .uleb128 0x1
+ .long .LASF8
+ .byte 0x1
+ .long .LASF9
+ .long .LASF10
+ .quad .Ltext0
+ .quad .Letext0
+ .long .Ldebug_line0
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0x4
+ .long .LASF0
+ .uleb128 0x2
+ .byte 0x4
+ .byte 0x4
+ .long .LASF1
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0x7
+ .long .LASF2
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0x5
+ .long .LASF3
+ .uleb128 0x2
+ .byte 0x4
+ .byte 0x7
+ .long .LASF4
+ .uleb128 0x3
+ .byte 0x4
+ .byte 0x5
+ .string "int"
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0xf
+ .long .LASF5
+ .uleb128 0x2
+ .byte 0x4
+ .byte 0xf
+ .long .LASF6
+ .uleb128 0x2
+ .byte 0x10
+ .byte 0xf
+ .long .LASF7
+ .uleb128 0x4
+ .byte 0x1
+ .string "f1"
+ .byte 0x1
+ .byte 0x9
+ .byte 0x1
+ .quad .LFB0
+ .quad .LFE0
+ .byte 0x2
+ .byte 0x77
+ .sleb128 8
+ .byte 0x1
+ .long 0x22b
+ .uleb128 0x5
+ .string "a"
+ .byte 0x1
+ .byte 0x9
+ .long 0x2d
+ .byte 0x1
+ .byte 0x61
+ .uleb128 0x5
+ .string "b"
+ .byte 0x1
+ .byte 0x9
+ .long 0x2d
+ .byte 0x1
+ .byte 0x62
+ .uleb128 0x5
+ .string "c"
+ .byte 0x1
+ .byte 0x9
+ .long 0x2d
+ .byte 0x1
+ .byte 0x63
+ .uleb128 0x5
+ .string "d"
+ .byte 0x1
+ .byte 0x9
+ .long 0x34
+ .byte 0x1
+ .byte 0x64
+ .uleb128 0x5
+ .string "e"
+ .byte 0x1
+ .byte 0x9
+ .long 0x34
+ .byte 0x1
+ .byte 0x65
+ .uleb128 0x5
+ .string "f"
+ .byte 0x1
+ .byte 0x9
+ .long 0x50
+ .byte 0x1
+ .byte 0x55
+ .uleb128 0x5
+ .string "g"
+ .byte 0x1
+ .byte 0x9
+ .long 0x49
+ .byte 0x1
+ .byte 0x54
+ .uleb128 0x5
+ .string "h"
+ .byte 0x1
+ .byte 0x9
+ .long 0x22b
+ .byte 0x1
+ .byte 0x51
+ .uleb128 0x5
+ .string "i"
+ .byte 0x1
+ .byte 0x9
+ .long 0x232
+ .byte 0x1
+ .byte 0x52
+ .uleb128 0x6
+ .string "j"
+ .byte 0x1
+ .byte 0xb
+ .long 0x2d
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "l"
+ .byte 0x1
+ .byte 0xc
+ .long 0x22b
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0xf9
+ .uleb128 0x3b
+ .byte 0x9f
+ .uleb128 0x6
+ .string "m"
+ .byte 0x1
+ .byte 0xe
+ .long 0x22b
+ .byte 0x1
+ .byte 0x63
+ .uleb128 0x6
+ .string "n"
+ .byte 0x1
+ .byte 0x10
+ .long 0x34
+ .byte 0x7
+ .byte 0x72
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x3b
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "o"
+ .byte 0x1
+ .byte 0x11
+ .long 0x2d
+ .byte 0x7
+ .byte 0x71
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x42
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "p"
+ .byte 0x1
+ .byte 0x12
+ .long 0x34
+ .byte 0x7
+ .byte 0x74
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x49
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "q"
+ .byte 0x1
+ .byte 0x13
+ .long 0x2d
+ .byte 0x7
+ .byte 0x75
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x50
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "r"
+ .byte 0x1
+ .byte 0x14
+ .long 0x232
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x3b
+ .byte 0x9f
+ .uleb128 0x6
+ .string "s"
+ .byte 0x1
+ .byte 0x15
+ .long 0x22b
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x13
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x42
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "t"
+ .byte 0x1
+ .byte 0x16
+ .long 0x49
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x49
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "u"
+ .byte 0x1
+ .byte 0x17
+ .long 0x50
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x50
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "v"
+ .byte 0x1
+ .byte 0x18
+ .long 0x34
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "w"
+ .byte 0x1
+ .byte 0x19
+ .long 0x2d
+ .byte 0x12
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x3fd00000
+ .byte 0x1e
+ .byte 0x9f
+ .uleb128 0x6
+ .string "x"
+ .byte 0x1
+ .byte 0x1a
+ .long 0x2d
+ .byte 0x14
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0x22
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x3ff00000
+ .byte 0x22
+ .byte 0x9f
+ .uleb128 0x6
+ .string "y"
+ .byte 0x1
+ .byte 0x1b
+ .long 0x2d
+ .byte 0x14
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0xf5
+ .uleb128 0x13
+ .uleb128 0x2d
+ .byte 0x22
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40000000
+ .byte 0x22
+ .byte 0x9f
+ .uleb128 0x6
+ .string "z"
+ .byte 0x1
+ .byte 0x1c
+ .long 0x34
+ .byte 0x12
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf3
+ .uleb128 0x3
+ .byte 0xf5
+ .uleb128 0x15
+ .uleb128 0x34
+ .byte 0x22
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40400000
+ .byte 0x22
+ .byte 0x9f
+ .byte 0
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0x5
+ .long .LASF11
+ .uleb128 0x2
+ .byte 0x8
+ .byte 0x7
+ .long .LASF12
+ .uleb128 0x4
+ .byte 0x1
+ .string "f2"
+ .byte 0x1
+ .byte 0x21
+ .byte 0x1
+ .quad .LFB1
+ .quad .LFE1
+ .byte 0x2
+ .byte 0x77
+ .sleb128 8
+ .byte 0x1
+ .long 0x402
+ .uleb128 0x5
+ .string "a"
+ .byte 0x1
+ .byte 0x21
+ .long 0x2d
+ .byte 0x1
+ .byte 0x61
+ .uleb128 0x5
+ .string "b"
+ .byte 0x1
+ .byte 0x21
+ .long 0x2d
+ .byte 0x1
+ .byte 0x62
+ .uleb128 0x5
+ .string "c"
+ .byte 0x1
+ .byte 0x21
+ .long 0x2d
+ .byte 0x1
+ .byte 0x63
+ .uleb128 0x5
+ .string "d"
+ .byte 0x1
+ .byte 0x21
+ .long 0x34
+ .byte 0x1
+ .byte 0x64
+ .uleb128 0x5
+ .string "e"
+ .byte 0x1
+ .byte 0x21
+ .long 0x34
+ .byte 0x1
+ .byte 0x65
+ .uleb128 0x5
+ .string "f"
+ .byte 0x1
+ .byte 0x21
+ .long 0x50
+ .byte 0x1
+ .byte 0x55
+ .uleb128 0x5
+ .string "g"
+ .byte 0x1
+ .byte 0x21
+ .long 0x49
+ .byte 0x1
+ .byte 0x54
+ .uleb128 0x5
+ .string "h"
+ .byte 0x1
+ .byte 0x21
+ .long 0x22b
+ .byte 0x1
+ .byte 0x51
+ .uleb128 0x5
+ .string "i"
+ .byte 0x1
+ .byte 0x21
+ .long 0x232
+ .byte 0x1
+ .byte 0x52
+ .uleb128 0x6
+ .string "j"
+ .byte 0x1
+ .byte 0x23
+ .long 0x2d
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "l"
+ .byte 0x1
+ .byte 0x24
+ .long 0x22b
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0xf9
+ .uleb128 0x3b
+ .byte 0x9f
+ .uleb128 0x6
+ .string "m"
+ .byte 0x1
+ .byte 0x26
+ .long 0x22b
+ .byte 0x1
+ .byte 0x63
+ .uleb128 0x6
+ .string "n"
+ .byte 0x1
+ .byte 0x28
+ .long 0x34
+ .byte 0x7
+ .byte 0x72
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x3b
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "o"
+ .byte 0x1
+ .byte 0x29
+ .long 0x2d
+ .byte 0x7
+ .byte 0x71
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x42
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "p"
+ .byte 0x1
+ .byte 0x2a
+ .long 0x34
+ .byte 0x7
+ .byte 0x74
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x49
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "q"
+ .byte 0x1
+ .byte 0x2b
+ .long 0x2d
+ .byte 0x7
+ .byte 0x75
+ .sleb128 0
+ .byte 0xf7
+ .uleb128 0x50
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0x9f
+ .uleb128 0x6
+ .string "r"
+ .byte 0x1
+ .byte 0x2c
+ .long 0x232
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x3b
+ .byte 0x9f
+ .uleb128 0x6
+ .string "s"
+ .byte 0x1
+ .byte 0x2d
+ .long 0x22b
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x13
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x42
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "t"
+ .byte 0x1
+ .byte 0x2e
+ .long 0x49
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x49
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "u"
+ .byte 0x1
+ .byte 0x2f
+ .long 0x50
+ .byte 0x8
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x50
+ .byte 0xf7
+ .uleb128 0
+ .byte 0x9f
+ .uleb128 0x6
+ .string "v"
+ .byte 0x1
+ .byte 0x30
+ .long 0x34
+ .byte 0x6
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf7
+ .uleb128 0x34
+ .byte 0x9f
+ .uleb128 0x6
+ .string "w"
+ .byte 0x1
+ .byte 0x31
+ .long 0x2d
+ .byte 0x12
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf7
+ .uleb128 0x2d
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x3fd00000
+ .byte 0x1e
+ .byte 0x9f
+ .uleb128 0x6
+ .string "x"
+ .byte 0x1
+ .byte 0x32
+ .long 0x2d
+ .byte 0x20
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x2d
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0x22
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40080000
+ .byte 0x1c
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0x78b58c40
+ .long 0x4415af1d
+ .byte 0x22
+ .byte 0x9f
+ .uleb128 0x6
+ .string "y"
+ .byte 0x1
+ .byte 0x33
+ .long 0x2d
+ .byte 0x14
+ .byte 0xf5
+ .uleb128 0x13
+ .uleb128 0x2d
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x401c0000
+ .byte 0x1e
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x2d
+ .byte 0x22
+ .byte 0x9f
+ .uleb128 0x6
+ .string "z"
+ .byte 0x1
+ .byte 0x34
+ .long 0x34
+ .byte 0x10
+ .byte 0xf5
+ .uleb128 0x14
+ .uleb128 0x34
+ .byte 0xf5
+ .uleb128 0x15
+ .uleb128 0x34
+ .byte 0x22
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40400000
+ .byte 0x22
+ .byte 0x9f
+ .byte 0
+ .uleb128 0x4
+ .byte 0x1
+ .string "f3"
+ .byte 0x1
+ .byte 0x43
+ .byte 0x1
+ .quad .LFB2
+ .quad .LFE2
+ .byte 0x2
+ .byte 0x77
+ .sleb128 8
+ .byte 0x1
+ .long 0x4cd
+ .uleb128 0x5
+ .string "a"
+ .byte 0x1
+ .byte 0x43
+ .long 0x22b
+ .byte 0x1
+ .byte 0x55
+ .uleb128 0x5
+ .string "b"
+ .byte 0x1
+ .byte 0x43
+ .long 0x50
+ .byte 0x1
+ .byte 0x54
+ .uleb128 0x5
+ .string "c"
+ .byte 0x1
+ .byte 0x43
+ .long 0x22b
+ .byte 0x1
+ .byte 0x51
+ .uleb128 0x5
+ .string "d"
+ .byte 0x1
+ .byte 0x43
+ .long 0x49
+ .byte 0x1
+ .byte 0x52
+ .uleb128 0x6
+ .string "w"
+ .byte 0x1
+ .byte 0x45
+ .long 0x22b
+ .byte 0x14
+ .byte 0x72
+ .sleb128 0
+ .byte 0xc
+ .long 0xffffffff
+ .byte 0x1a
+ .byte 0x12
+ .byte 0x75
+ .sleb128 0
+ .byte 0x16
+ .byte 0x14
+ .byte 0x2b
+ .byte 0x28
+ .value 0x1
+ .byte 0x16
+ .byte 0x13
+ .byte 0x9f
+ .uleb128 0x6
+ .string "x"
+ .byte 0x1
+ .byte 0x46
+ .long 0x22b
+ .byte 0xe
+ .byte 0x74
+ .sleb128 0
+ .byte 0x8
+ .byte 0x20
+ .byte 0x24
+ .byte 0x8
+ .byte 0x20
+ .byte 0x26
+ .byte 0x75
+ .sleb128 0
+ .byte 0x22
+ .byte 0x23
+ .uleb128 0x7
+ .byte 0x9f
+ .uleb128 0x6
+ .string "y"
+ .byte 0x1
+ .byte 0x47
+ .long 0x22b
+ .byte 0x13
+ .byte 0x72
+ .sleb128 0
+ .byte 0xc
+ .long 0xffffffff
+ .byte 0x1a
+ .byte 0x71
+ .sleb128 0
+ .byte 0x22
+ .byte 0x23
+ .uleb128 0x912345678
+ .byte 0x9f
+ .uleb128 0x6
+ .string "z"
+ .byte 0x1
+ .byte 0x48
+ .long 0x50
+ .byte 0x21
+ .byte 0x74
+ .sleb128 0
+ .byte 0x8
+ .byte 0x20
+ .byte 0x24
+ .byte 0x8
+ .byte 0x20
+ .byte 0x26
+ .byte 0x75
+ .sleb128 0
+ .byte 0x22
+ .byte 0x23
+ .uleb128 0x7
+ .byte 0x72
+ .sleb128 0
+ .byte 0xc
+ .long 0xffffffff
+ .byte 0x1a
+ .byte 0x71
+ .sleb128 0
+ .byte 0x22
+ .byte 0x23
+ .uleb128 0x912345678
+ .byte 0x22
+ .byte 0x9f
+ .byte 0
+ .uleb128 0x4
+ .byte 0x1
+ .string "f4"
+ .byte 0x1
+ .byte 0x4d
+ .byte 0x1
+ .quad .LFB3
+ .quad .LFE3
+ .byte 0x2
+ .byte 0x77
+ .sleb128 8
+ .byte 0x1
+ .long 0x576
+ .uleb128 0x5
+ .string "a"
+ .byte 0x1
+ .byte 0x4d
+ .long 0x5e
+ .byte 0x1
+ .byte 0x61
+ .uleb128 0x5
+ .string "b"
+ .byte 0x1
+ .byte 0x4d
+ .long 0x57
+ .byte 0x1
+ .byte 0x62
+ .uleb128 0x5
+ .string "c"
+ .byte 0x1
+ .byte 0x4d
+ .long 0x65
+ .byte 0x1
+ .byte 0x63
+ .uleb128 0x6
+ .string "w"
+ .byte 0x1
+ .byte 0x4f
+ .long 0x5e
+ .byte 0x14
+ .byte 0xf5
+ .uleb128 0x11
+ .uleb128 0x5e
+ .byte 0xf4
+ .uleb128 0x5e
+ .byte 0x4
+ .long 0x32000050
+ .byte 0x1e
+ .byte 0xf4
+ .uleb128 0x5e
+ .byte 0x4
+ .long 0x3200003c
+ .byte 0x22
+ .byte 0x9f
+ .uleb128 0x6
+ .string "x"
+ .byte 0x1
+ .byte 0x50
+ .long 0x57
+ .byte 0x1c
+ .byte 0xf5
+ .uleb128 0x12
+ .uleb128 0x57
+ .byte 0xf4
+ .uleb128 0x57
+ .byte 0x8
+ .long 0x50
+ .long 0x31a00000
+ .byte 0x1b
+ .byte 0xf4
+ .uleb128 0x57
+ .byte 0x8
+ .long 0x3c
+ .long 0x31a00000
+ .byte 0x1c
+ .byte 0x9f
+ .uleb128 0x6
+ .string "y"
+ .byte 0x1
+ .byte 0x51
+ .long 0x65
+ .byte 0x19
+ .byte 0xf5
+ .uleb128 0x13
+ .uleb128 0x65
+ .byte 0x1f
+ .byte 0xf4
+ .uleb128 0x65
+ .byte 0x10
+ .long 0x50
+ .long 0
+ .long 0
+ .long 0x303e0000
+ .byte 0x1b
+ .byte 0x9f
+ .byte 0
+ .uleb128 0x7
+ .byte 0x1
+ .long .LASF13
+ .byte 0x1
+ .byte 0x56
+ .long 0x50
+ .quad .LFB4
+ .quad .LFE4
+ .long .LLST0
+ .byte 0x1
+ .long 0x6a1
+ .uleb128 0x8
+ .quad .LVL4
+ .long 0x6c
+ .long 0x604
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x61
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x3ff00000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x62
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40000000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x63
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40080000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x64
+ .byte 0x7
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40800000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x65
+ .byte 0x7
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40a00000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x55
+ .byte 0x1
+ .byte 0x36
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x54
+ .byte 0x1
+ .byte 0x37
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x51
+ .byte 0x1
+ .byte 0x38
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x52
+ .byte 0x1
+ .byte 0x39
+ .byte 0
+ .uleb128 0x8
+ .quad .LVL5
+ .long 0x239
+ .long 0x66d
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x61
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x3ff00000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x62
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40000000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x63
+ .byte 0xb
+ .byte 0xf4
+ .uleb128 0x2d
+ .byte 0x8
+ .long 0
+ .long 0x40080000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x64
+ .byte 0x7
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40800000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x65
+ .byte 0x7
+ .byte 0xf4
+ .uleb128 0x34
+ .byte 0x4
+ .long 0x40a00000
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x55
+ .byte 0x1
+ .byte 0x36
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x54
+ .byte 0x1
+ .byte 0x37
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x51
+ .byte 0x1
+ .byte 0x38
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x52
+ .byte 0x1
+ .byte 0x39
+ .byte 0
+ .uleb128 0x8
+ .quad .LVL6
+ .long 0x402
+ .long 0x693
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x55
+ .byte 0x1
+ .byte 0x31
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x54
+ .byte 0x1
+ .byte 0x32
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x51
+ .byte 0x1
+ .byte 0x33
+ .uleb128 0x9
+ .byte 0x1
+ .byte 0x52
+ .byte 0x1
+ .byte 0x34
+ .byte 0
+ .uleb128 0xa
+ .quad .LVL7
+ .long 0x4cd
+ .byte 0
+ .uleb128 0xb
+ .string "vv"
+ .byte 0x1
+ .byte 0x5
+ .long 0x6ad
+ .byte 0x1
+ .byte 0x1
+ .uleb128 0xc
+ .long 0x50
+ .uleb128 0xd
+ .string "vv"
+ .byte 0x1
+ .byte 0x5
+ .long 0x6ad
+ .byte 0x1
+ .byte 0x9
+ .byte 0x3
+ .quad vv
+ .byte 0
+ .section .debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+ .uleb128 0x1
+ .uleb128 0x11
+ .byte 0x1
+ .uleb128 0x25
+ .uleb128 0xe
+ .uleb128 0x13
+ .uleb128 0xb
+ .uleb128 0x3
+ .uleb128 0xe
+ .uleb128 0x1b
+ .uleb128 0xe
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x12
+ .uleb128 0x1
+ .uleb128 0x10
+ .uleb128 0x6
+ .byte 0
+ .byte 0
+ .uleb128 0x2
+ .uleb128 0x24
+ .byte 0
+ .uleb128 0xb
+ .uleb128 0xb
+ .uleb128 0x3e
+ .uleb128 0xb
+ .uleb128 0x3
+ .uleb128 0xe
+ .byte 0
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x24
+ .byte 0
+ .uleb128 0xb
+ .uleb128 0xb
+ .uleb128 0x3e
+ .uleb128 0xb
+ .uleb128 0x3
+ .uleb128 0x8
+ .byte 0
+ .byte 0
+ .uleb128 0x4
+ .uleb128 0x2e
+ .byte 0x1
+ .uleb128 0x3f
+ .uleb128 0xc
+ .uleb128 0x3
+ .uleb128 0x8
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x27
+ .uleb128 0xc
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x12
+ .uleb128 0x1
+ .uleb128 0x40
+ .uleb128 0xa
+ .uleb128 0x2117
+ .uleb128 0xc
+ .uleb128 0x1
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0x5
+ .uleb128 0x5
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x8
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x2
+ .uleb128 0xa
+ .byte 0
+ .byte 0
+ .uleb128 0x6
+ .uleb128 0x34
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x8
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x2
+ .uleb128 0xa
+ .byte 0
+ .byte 0
+ .uleb128 0x7
+ .uleb128 0x2e
+ .byte 0x1
+ .uleb128 0x3f
+ .uleb128 0xc
+ .uleb128 0x3
+ .uleb128 0xe
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x12
+ .uleb128 0x1
+ .uleb128 0x40
+ .uleb128 0x6
+ .uleb128 0x2117
+ .uleb128 0xc
+ .uleb128 0x1
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0x8
+ .uleb128 0x4109
+ .byte 0x1
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x31
+ .uleb128 0x13
+ .uleb128 0x1
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0x9
+ .uleb128 0x410a
+ .byte 0
+ .uleb128 0x2
+ .uleb128 0xa
+ .uleb128 0x2111
+ .uleb128 0xa
+ .byte 0
+ .byte 0
+ .uleb128 0xa
+ .uleb128 0x4109
+ .byte 0
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x31
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0xb
+ .uleb128 0x34
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x8
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x3f
+ .uleb128 0xc
+ .uleb128 0x3c
+ .uleb128 0xc
+ .byte 0
+ .byte 0
+ .uleb128 0xc
+ .uleb128 0x35
+ .byte 0
+ .uleb128 0x49
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0xd
+ .uleb128 0x34
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x8
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x3f
+ .uleb128 0xc
+ .uleb128 0x2
+ .uleb128 0xa
+ .byte 0
+ .byte 0
+ .byte 0
+ .section .debug_loc,"",@progbits
+.Ldebug_loc0:
+.LLST0:
+ .quad .LFB4-.Ltext0
+ .quad .LCFI0-.Ltext0
+ .value 0x2
+ .byte 0x77
+ .sleb128 8
+ .quad .LCFI0-.Ltext0
+ .quad .LCFI1-.Ltext0
+ .value 0x2
+ .byte 0x77
+ .sleb128 16
+ .quad .LCFI1-.Ltext0
+ .quad .LFE4-.Ltext0
+ .value 0x2
+ .byte 0x77
+ .sleb128 8
+ .quad 0
+ .quad 0
+ .section .debug_aranges,"",@progbits
+ .long 0x2c
+ .value 0x2
+ .long .Ldebug_info0
+ .byte 0x8
+ .byte 0
+ .value 0
+ .value 0
+ .quad .Ltext0
+ .quad .Letext0-.Ltext0
+ .quad 0
+ .quad 0
+ .section .debug_line,"",@progbits
+.Ldebug_line0:
+ .section .debug_str,"MS",@progbits,1
+.LASF4:
+ .string "unsigned int"
+.LASF6:
+ .string "_Decimal32"
+.LASF7:
+ .string "_Decimal128"
+.LASF2:
+ .string "long unsigned int"
+.LASF12:
+ .string "long long unsigned int"
+.LASF5:
+ .string "_Decimal64"
+.LASF13:
+ .string "main"
+.LASF3:
+ .string "long int"
+.LASF10:
+ .string "/tmp"
+.LASF0:
+ .string "double"
+.LASF11:
+ .string "long long int"
+.LASF1:
+ .string "float"
+.LASF8:
+ .string "GNU C 4.7.0 20110708 (experimental) [trunk revision 176048]"
+.LASF9:
+ .string "typeddwarf.c"
+ .ident "GCC: (GNU) 4.7.0 20110708 (experimental) [trunk revision 176048]"
+ .section .note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.c b/gdb/testsuite/gdb.dwarf2/typeddwarf.c
index e5f7d67..40497da 100644
--- a/gdb/testsuite/gdb.dwarf2/typeddwarf.c
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.c
@@ -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++;
}
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.exp b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
index e6a420a..36a17e5 100644
--- a/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
@@ -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 {} {
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-22 15:40 ` Tom Tromey
@ 2011-07-22 19:10 ` Pedro Alves
2011-07-22 19:19 ` Tom Tromey
0 siblings, 1 reply; 28+ messages in thread
From: Pedro Alves @ 2011-07-22 19:10 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey, Daniel Jacobowitz
On Friday 22 July 2011 16:19:38, Tom Tromey wrote:
> >>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:
>
> Pedro> # of expected passes 39
> Pedro> with an unpatched gdb (x86-64-linux), same as with patched gdb.
> Pedro> Is that expected?
>
> It definitely fails for me with unpatched gdb.
>
> Does your machine have AVX? I believe it will only fail on an
> AVX-capable machine.
Ah, that's it then. I was curious to know why were the
upper parts of the ymm unavailable.
Are you hitting:
regcache_raw_read ()
{
...
/* A number of targets can't access the whole set of raw
registers (because the debug API provides no means to get at
them). */
if (regcache->register_status[regnum] == REG_UNKNOWN)
regcache->register_status[regnum] = REG_UNAVAILABLE;
}
?
--
Pedro Alves
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-22 19:10 ` Pedro Alves
@ 2011-07-22 19:19 ` Tom Tromey
2011-07-22 19:31 ` Pedro Alves
0 siblings, 1 reply; 28+ messages in thread
From: Tom Tromey @ 2011-07-22 19:19 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches, Daniel Jacobowitz
>>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:
Pedro> Ah, that's it then. I was curious to know why were the
Pedro> upper parts of the ymm unavailable.
amd64_linux_fetch_inferior_registers calls ptrace(PTRACE_GETREGSET)
to fetch the registers. Then it passes this to amd64_supply_xsave,
which calls i387_supply_xsave. This function then decodes the "XCR0"
flag and determines that the upper parts were not supplied by the
kernel; that is, we take the true branch here:
if ((clear_bv & I386_XSTATE_AVX))
p = NULL;
else
p = regs;
Tom
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-22 19:19 ` Tom Tromey
@ 2011-07-22 19:31 ` Pedro Alves
2011-07-22 21:58 ` Pedro Alves
2011-07-22 22:20 ` Tom Tromey
0 siblings, 2 replies; 28+ messages in thread
From: Pedro Alves @ 2011-07-22 19:31 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches, Daniel Jacobowitz
On Friday 22 July 2011 19:55:31, Tom Tromey wrote:
> >>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:
>
> Pedro> Ah, that's it then. I was curious to know why were the
> Pedro> upper parts of the ymm unavailable.
>
> amd64_linux_fetch_inferior_registers calls ptrace(PTRACE_GETREGSET)
> to fetch the registers. Then it passes this to amd64_supply_xsave,
> which calls i387_supply_xsave. This function then decodes the "XCR0"
> flag and determines that the upper parts were not supplied by the
> kernel; that is, we take the true branch here:
>
> if ((clear_bv & I386_XSTATE_AVX))
> p = NULL;
> else
> p = regs;
Ah, thanks. With a bit more context:
case avxh:
if ((clear_bv & I386_XSTATE_AVX))
p = NULL;
else
p = XSAVE_AVXH_ADDR (tdep, regs, regnum);
regcache_raw_supply (regcache, regnum, p);
return;
regcache_raw_supply with p=NULL means the register
is unavailable. But before the <unavailable> stuff,
it meant "supply the register as 0". I seem to remember
discussing this AVX stuff with H.J., and coming to the
conclusion that what want is really 0, but maybe not.
gdbserver is explicitly zeroing in this case, instead
of returning unavailable, see
gdbserver/i387-fp.c:i387_xsave_to_cache.
What does it really mean when you have an AVX
capable machine, but I386_XSTATE_AVX is clear?
Whatever the answer, we need to fix one of native
gdb or gdbserver for consistency.
--
Pedro Alves
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-22 19:31 ` Pedro Alves
@ 2011-07-22 21:58 ` Pedro Alves
2011-07-22 22:20 ` Tom Tromey
1 sibling, 0 replies; 28+ messages in thread
From: Pedro Alves @ 2011-07-22 21:58 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey, Daniel Jacobowitz
On Friday 22 July 2011 20:10:23, Pedro Alves wrote:
> On Friday 22 July 2011 19:55:31, Tom Tromey wrote:
> > >>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:
> >
> > Pedro> Ah, that's it then. I was curious to know why were the
> > Pedro> upper parts of the ymm unavailable.
> >
> > amd64_linux_fetch_inferior_registers calls ptrace(PTRACE_GETREGSET)
> > to fetch the registers. Then it passes this to amd64_supply_xsave,
> > which calls i387_supply_xsave. This function then decodes the "XCR0"
> > flag and determines that the upper parts were not supplied by the
> > kernel; that is, we take the true branch here:
> >
> > if ((clear_bv & I386_XSTATE_AVX))
> > p = NULL;
> > else
> > p = regs;
>
> Ah, thanks. With a bit more context:
>
> case avxh:
> if ((clear_bv & I386_XSTATE_AVX))
> p = NULL;
> else
> p = XSAVE_AVXH_ADDR (tdep, regs, regnum);
> regcache_raw_supply (regcache, regnum, p);
> return;
>
> regcache_raw_supply with p=NULL means the register
> is unavailable. But before the <unavailable> stuff,
> it meant "supply the register as 0". I seem to remember
> discussing this AVX stuff with H.J., and coming to the
> conclusion that what want is really 0, but maybe not.
Found it:
<http://sourceware.org/ml/gdb-patches/2010-10/msg00268.html>
(and follow up)
> gdbserver is explicitly zeroing in this case, instead
> of returning unavailable, see
> gdbserver/i387-fp.c:i387_xsave_to_cache.
>
> What does it really mean when you have an AVX
> capable machine, but I386_XSTATE_AVX is clear?
>
> Whatever the answer, we need to fix one of native
> gdb or gdbserver for consistency.
--
Pedro Alves
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-22 19:31 ` Pedro Alves
2011-07-22 21:58 ` Pedro Alves
@ 2011-07-22 22:20 ` Tom Tromey
2011-07-26 17:08 ` Pedro Alves
1 sibling, 1 reply; 28+ messages in thread
From: Tom Tromey @ 2011-07-22 22:20 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches, Daniel Jacobowitz, hjl
>>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:
CC'ing H.J.
Pedro> But before the <unavailable> stuff, it meant "supply the register
Pedro> as 0". I seem to remember discussing this AVX stuff with H.J.,
Pedro> and coming to the conclusion that what want is really 0, but
Pedro> maybe not.
I am far from being an expert in this area, but from the Intel
Architecture manual, section 13.5.1:
Saving the x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 state using FXSAVE
requires processor overhead. If the new task does not access x87 FPU,
MMX, XMM, and MXCSR registers, avoid overhead by not automatically
saving the state on a task switch.
The TS flag in control register CR0 is provided to allow the operating
system to delay saving the x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 state
until an instruction that actually accesses this state is encountered in
a new task.
So I think what is going on here is that the upper bits of these
registers are truly unavailable, because the inferior has never executed
an instruction referencing them.
Pedro> Whatever the answer, we need to fix one of native
Pedro> gdb or gdbserver for consistency.
If you agree with what I have checked in, I will update gdbserver.
Otherwise, let me know what you think would be correct and I will
implement that, instead, for both.
thanks,
Tom
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-20 20:53 ` Tom Tromey
@ 2011-07-24 13:48 ` Mark Kettenis
2011-07-25 15:50 ` Tom Tromey
0 siblings, 1 reply; 28+ messages in thread
From: Mark Kettenis @ 2011-07-24 13:48 UTC (permalink / raw)
To: tromey; +Cc: drow, gdb-patches
> From: Tom Tromey <tromey@redhat.com>
> Date: Wed, 20 Jul 2011 14:29:03 -0600
>
> Tom> I looked into this, and I changed some things, but I did not change it
> Tom> completely.
>
> I forgot to mention -- please comment. In the absence of comments I
> will commit this version.
Not sure if you already did so, but I'd like to have a proper look at
this before you do so. Just returned from vacation, so it may take a
few days before I've cleared my backlog of things and get to it.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-24 13:48 ` Mark Kettenis
@ 2011-07-25 15:50 ` Tom Tromey
0 siblings, 0 replies; 28+ messages in thread
From: Tom Tromey @ 2011-07-25 15:50 UTC (permalink / raw)
To: Mark Kettenis; +Cc: drow, gdb-patches
>>>>> "Mark" == Mark Kettenis <mark.kettenis@xs4all.nl> writes:
Tom> I forgot to mention -- please comment. In the absence of comments I
Tom> will commit this version.
Mark> Not sure if you already did so, but I'd like to have a proper look at
Mark> this before you do so. Just returned from vacation, so it may take a
Mark> few days before I've cleared my backlog of things and get to it.
It is in, but I will change it if need be.
Tom
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-22 22:20 ` Tom Tromey
@ 2011-07-26 17:08 ` Pedro Alves
2011-07-26 17:13 ` Pedro Alves
2011-07-27 18:25 ` Tom Tromey
0 siblings, 2 replies; 28+ messages in thread
From: Pedro Alves @ 2011-07-26 17:08 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches, Daniel Jacobowitz, hjl
On Friday 22 July 2011 20:30:53, Tom Tromey wrote:
> >>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:
> Pedro> But before the <unavailable> stuff, it meant "supply the register
> Pedro> as 0". I seem to remember discussing this AVX stuff with H.J.,
> Pedro> and coming to the conclusion that what want is really 0, but
> Pedro> maybe not.
>
> I am far from being an expert in this area,
Same here...
> but from the Intel Architecture manual, section 13.5.1:
Thanks. I finally took a bit to read that too.
> Saving the x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 state using FXSAVE
> requires processor overhead. If the new task does not access x87 FPU,
> MMX, XMM, and MXCSR registers, avoid overhead by not automatically
> saving the state on a task switch.
>
> The TS flag in control register CR0 is provided to allow the operating
> system to delay saving the x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 state
> until an instruction that actually accesses this state is encountered in
> a new task.
>
> So I think what is going on here is that the upper bits of these
> registers are truly unavailable, because the inferior has never executed
> an instruction referencing them.
My mental model of <unavailable> is:
<unavailable> means the object exists, and its value exists,
but we have no means to fetch it. This corresponds to trying
to print the value of a register while inspecting a traceframe,
while that register had not been collected by the corresponding
tracepoint -- the register exists in the architecture/machine, but we
can't know what value it had when the tracepoint hit. It also
corresponds to a (trimmed/partial) core dump file not containing a
dump of all the machine's registers, or a dump of all the process'es
mapped memory (due to ulimit, perhaps). And corresponds to not
being able to get at some register's current value because the
debug API exposes no means to get at the current value. Along
with other similar scenarios.
Let me brain dump what I think is happening in this avx case,
to make sure we're on the same page:
In this case, IIUC, with the delayed xsave mechanism active,
if a task has already accessed the x87 states, but hasn't triggered
a delayed x87 states' save/restore since the last context switch, the
current value of the x87 states of that task should be in the
save area (and valie), which is what ptrace gives us when we read
registers. For a task that did access (and change) the x87 state
since the last x87 state save, (I hope!) a ptrace stopped task's
save area is up to date with the real x87 states.
That is, at runtime, the from ptrace's perpective, the delay/lazy
scheme should be transparent, save for one case...
... that is the case of gdb/ptrace reading an x87 state
before the program had first accessed the state itself for the
first time.
H.J.Lu wrote:
> Values in vector registers are invalid, not unavailable. OS
> initializes them to zero when they are set the firs time in
> a program. I prefer *value not valid".
That is, in between the program starting, and the program
acessing the vector registers, the register's values are
invalid. But, given that the kernel will fill them
in with zero's on first access (meaning, from userspace's
perspective, it's the same as if the registers have always
been zero from the start of the program), I think it's best
that a debugger provides the same illusion to the user.
As H.J. wrote:
> GDB may update vector registers before they are set by program.
> GDB sets proper bits in XSAVE area to tell OS/hardware that vector
> registers now have valid values.
... and indeed this is what i387-tdep.c:i387_collect_xsave
appears to be doing.
Am I making sense?
> Pedro> Whatever the answer, we need to fix one of native
> Pedro> gdb or gdbserver for consistency.
>
> If you agree with what I have checked in, I will update gdbserver.
I think your patch implements the right interface for partial
registers support. I like it...
> Otherwise, let me know what you think would be correct and I will
> implement that, instead, for both.
... but I think that we should go with 0, instead of <unavailable>,
meaning changing x87-tdep.c:i387_supply_xsave to supply
explicity zeroed buffer, instead of a NULL pointer, like
gdbserver does.
--
Pedro Alves
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-26 17:08 ` Pedro Alves
@ 2011-07-26 17:13 ` Pedro Alves
2011-07-26 19:46 ` Tom Tromey
2011-07-27 18:25 ` Tom Tromey
1 sibling, 1 reply; 28+ messages in thread
From: Pedro Alves @ 2011-07-26 17:13 UTC (permalink / raw)
To: gdb-patches, H.J. Lu; +Cc: Tom Tromey, Daniel Jacobowitz
On Tuesday 26 July 2011 16:31:18, Pedro Alves wrote:
> On Friday 22 July 2011 20:30:53, Tom Tromey wrote:
> > >>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:
>
> > Pedro> But before the <unavailable> stuff, it meant "supply the register
> > Pedro> as 0". I seem to remember discussing this AVX stuff with H.J.,
> > Pedro> and coming to the conclusion that what want is really 0, but
> > Pedro> maybe not.
> >
> > I am far from being an expert in this area,
>
> Same here...
>
> > but from the Intel Architecture manual, section 13.5.1:
>
> Thanks. I finally took a bit to read that too.
>
> > Saving the x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 state using FXSAVE
> > requires processor overhead. If the new task does not access x87 FPU,
> > MMX, XMM, and MXCSR registers, avoid overhead by not automatically
> > saving the state on a task switch.
> >
> > The TS flag in control register CR0 is provided to allow the operating
> > system to delay saving the x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 state
> > until an instruction that actually accesses this state is encountered in
> > a new task.
> >
> > So I think what is going on here is that the upper bits of these
> > registers are truly unavailable, because the inferior has never executed
> > an instruction referencing them.
>
> My mental model of <unavailable> is:
>
> <unavailable> means the object exists, and its value exists,
> but we have no means to fetch it. This corresponds to trying
> to print the value of a register while inspecting a traceframe,
> while that register had not been collected by the corresponding
> tracepoint -- the register exists in the architecture/machine, but we
> can't know what value it had when the tracepoint hit. It also
> corresponds to a (trimmed/partial) core dump file not containing a
> dump of all the machine's registers, or a dump of all the process'es
> mapped memory (due to ulimit, perhaps). And corresponds to not
> being able to get at some register's current value because the
> debug API exposes no means to get at the current value. Along
> with other similar scenarios.
>
> Let me brain dump what I think is happening in this avx case,
> to make sure we're on the same page:
>
> In this case, IIUC, with the delayed xsave mechanism active,
> if a task has already accessed the x87 states, but hasn't triggered
> a delayed x87 states' save/restore since the last context switch, the
> current value of the x87 states of that task should be in the
> save area (and valie), which is what ptrace gives us when we read
> registers. For a task that did access (and change) the x87 state
> since the last x87 state save, (I hope!) a ptrace stopped task's
> save area is up to date with the real x87 states.
I glanced at:
<http://kerneltrap.org/mailarchive/linux-kernel/2010/2/10/4537101/thread>
and now I'm not sure my last assumption with ptrace stopped tasks
holds. If not, then we have two distinct cases to handle -- x87 state
has never been accessed; and x87 state in the xsave memory area is
not up to date. Is that true? Is there a way to distinguish them?
Is that what linux puts in the SW usable bytes [464..511]?
>
> That is, at runtime, the from ptrace's perpective, the delay/lazy
> scheme should be transparent, save for one case...
>
> ... that is the case of gdb/ptrace reading an x87 state
> before the program had first accessed the state itself for the
> first time.
>
> H.J.Lu wrote:
>
> > Values in vector registers are invalid, not unavailable. OS
> > initializes them to zero when they are set the firs time in
> > a program. I prefer *value not valid".
>
> That is, in between the program starting, and the program
> acessing the vector registers, the register's values are
> invalid. But, given that the kernel will fill them
> in with zero's on first access (meaning, from userspace's
> perspective, it's the same as if the registers have always
> been zero from the start of the program), I think it's best
> that a debugger provides the same illusion to the user.
>
> As H.J. wrote:
>
> > GDB may update vector registers before they are set by program.
> > GDB sets proper bits in XSAVE area to tell OS/hardware that vector
> > registers now have valid values.
>
> ... and indeed this is what i387-tdep.c:i387_collect_xsave
> appears to be doing.
>
> Am I making sense?
>
> > Pedro> Whatever the answer, we need to fix one of native
> > Pedro> gdb or gdbserver for consistency.
> >
> > If you agree with what I have checked in, I will update gdbserver.
>
> I think your patch implements the right interface for partial
> registers support. I like it...
>
> > Otherwise, let me know what you think would be correct and I will
> > implement that, instead, for both.
>
> ... but I think that we should go with 0, instead of <unavailable>,
> meaning changing x87-tdep.c:i387_supply_xsave to supply
> explicity zeroed buffer, instead of a NULL pointer, like
> gdbserver does.
>
>
--
Pedro Alves
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-26 17:13 ` Pedro Alves
@ 2011-07-26 19:46 ` Tom Tromey
0 siblings, 0 replies; 28+ messages in thread
From: Tom Tromey @ 2011-07-26 19:46 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches, H.J. Lu, Daniel Jacobowitz
>>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:
Pedro> I glanced at:
Pedro> <http://kerneltrap.org/mailarchive/linux-kernel/2010/2/10/4537101/thread>
Pedro> and now I'm not sure my last assumption with ptrace stopped tasks
Pedro> holds. If not, then we have two distinct cases to handle -- x87 state
Pedro> has never been accessed; and x87 state in the xsave memory area is
Pedro> not up to date. Is that true? Is there a way to distinguish them?
Pedro> Is that what linux puts in the SW usable bytes [464..511]?
I do not know. I think it would be best if H.J. weighed in on this.
Tom
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-26 17:08 ` Pedro Alves
2011-07-26 17:13 ` Pedro Alves
@ 2011-07-27 18:25 ` Tom Tromey
2011-07-27 19:30 ` Tom Tromey
1 sibling, 1 reply; 28+ messages in thread
From: Tom Tromey @ 2011-07-27 18:25 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches, Daniel Jacobowitz, hjl
>>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:
Pedro> <unavailable> means the object exists, and its value exists,
Pedro> but we have no means to fetch it.
[...]
After re-reading this reply a couple of times and thinking about the
issue, I think you are right, and we should supply 0 instead of
<unavailable> here.
Tom> If you agree with what I have checked in, I will update gdbserver.
Pedro> I think your patch implements the right interface for partial
Pedro> registers support. I like it...
Great.
Pedro> ... but I think that we should go with 0, instead of <unavailable>,
Pedro> meaning changing x87-tdep.c:i387_supply_xsave to supply
Pedro> explicity zeroed buffer, instead of a NULL pointer, like
Pedro> gdbserver does.
I will do this.
Tom
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-27 18:25 ` Tom Tromey
@ 2011-07-27 19:30 ` Tom Tromey
2011-07-27 19:33 ` Pedro Alves
2011-07-28 5:19 ` Mark Kettenis
0 siblings, 2 replies; 28+ messages in thread
From: Tom Tromey @ 2011-07-27 19:30 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches, Daniel Jacobowitz, hjl
Pedro> ... but I think that we should go with 0, instead of <unavailable>,
Pedro> meaning changing x87-tdep.c:i387_supply_xsave to supply
Pedro> explicity zeroed buffer, instead of a NULL pointer, like
Pedro> gdbserver does.
Tom> I will do this.
Here's the patch.
In absence of comment I will check it in, in a couple of days.
Built and regtested by the buildbot.
Tom
2011-07-27 Tom Tromey <tromey@redhat.com>
* i387-tdep.c (i387_supply_xsave): Supply zero for high bits of
AVX registers.
diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
index c4ace82..332d491 100644
--- a/gdb/i387-tdep.c
+++ b/gdb/i387-tdep.c
@@ -798,17 +798,26 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
/* Handle the upper YMM registers. */
if ((tdep->xcr0 & I386_XSTATE_AVX))
{
+ gdb_byte buf[MAX_REGISTER_SIZE];
+
if ((clear_bv & I386_XSTATE_AVX))
- p = NULL;
+ {
+ memset (buf, 0, sizeof (buf));
+ p = NULL;
+ }
else
p = regs;
for (i = I387_YMM0H_REGNUM (tdep);
i < I387_YMMENDH_REGNUM (tdep); i++)
{
+ const void *arg;
+
if (p != NULL)
- p = XSAVE_AVXH_ADDR (tdep, regs, i);
- regcache_raw_supply (regcache, i, p);
+ arg = XSAVE_AVXH_ADDR (tdep, regs, i);
+ else
+ arg = buf;
+ regcache_raw_supply (regcache, i, arg);
}
}
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-27 19:30 ` Tom Tromey
@ 2011-07-27 19:33 ` Pedro Alves
2011-07-28 5:19 ` Mark Kettenis
1 sibling, 0 replies; 28+ messages in thread
From: Pedro Alves @ 2011-07-27 19:33 UTC (permalink / raw)
To: Tom Tromey, H.J. Lu; +Cc: gdb-patches, Daniel Jacobowitz
On Wednesday 27 July 2011 20:08:26, Tom Tromey wrote:
> Pedro> ... but I think that we should go with 0, instead of <unavailable>,
> Pedro> meaning changing x87-tdep.c:i387_supply_xsave to supply
> Pedro> explicity zeroed buffer, instead of a NULL pointer, like
> Pedro> gdbserver does.
>
> Tom> I will do this.
>
> Here's the patch.
Thanks. Why only the AVX state though? There are
several other places in the same function that
pass NULL to regcache_raw_supply that I think
should get the same treatment.
i387_supply_xsave accepts and handles a NULL XSAVE
argument. I suppose it's for cores that miss the
xsave section? I can't quite tell what path ends
up calling i387_supply_xsave with NULL. Maybe it's
dead code (I remember this code having changed a bit
the design throughout the review iterations; this bit may
have been left behind). If not dead, that may be a genuine
case for <unavailable>.
>
> In absence of comment I will check it in, in a couple of days.
>
> Built and regtested by the buildbot.
>
> Tom
>
> 2011-07-27 Tom Tromey <tromey@redhat.com>
>
> * i387-tdep.c (i387_supply_xsave): Supply zero for high bits of
> AVX registers.
>
> diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
> index c4ace82..332d491 100644
> --- a/gdb/i387-tdep.c
> +++ b/gdb/i387-tdep.c
> @@ -798,17 +798,26 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
> /* Handle the upper YMM registers. */
> if ((tdep->xcr0 & I386_XSTATE_AVX))
> {
> + gdb_byte buf[MAX_REGISTER_SIZE];
> +
> if ((clear_bv & I386_XSTATE_AVX))
> - p = NULL;
> + {
> + memset (buf, 0, sizeof (buf));
> + p = NULL;
> + }
> else
> p = regs;
>
> for (i = I387_YMM0H_REGNUM (tdep);
> i < I387_YMMENDH_REGNUM (tdep); i++)
> {
> + const void *arg;
> +
> if (p != NULL)
> - p = XSAVE_AVXH_ADDR (tdep, regs, i);
> - regcache_raw_supply (regcache, i, p);
> + arg = XSAVE_AVXH_ADDR (tdep, regs, i);
> + else
> + arg = buf;
> + regcache_raw_supply (regcache, i, arg);
> }
> }
>
>
--
Pedro Alves
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: RFC: partially available registers
2011-07-27 19:30 ` Tom Tromey
2011-07-27 19:33 ` Pedro Alves
@ 2011-07-28 5:19 ` Mark Kettenis
1 sibling, 0 replies; 28+ messages in thread
From: Mark Kettenis @ 2011-07-28 5:19 UTC (permalink / raw)
To: tromey; +Cc: pedro, gdb-patches, drow, hjl
> From: Tom Tromey <tromey@redhat.com>
> Date: Wed, 27 Jul 2011 13:08:26 -0600
>
> Pedro> ... but I think that we should go with 0, instead of <unavailable>,
> Pedro> meaning changing x87-tdep.c:i387_supply_xsave to supply
> Pedro> explicity zeroed buffer, instead of a NULL pointer, like
> Pedro> gdbserver does.
>
> Tom> I will do this.
>
> Here's the patch.
>
> In absence of comment I will check it in, in a couple of days.
Please hold off for a moment.
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2011-07-27 19:57 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-13 20:17 RFC: partially available registers Tom Tromey
2011-07-14 4:24 ` Daniel Jacobowitz
2011-07-15 20:52 ` Tom Tromey
2011-07-18 4:15 ` Daniel Jacobowitz
2011-07-20 20:14 ` Pedro Alves
2011-07-20 18:49 ` Sergio Durigan Junior
2011-07-20 20:46 ` Tom Tromey
2011-07-20 20:53 ` Tom Tromey
2011-07-24 13:48 ` Mark Kettenis
2011-07-25 15:50 ` Tom Tromey
2011-07-21 5:23 ` Ulrich Weigand
2011-07-21 20:27 ` Tom Tromey
2011-07-22 13:48 ` Ulrich Weigand
2011-07-22 15:42 ` Tom Tromey
2011-07-22 14:30 ` Pedro Alves
2011-07-22 15:40 ` Tom Tromey
2011-07-22 19:10 ` Pedro Alves
2011-07-22 19:19 ` Tom Tromey
2011-07-22 19:31 ` Pedro Alves
2011-07-22 21:58 ` Pedro Alves
2011-07-22 22:20 ` Tom Tromey
2011-07-26 17:08 ` Pedro Alves
2011-07-26 17:13 ` Pedro Alves
2011-07-26 19:46 ` Tom Tromey
2011-07-27 18:25 ` Tom Tromey
2011-07-27 19:30 ` Tom Tromey
2011-07-27 19:33 ` Pedro Alves
2011-07-28 5:19 ` Mark Kettenis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).