summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2015-11-05 14:50:24 +0100
committerRichard Henderson <rth@redhat.com>2015-11-05 14:50:24 +0100
commit247584d3808b66e4059be8b6758382e92350c04b (patch)
treeb0499d39d44d602b7375ef5ae9da165eca3e9caa
parent4a2bd92e409721ec80e42e5a9ac58d71c5c0fa16 (diff)
downloadbinutils-gdb-users/rth/x86-seg.tar.gz
Segment support for x86_64, part 2users/rth/x86-seg
* amd64-tdep.c (amd64_address_to_pointer): New. (amd64_pointer_to_address): New. (amd64_init_abi): Register them.
-rw-r--r--gdb/amd64-tdep.c63
1 files changed, 60 insertions, 3 deletions
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index 3f12796f500..b3276928bf8 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -2934,9 +2934,64 @@ amd64_address_class_name_to_type_flags (struct gdbarch *gdbarch,
return 0;
}
-/* ??? We ought to fill in address_to_pointer and pointer_to_address,
- except that these hooks do not have access to the thread, or a
- regcache for the thread. */
+static void
+amd64_address_to_pointer (struct gdbarch *gdbarch, struct type *type,
+ gdb_byte *buf, CORE_ADDR addr)
+{
+ int regnum = -1;
+
+ switch (TYPE_ADDRESS_CLASS_ALL (type))
+ {
+ case TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1:
+ regnum = AMD64_FSBASE_REGNUM;
+ break;
+ case TYPE_INSTANCE_FLAG_ADDRESS_CLASS_2:
+ regnum = AMD64_GSBASE_REGNUM;
+ break;
+ }
+ if (regnum >= 0)
+ {
+ struct regcache *regcache = get_current_regcache ();
+ ULONGEST base;
+
+ if (regcache_raw_read_unsigned (regcache, regnum, &base) == REG_VALID)
+ addr -= base;
+ /* ??? else error, but we have no way to signal that here. */
+ }
+
+ store_unsigned_integer (buf, TYPE_LENGTH (type), BFD_ENDIAN_LITTLE, addr);
+}
+
+static CORE_ADDR
+amd64_pointer_to_address (struct gdbarch *gdbarch, struct type *type,
+ const gdb_byte *buf)
+{
+ ULONGEST addr = extract_unsigned_integer (buf, TYPE_LENGTH (type),
+ BFD_ENDIAN_LITTLE);
+ int regnum = -1;
+
+ switch (TYPE_ADDRESS_CLASS_ALL (type))
+ {
+ case TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1:
+ regnum = AMD64_FSBASE_REGNUM;
+ break;
+ case TYPE_INSTANCE_FLAG_ADDRESS_CLASS_2:
+ regnum = AMD64_GSBASE_REGNUM;
+ break;
+ }
+ if (regnum >= 0)
+ {
+ struct regcache *regcache = get_current_regcache ();
+ ULONGEST base;
+
+ if (regcache_raw_read_unsigned (regcache, regnum, &base) == REG_VALID)
+ addr += base;
+ /* ??? else error, but we have no way to signal that here. */
+ }
+
+ return addr;
+}
+
/* Figure out where the longjmp will land. Slurp the jmp_buf out of
@@ -3149,6 +3204,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
(gdbarch, amd64_address_class_type_flags_to_name);
set_gdbarch_address_class_name_to_type_flags
(gdbarch, amd64_address_class_name_to_type_flags);
+ set_gdbarch_address_to_pointer (gdbarch, amd64_address_to_pointer);
+ set_gdbarch_pointer_to_address (gdbarch, amd64_pointer_to_address);
}