aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@gnu.org>2004-05-09 19:48:25 +0000
committerMark Kettenis <kettenis@gnu.org>2004-05-09 19:48:25 +0000
commit6fa57a7d27e4a8d192a9a83952002f9603b6aa3a (patch)
treee230fd0180bed7273af46f3236a1ee8ffafe9d62
parente47577ab7b5afee567e9f300c054a25cd7fe1d1b (diff)
downloadbinutils-6fa57a7d27e4a8d192a9a83952002f9603b6aa3a.zip
binutils-6fa57a7d27e4a8d192a9a83952002f9603b6aa3a.tar.gz
binutils-6fa57a7d27e4a8d192a9a83952002f9603b6aa3a.tar.bz2
* amd64-tdep.c (amd64_return_value): Implement
RETURN_VALUE_ABI_RETURNS_ADDRESS.
-rw-r--r--gdb/ChangeLog3
-rw-r--r--gdb/amd64-tdep.c25
2 files changed, 24 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 75fa25a..248c120 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,8 @@
2004-05-09 Mark Kettenis <kettenis@gnu.org>
+ * amd64-tdep.c (amd64_return_value): Implement
+ RETURN_VALUE_ABI_RETURNS_ADDRESS.
+
* m68k-tdep.c (m68k_convert_register_p, m68k_register_to_value)
(m68k_value_to_register): New functions.
(m68k_gdbarch_init): Set convert_register_p, register_to_value and
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index d165714..2b56776 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -422,11 +422,28 @@ amd64_return_value (struct gdbarch *gdbarch, struct type *type,
amd64_classify (type, class);
/* 2. If the type has class MEMORY, then the caller provides space
- for the return value and passes the address of this storage in
- %rdi as if it were the first argument to the function. In
- effect, this address becomes a hidden first argument. */
+ for the return value and passes the address of this storage in
+ %rdi as if it were the first argument to the function. In effect,
+ this address becomes a hidden first argument.
+
+ On return %rax will contain the address that has been passed in
+ by the caller in %rdi. */
if (class[0] == AMD64_MEMORY)
- return RETURN_VALUE_STRUCT_CONVENTION;
+ {
+ /* As indicated by the comment above, the ABI guarantees that we
+ can always find the return value just after the function has
+ returned. */
+
+ if (readbuf)
+ {
+ ULONGEST addr;
+
+ regcache_raw_read_unsigned (regcache, AMD64_RAX_REGNUM, &addr);
+ read_memory (addr, readbuf, TYPE_LENGTH (type));
+ }
+
+ return RETURN_VALUE_ABI_RETURNS_ADDRESS;
+ }
gdb_assert (class[1] != AMD64_MEMORY);
gdb_assert (len <= 16);