summaryrefslogtreecommitdiffstats
path: root/backends
diff options
context:
space:
mode:
authorRoland McGrath <[email protected]>2006-10-10 00:25:21 +0000
committerRoland McGrath <[email protected]>2006-10-10 00:25:21 +0000
commitc373d850ec9ca342f4c71d5e287c8d8bf0723cd6 (patch)
treec8f9ea814866cdfb30ac9506ccddbc8629ebe345 /backends
parent1dee360aa30fecd20f403f98fd1cb9e543afcca7 (diff)
2006-10-09 Roland McGrath <[email protected]>
* ia64_symbol.c (ia64_reloc_simple_type): Treat SECREL types as simple.
Diffstat (limited to 'backends')
-rw-r--r--backends/ChangeLog27
-rw-r--r--backends/Makefile.am2
-rw-r--r--backends/i386_init.c4
-rw-r--r--backends/i386_regs.c42
-rw-r--r--backends/ia64_init.c2
-rw-r--r--backends/ia64_regs.c28
-rw-r--r--backends/ia64_symbol.c11
-rw-r--r--backends/ppc64_init.c4
-rw-r--r--backends/ppc_init.c4
-rw-r--r--backends/ppc_regs.c18
-rw-r--r--backends/s390_init.c2
-rw-r--r--backends/s390_regs.c25
-rw-r--r--backends/sparc_init.c5
-rw-r--r--backends/sparc_regs.c50
-rw-r--r--backends/sparc_retval.c154
-rw-r--r--backends/x86_64_init.c4
-rw-r--r--backends/x86_64_regs.c33
17 files changed, 365 insertions, 50 deletions
diff --git a/backends/ChangeLog b/backends/ChangeLog
index 34ec4cfd..86ac44b9 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,30 @@
+2006-10-09 Roland McGrath <[email protected]>
+
+ * ia64_symbol.c (ia64_reloc_simple_type): Treat SECREL types as simple.
+
+2006-08-29 Roland McGrath <[email protected]>
+
+ * sparc_retval.c: New file.
+ * Makefile.am (sparc_SRCS): Add it.
+ * sparc_init.c (sparc_init): Initialize return_value_location hook.
+
+2006-08-22 Roland McGrath <[email protected]>
+
+ * i386_regs.c (i386_register_name): Renamed i386_register_info.
+ Take new args, yield more info.
+ * i386_init.c (i386_init): Update initializer.
+ * ia64_regs.c (ia64_register_name): Likewise.
+ * ia64_init.c (ia64_init): Likewise.
+ * ppc_regs.c (ppc_register_name): Likewise.
+ * ppc64_init.c (ppc64_init): Likewise.
+ * ppc_init.c (ppc_init): Likewise.
+ * s390_regs.c (s390_register_name): Likewise.
+ * s390_init.c (s390_init): Likewise.
+ * sparc_regs.c (sparc_register_name): Likewise.
+ * sparc_init.c (sparc_init): Likewise.
+ * x86_64_regs.c (x86_64_register_name): Likewise.
+ * x86_64_init.c (x86_64_init): Likewise.
+
2006-08-08 Roland McGrath <[email protected]>
* Makefile.am (%.os): Don't depend on %.o, since we don't actually
diff --git a/backends/Makefile.am b/backends/Makefile.am
index a81c90e9..8af59139 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -95,7 +95,7 @@ arm_SRCS = arm_init.c arm_symbol.c
libebl_arm_pic_a_SOURCES = $(arm_SRCS)
am_libebl_arm_pic_a_OBJECTS = $(arm_SRCS:.c=.os)
-sparc_SRCS = sparc_init.c sparc_symbol.c sparc_regs.c
+sparc_SRCS = sparc_init.c sparc_symbol.c sparc_regs.c sparc_retval.c
libebl_sparc_pic_a_SOURCES = $(sparc_SRCS)
am_libebl_sparc_pic_a_OBJECTS = $(sparc_SRCS:.c=.os)
diff --git a/backends/i386_init.c b/backends/i386_init.c
index e0742b70..9f240075 100644
--- a/backends/i386_init.c
+++ b/backends/i386_init.c
@@ -1,5 +1,5 @@
/* Initialization of i386 specific backend library.
- Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+ Copyright (C) 2000, 2001, 2002, 2005, 2006 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <[email protected]>, 2000.
@@ -55,7 +55,7 @@ i386_init (elf, machine, eh, ehlen)
generic_debugscn_p = eh->debugscn_p;
HOOK (eh, debugscn_p);
HOOK (eh, return_value_location);
- HOOK (eh, register_name);
+ HOOK (eh, register_info);
return MODVERSION;
}
diff --git a/backends/i386_regs.c b/backends/i386_regs.c
index 248700b6..a63c5439 100644
--- a/backends/i386_regs.c
+++ b/backends/i386_regs.c
@@ -28,14 +28,16 @@
#endif
#include <string.h>
+#include <dwarf.h>
#define BACKEND i386_
#include "libebl_CPU.h"
ssize_t
-i386_register_name (Ebl *ebl __attribute__ ((unused)),
+i386_register_info (Ebl *ebl __attribute__ ((unused)),
int regno, char *name, size_t namelen,
- const char **prefix, const char **setname)
+ const char **prefix, const char **setname,
+ int *bits, int *type)
{
if (name == NULL)
return 46;
@@ -44,18 +46,37 @@ i386_register_name (Ebl *ebl __attribute__ ((unused)),
return -1;
*prefix = "%";
+ *bits = 32;
+ *type = DW_ATE_unsigned;
if (regno < 11)
- *setname = "integer";
+ {
+ *setname = "integer";
+ if (regno < 9)
+ *type = DW_ATE_signed;
+ }
else if (regno < 19)
- *setname = "x87";
+ {
+ *setname = "x87";
+ *type = DW_ATE_float;
+ *bits = 80;
+ }
else if (regno < 29)
- *setname = "SSE";
+ {
+ *setname = "SSE";
+ *bits = 128;
+ }
else if (regno < 37)
- *setname = "MMX";
+ {
+ *setname = "MMX";
+ *bits = 64;
+ }
else if (regno < 40)
*setname = "FPU-control";
else
- *setname = "segment";
+ {
+ *setname = "segment";
+ *bits = 16;
+ }
switch (regno)
{
@@ -64,7 +85,12 @@ i386_register_name (Ebl *ebl __attribute__ ((unused)),
"ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "ip"
};
- case 0 ... 8:
+ case 4:
+ case 5:
+ case 8:
+ *type = DW_ATE_address;
+ case 0 ... 3:
+ case 6 ... 7:
name[0] = 'e';
name[1] = baseregs[regno][0];
name[2] = baseregs[regno][1];
diff --git a/backends/ia64_init.c b/backends/ia64_init.c
index 490c774a..acae2346 100644
--- a/backends/ia64_init.c
+++ b/backends/ia64_init.c
@@ -55,7 +55,7 @@ ia64_init (elf, machine, eh, ehlen)
HOOK (eh, dynamic_tag_name);
HOOK (eh, dynamic_tag_check);
HOOK (eh, machine_flag_check);
- HOOK (eh, register_name);
+ HOOK (eh, register_info);
HOOK (eh, return_value_location);
return MODVERSION;
diff --git a/backends/ia64_regs.c b/backends/ia64_regs.c
index 076609db..0460739c 100644
--- a/backends/ia64_regs.c
+++ b/backends/ia64_regs.c
@@ -28,14 +28,16 @@
#endif
#include <string.h>
+#include <dwarf.h>
#define BACKEND i386_
#include "libebl_CPU.h"
ssize_t
-ia64_register_name (Ebl *ebl __attribute__ ((unused)),
+ia64_register_info (Ebl *ebl __attribute__ ((unused)),
int regno, char *name, size_t namelen,
- const char **prefix, const char **setname)
+ const char **prefix, const char **setname,
+ int *bits, int *type)
{
if (name == NULL)
return 687 + 64;
@@ -45,6 +47,8 @@ ia64_register_name (Ebl *ebl __attribute__ ((unused)),
*prefix = "ar.";
*setname = "application";
+ *bits = 64;
+ *type = DW_ATE_signed;
switch (regno)
{
case 0 ... 9:
@@ -78,6 +82,8 @@ ia64_register_name (Ebl *ebl __attribute__ ((unused)),
name[0] = 'f';
name[1] = (regno - 128) + '0';
namelen = 2;
+ *type = DW_ATE_float;
+ *bits = 128;
*setname = "FPU";
*prefix = "";
break;
@@ -97,6 +103,8 @@ ia64_register_name (Ebl *ebl __attribute__ ((unused)),
name[2] = (regno - 128 - 100) / 10 + '0';
name[3] = (regno - 128) % 10 + '0';
namelen = 4;
+ *type = DW_ATE_float;
+ *bits = 128;
*setname = "FPU";
*prefix = "";
break;
@@ -105,6 +113,7 @@ ia64_register_name (Ebl *ebl __attribute__ ((unused)),
name[0] = 'b';
name[1] = (regno - 320) + '0';
namelen = 2;
+ *type = DW_ATE_address;
*setname = "branch";
*prefix = "";
break;
@@ -117,12 +126,14 @@ ia64_register_name (Ebl *ebl __attribute__ ((unused)),
};
*setname = "special";
*prefix = "";
+ *type = regno == 331 ? DW_ATE_address : DW_ATE_unsigned;
return stpcpy (name, named_special[regno - 328]) + 1 - name;
}
case 590:
*setname = "special";
*prefix = "";
+ *type = DW_ATE_unsigned;
return stpcpy (name, "bof") + 1 - name;
case 334 + 0 ... 334 + 7:
@@ -158,6 +169,9 @@ ia64_register_name (Ebl *ebl __attribute__ ((unused)),
[66 - 8] = "ec",
};
const size_t idx = regno - (334 + 8);
+ *type = DW_ATE_unsigned;
+ if (idx == 1 || idx == 2)
+ *type = DW_ATE_address;
if (idx < sizeof named_ar / sizeof named_ar[0]
&& named_ar[idx][0] != '\0')
return stpcpy (name, named_ar[idx]) + 1 - name;
@@ -193,6 +207,8 @@ ia64_register_name (Ebl *ebl __attribute__ ((unused)),
name[3] = (regno - 462) + '0';
namelen = 4;
*setname = "NAT";
+ *type = DW_ATE_boolean;
+ *bits = 1;
*prefix = "";
break;
@@ -204,6 +220,8 @@ ia64_register_name (Ebl *ebl __attribute__ ((unused)),
name[4] = (regno - 462) % 10 + '0';
namelen = 5;
*setname = "NAT";
+ *type = DW_ATE_boolean;
+ *bits = 1;
*prefix = "";
break;
@@ -216,6 +234,8 @@ ia64_register_name (Ebl *ebl __attribute__ ((unused)),
name[5] = (regno - 462) % 10 + '0';
namelen = 6;
*setname = "NAT";
+ *type = DW_ATE_boolean;
+ *bits = 1;
*prefix = "";
break;
@@ -224,6 +244,8 @@ ia64_register_name (Ebl *ebl __attribute__ ((unused)),
name[1] = (regno - 687) + '0';
namelen = 2;
*setname = "predicate";
+ *type = DW_ATE_boolean;
+ *bits = 1;
*prefix = "";
break;
@@ -233,6 +255,8 @@ ia64_register_name (Ebl *ebl __attribute__ ((unused)),
name[2] = (regno - 687) % 10 + '0';
namelen = 3;
*setname = "predicate";
+ *type = DW_ATE_boolean;
+ *bits = 1;
*prefix = "";
break;
diff --git a/backends/ia64_symbol.c b/backends/ia64_symbol.c
index d7caaf38..4faec0c9 100644
--- a/backends/ia64_symbol.c
+++ b/backends/ia64_symbol.c
@@ -1,5 +1,5 @@
/* IA-64 specific symbolic name handling.
- Copyright (C) 2002, 2003, 2005 Red Hat, Inc.
+ Copyright (C) 2002, 2003, 2005, 2006 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <[email protected]>, 2002.
@@ -109,18 +109,27 @@ ia64_reloc_simple_type (Ebl *ebl, int type)
{
switch (type)
{
+ /* The SECREL types when used with non-allocated sections
+ like .debug_* are the same as direct absolute relocs
+ applied to those sections, since a 0 section address is assumed.
+ So we treat them the same here. */
+
+ case R_IA64_SECREL32MSB:
case R_IA64_DIR32MSB:
if (ebl->data == ELFDATA2MSB)
return ELF_T_WORD;
break;
+ case R_IA64_SECREL32LSB:
case R_IA64_DIR32LSB:
if (ebl->data == ELFDATA2LSB)
return ELF_T_WORD;
break;
case R_IA64_DIR64MSB:
+ case R_IA64_SECREL64MSB:
if (ebl->data == ELFDATA2MSB)
return ELF_T_XWORD;
break;
+ case R_IA64_SECREL64LSB:
case R_IA64_DIR64LSB:
if (ebl->data == ELFDATA2LSB)
return ELF_T_XWORD;
diff --git a/backends/ppc64_init.c b/backends/ppc64_init.c
index 1d4e8304..8cd75357 100644
--- a/backends/ppc64_init.c
+++ b/backends/ppc64_init.c
@@ -1,5 +1,5 @@
/* Initialization of PPC64 specific backend library.
- Copyright (C) 2004, 2005 Red Hat, Inc.
+ Copyright (C) 2004, 2005, 2006 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <[email protected]>, 2004.
@@ -57,7 +57,7 @@ ppc64_init (elf, machine, eh, ehlen)
HOOK (eh, check_special_symbol);
HOOK (eh, bss_plt_p);
HOOK (eh, return_value_location);
- HOOK (eh, register_name);
+ HOOK (eh, register_info);
return MODVERSION;
}
diff --git a/backends/ppc_init.c b/backends/ppc_init.c
index 1663258c..1dfd5ec9 100644
--- a/backends/ppc_init.c
+++ b/backends/ppc_init.c
@@ -1,5 +1,5 @@
/* Initialization of PPC specific backend library.
- Copyright (C) 2004, 2005 Red Hat, Inc.
+ Copyright (C) 2004, 2005, 2006 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <[email protected]>, 2004.
@@ -56,7 +56,7 @@ ppc_init (elf, machine, eh, ehlen)
HOOK (eh, check_special_symbol);
HOOK (eh, bss_plt_p);
HOOK (eh, return_value_location);
- HOOK (eh, register_name);
+ HOOK (eh, register_info);
return MODVERSION;
}
diff --git a/backends/ppc_regs.c b/backends/ppc_regs.c
index bea8d357..3d47d3d0 100644
--- a/backends/ppc_regs.c
+++ b/backends/ppc_regs.c
@@ -28,14 +28,16 @@
#endif
#include <string.h>
+#include <dwarf.h>
#define BACKEND ppc_
#include "libebl_CPU.h"
ssize_t
-ppc_register_name (Ebl *ebl __attribute__ ((unused)),
+ppc_register_info (Ebl *ebl __attribute__ ((unused)),
int regno, char *name, size_t namelen,
- const char **prefix, const char **setname)
+ const char **prefix, const char **setname,
+ int *bits, int *type)
{
if (name == NULL)
return 1156;
@@ -44,6 +46,9 @@ ppc_register_name (Ebl *ebl __attribute__ ((unused)),
return -1;
*prefix = NULL;
+ *bits = ebl->machine == EM_PPC64 ? 64 : 32;
+ *type = (regno < 32 ? DW_ATE_signed
+ : regno < 64 ? DW_ATE_float : DW_ATE_unsigned);
if (regno < 32 || regno == 64 || regno == 66)
*setname = "integer";
@@ -52,7 +57,10 @@ ppc_register_name (Ebl *ebl __attribute__ ((unused)),
else if (regno < 1124)
*setname = "privileged";
else
- *setname = "vector";
+ {
+ *setname = "vector";
+ *bits = 128;
+ }
switch (regno)
{
@@ -155,5 +163,5 @@ ppc_register_name (Ebl *ebl __attribute__ ((unused)),
return namelen;
}
-__typeof (ppc_register_name)
- ppc64_register_name __attribute__ ((alias ("ppc_register_name")));
+__typeof (ppc_register_info)
+ ppc64_register_info __attribute__ ((alias ("ppc_register_info")));
diff --git a/backends/s390_init.c b/backends/s390_init.c
index 80cbb832..05ffce60 100644
--- a/backends/s390_init.c
+++ b/backends/s390_init.c
@@ -50,7 +50,7 @@ s390_init (elf, machine, eh, ehlen)
eh->name = "IBM S/390";
s390_init_reloc (eh);
HOOK (eh, reloc_simple_type);
- HOOK (eh, register_name);
+ HOOK (eh, register_info);
HOOK (eh, return_value_location);
/* Only the 64-bit format uses the incorrect hash table entry size. */
diff --git a/backends/s390_regs.c b/backends/s390_regs.c
index 28b79898..7e8113a2 100644
--- a/backends/s390_regs.c
+++ b/backends/s390_regs.c
@@ -28,6 +28,7 @@
#endif
#include <string.h>
+#include <dwarf.h>
#define BACKEND s390_
#include "libebl_CPU.h"
@@ -50,9 +51,10 @@ zseries (64)
ssize_t
-s390_register_name (Ebl *ebl __attribute__ ((unused)),
+s390_register_info (Ebl *ebl __attribute__ ((unused)),
int regno, char *name, size_t namelen,
- const char **prefix, const char **setname)
+ const char **prefix, const char **setname,
+ int *bits, int *type)
{
if (name == NULL)
return 66;
@@ -62,14 +64,26 @@ s390_register_name (Ebl *ebl __attribute__ ((unused)),
*prefix = "%";
+ *bits = ebl->class == ELFCLASS64 ? 64 : 32;
+ *type = DW_ATE_unsigned;
if (regno < 16)
- *setname = "integer";
+ {
+ *setname = "integer";
+ *type = DW_ATE_signed;
+ }
else if (regno < 32)
- *setname = "FPU";
+ {
+ *setname = "FPU";
+ *type = DW_ATE_float;
+ *bits = 64;
+ }
else if (regno < 48 || regno > 63)
*setname = "control";
else
- *setname = "access";
+ {
+ *setname = "access";
+ *bits = 32;
+ }
switch (regno)
{
@@ -116,6 +130,7 @@ s390_register_name (Ebl *ebl __attribute__ ((unused)),
case 64:
return stpcpy (name, "pswm") + 1 - name;
case 65:
+ *type = DW_ATE_address;
return stpcpy (name, "pswa") + 1 - name;
default:
diff --git a/backends/sparc_init.c b/backends/sparc_init.c
index 3767c1a8..ba0e08a3 100644
--- a/backends/sparc_init.c
+++ b/backends/sparc_init.c
@@ -1,5 +1,5 @@
/* Initialization of SPARC specific backend library.
- Copyright (C) 2002, 2005 Red Hat, Inc.
+ Copyright (C) 2002, 2005, 2006 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -56,7 +56,8 @@ sparc_init (elf, machine, eh, ehlen)
sparc_init_reloc (eh);
HOOK (eh, reloc_simple_type);
//HOOK (eh, core_note);
- HOOK (eh, register_name);
+ HOOK (eh, register_info);
+ HOOK (eh, return_value_location);
return MODVERSION;
}
diff --git a/backends/sparc_regs.c b/backends/sparc_regs.c
index 820878e1..b3e9e201 100644
--- a/backends/sparc_regs.c
+++ b/backends/sparc_regs.c
@@ -28,45 +28,77 @@
#endif
#include <string.h>
+#include <dwarf.h>
#define BACKEND sparc_
#include "libebl_CPU.h"
ssize_t
-sparc_register_name (Ebl *ebl,
+sparc_register_info (Ebl *ebl,
int regno, char *name, size_t namelen,
- const char **prefix, const char **setname)
+ const char **prefix, const char **setname,
+ int *bits, int *type)
{
- const int nfp = ebl->machine == EM_SPARC ? 32 : 64;
+ const int nfp = 32 + (ebl->machine == EM_SPARC ? 0 : 16);
+ const int nspec = ebl->machine == EM_SPARC ? 8 : 6;
if (name == NULL)
- return 32 + nfp;
+ return 32 + nfp + nspec;
- if (regno < 0 || regno >= 32 + nfp || namelen < 4)
+ if (regno < 0 || regno >= 32 + nfp + nspec || namelen < 6)
return -1;
+ *bits = ebl->machine == EM_SPARC ? 32 : 64;
+ *type = DW_ATE_signed;
+
*prefix = "%";
+ if (regno >= 32 + nfp)
+ {
+ regno -= 32 + nfp;
+ static const char names[2][8][6] =
+ {
+ { "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr" }, /* v8 */
+ { "pc", "npc", "state", "fsr", "fprs", "y" } /* v9 */
+ };
+ *setname = "control";
+ *type = DW_ATE_unsigned;
+ if ((ebl->machine != EM_SPARC ? 0 : 4) + 1 - (unsigned int) regno <= 1)
+ *type = DW_ATE_address;
+ return stpncpy (name, names[ebl->machine != EM_SPARC][regno],
+ namelen) + 1 - name;
+ }
+
if (regno < 32)
{
*setname = "integer";
name[0] = "goli"[regno >> 3];
name[1] = (regno & 7) + '0';
namelen = 2;
+ if ((regno & 8) && (regno & 7) == 6)
+ *type = DW_ATE_address;
}
else
{
*setname = "FPU";
+ *type = DW_ATE_float;
+
+ regno -= 32;
+ if (regno >= 32)
+ regno = 32 + 2 * (regno - 32);
+ else
+ *bits = 32;
+
name[0] = 'f';
- if (regno < 32 + 10)
+ if (regno < 10)
{
- name[1] = (regno - 32) + '0';
+ name[1] = regno + '0';
namelen = 2;
}
else
{
- name[1] = (regno - 32) / 10 + '0';
- name[2] = (regno - 32) % 10 + '0';
+ name[1] = regno / 10 + '0';
+ name[2] = regno % 10 + '0';
namelen = 3;
}
}
diff --git a/backends/sparc_retval.c b/backends/sparc_retval.c
new file mode 100644
index 00000000..cfde0d2f
--- /dev/null
+++ b/backends/sparc_retval.c
@@ -0,0 +1,154 @@
+/* Function return value location for SPARC.
+ Copyright (C) 2006 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND sparc_
+#include "libebl_CPU.h"
+
+
+/* %o0, or pair %o0, %o1. */
+static const Dwarf_Op loc_intreg[] =
+ {
+ { .atom = DW_OP_reg8 }, { .atom = DW_OP_piece, .number = 4 },
+ { .atom = DW_OP_reg9 }, { .atom = DW_OP_piece, .number = 4 },
+ };
+#define nloc_intreg 1
+#define nloc_intregpair 4
+
+/* %f0 or pair %f0, %f1, or quad %f0..%f3. */
+static const Dwarf_Op loc_fpreg[] =
+ {
+ { .atom = DW_OP_regx, .number = 32 }, { .atom = DW_OP_piece, .number = 4 },
+ { .atom = DW_OP_regx, .number = 33 }, { .atom = DW_OP_piece, .number = 4 },
+ { .atom = DW_OP_regx, .number = 34 }, { .atom = DW_OP_piece, .number = 4 },
+ { .atom = DW_OP_regx, .number = 35 }, { .atom = DW_OP_piece, .number = 4 },
+ };
+#define nloc_fpreg 1
+#define nloc_fpregpair 4
+#define nloc_fpregquad 8
+
+/* The return value is a structure and is actually stored in stack space
+ passed in a hidden argument by the caller. But, the compiler
+ helpfully returns the address of that space in %o0. */
+static const Dwarf_Op loc_aggregate[] =
+ {
+ { .atom = DW_OP_breg8, .number = 0 }
+ };
+#define nloc_aggregate 1
+
+int
+sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+ /* Start with the function's type, and get the DW_AT_type attribute,
+ which is the type of the return value. */
+
+ Dwarf_Attribute attr_mem;
+ Dwarf_Attribute *attr = dwarf_attr (functypedie, DW_AT_type, &attr_mem);
+ if (attr == NULL)
+ /* The function has no return value, like a `void' function in C. */
+ return 0;
+
+ Dwarf_Die die_mem;
+ Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
+ int tag = dwarf_tag (typedie);
+
+ /* Follow typedefs and qualifiers to get to the actual type. */
+ while (tag == DW_TAG_typedef
+ || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
+ || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
+ {
+ attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+ typedie = dwarf_formref_die (attr, &die_mem);
+ tag = dwarf_tag (typedie);
+ }
+
+ Dwarf_Word size;
+ switch (tag)
+ {
+ case -1:
+ return -1;
+
+ case DW_TAG_subrange_type:
+ if (! dwarf_hasattr (typedie, DW_AT_byte_size))
+ {
+ attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+ typedie = dwarf_formref_die (attr, &die_mem);
+ tag = dwarf_tag (typedie);
+ }
+ /* Fall through. */
+
+ case DW_TAG_base_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_ptr_to_member_type:
+ if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
+ &attr_mem), &size) != 0)
+ {
+ uint8_t asize;
+ Dwarf_Die cudie;
+ if ((tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ && dwarf_diecu (typedie, &cudie, &asize, NULL) != NULL)
+ size = asize;
+ else
+ return -1;
+ }
+ if (tag == DW_TAG_base_type)
+ {
+ Dwarf_Word encoding;
+ if (dwarf_formudata (dwarf_attr (typedie, DW_AT_encoding,
+ &attr_mem), &encoding) != 0)
+ return -1;
+ if (encoding == DW_ATE_float)
+ {
+ *locp = loc_fpreg;
+ if (size <= 4)
+ return nloc_fpreg;
+ if (size <= 8)
+ return nloc_fpregpair;
+ if (size <= 16)
+ return nloc_fpregquad;
+ }
+ }
+ if (size <= 8)
+ {
+ intreg:
+ *locp = loc_intreg;
+ return size <= 4 ? nloc_intreg : nloc_intregpair;
+ }
+
+ aggregate:
+ *locp = loc_aggregate;
+ return nloc_aggregate;
+
+ case DW_TAG_structure_type:
+ case DW_TAG_class_type:
+ case DW_TAG_union_type:
+ case DW_TAG_array_type:
+ if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
+ &attr_mem), &size) == 0
+ && size > 0 && size <= 8)
+ goto intreg;
+ goto aggregate;
+ }
+
+ /* XXX We don't have a good way to return specific errors from ebl calls.
+ This value means we do not understand the type, but it is well-formed
+ DWARF and might be valid. */
+ return -2;
+}
diff --git a/backends/x86_64_init.c b/backends/x86_64_init.c
index 4951e1c7..476f4ed2 100644
--- a/backends/x86_64_init.c
+++ b/backends/x86_64_init.c
@@ -1,5 +1,5 @@
/* Initialization of x86-64 specific backend library.
- Copyright (C) 2002, 2005 Red Hat, Inc.
+ Copyright (C) 2002, 2005, 2006 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <[email protected]>, 2002.
@@ -54,7 +54,7 @@ x86_64_init (elf, machine, eh, ehlen)
HOOK (eh, reloc_simple_type);
HOOK (eh, core_note);
HOOK (eh, return_value_location);
- HOOK (eh, register_name);
+ HOOK (eh, register_info);
return MODVERSION;
}
diff --git a/backends/x86_64_regs.c b/backends/x86_64_regs.c
index 45ef94ea..1128a352 100644
--- a/backends/x86_64_regs.c
+++ b/backends/x86_64_regs.c
@@ -1,5 +1,5 @@
/* Register names and numbers for x86-64 DWARF.
- Copyright (C) 2005 Red Hat, Inc.
+ Copyright (C) 2005, 2006 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -34,9 +34,10 @@
#include "libebl_CPU.h"
ssize_t
-x86_64_register_name (Ebl *ebl __attribute__ ((unused)),
+x86_64_register_info (Ebl *ebl __attribute__ ((unused)),
int regno, char *name, size_t namelen,
- const char **prefix, const char **setname)
+ const char **prefix, const char **setname,
+ int *bits, int *type)
{
if (name == NULL)
return 49;
@@ -45,14 +46,32 @@ x86_64_register_name (Ebl *ebl __attribute__ ((unused)),
return -1;
*prefix = "%";
+ *bits = 64;
+ *type = DW_ATE_unsigned;
if (regno < 17)
- *setname = "integer";
+ {
+ *setname = "integer";
+ if (regno == 16 || regno == 6 || regno == 7)
+ *type = DW_ATE_address;
+ else
+ *type = DW_ATE_signed;
+ }
else if (regno < 33)
- *setname = "SSE";
+ {
+ *setname = "SSE";
+ *bits = 128;
+ }
else if (regno < 41)
- *setname = "x87";
+ {
+ *setname = "x87";
+ *type = DW_ATE_float;
+ *bits = 80;
+ }
else
- *setname = "MMX";
+ {
+ *setname = "MMX";
+ *bits = 64;
+ }
switch (regno)
{