summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2006-07-21 10:06:31 +0000
committerRoland McGrath <roland@redhat.com>2006-07-21 10:06:31 +0000
commit950246297c03f9ce25f645470250619e40d71018 (patch)
tree9727ed2b50b6c582cfb7f36672361f7f3d335876
parent858b189f82ecc32ca7042e74ccb022f794a9f83b (diff)
downloadelfutils-950246297c03f9ce25f645470250619e40d71018.tar.gz
backends/
2006-07-21 Roland McGrath <roland@redhat.com> * i386_regs.c (i386_register_name): Fix return value when using stpcpy. * ppc_regs.c (ppc_register_name): Likewise. * s390_regs.c (s390_register_name): Likewise. * ia64_retval.c: New file. * Makefile.am (ia64_SRCS): Add it. * ia64_init.c (ia64_init): Install return_value_location hook. * ia64_regs.c: New file. * Makefile.am (ia64_SRCS): Add it. * ia64_init.c (ia64_init): Install register_name hook. tests/ 2006-07-21 Roland McGrath <roland@redhat.com> * allregs.c (struct reginfo): Increase size of name. (one_register): Assert that it's big enough.
-rw-r--r--backends/ChangeLog14
-rw-r--r--backends/Makefile.am2
-rw-r--r--backends/i386_regs.c12
-rw-r--r--backends/ia64_init.c4
-rw-r--r--backends/ia64_regs.c219
-rw-r--r--backends/ia64_retval.c223
-rw-r--r--backends/ppc_regs.c8
-rw-r--r--backends/s390_regs.c4
-rw-r--r--tests/ChangeLog5
-rw-r--r--tests/allregs.c5
10 files changed, 480 insertions, 16 deletions
diff --git a/backends/ChangeLog b/backends/ChangeLog
index e7416332..949f8375 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,17 @@
+2006-07-21 Roland McGrath <roland@redhat.com>
+
+ * i386_regs.c (i386_register_name): Fix return value when using stpcpy.
+ * ppc_regs.c (ppc_register_name): Likewise.
+ * s390_regs.c (s390_register_name): Likewise.
+
+ * ia64_retval.c: New file.
+ * Makefile.am (ia64_SRCS): Add it.
+ * ia64_init.c (ia64_init): Install return_value_location hook.
+
+ * ia64_regs.c: New file.
+ * Makefile.am (ia64_SRCS): Add it.
+ * ia64_init.c (ia64_init): Install register_name hook.
+
2006-07-05 Ulrich Drepper <drepper@redhat.com>
* alpha_init.c: Initialize sysvhash_entrysize.
diff --git a/backends/Makefile.am b/backends/Makefile.am
index 13a809de..95143bcb 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -84,7 +84,7 @@ x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c \
libebl_x86_64_pic_a_SOURCES = $(x86_64_SRCS)
am_libebl_x86_64_pic_a_OBJECTS = $(x86_64_SRCS:.c=.os)
-ia64_SRCS = ia64_init.c ia64_symbol.c
+ia64_SRCS = ia64_init.c ia64_symbol.c ia64_regs.c ia64_retval.c
libebl_ia64_pic_a_SOURCES = $(ia64_SRCS)
am_libebl_ia64_pic_a_OBJECTS = $(ia64_SRCS:.c=.os)
diff --git a/backends/i386_regs.c b/backends/i386_regs.c
index c2c21423..248700b6 100644
--- a/backends/i386_regs.c
+++ b/backends/i386_regs.c
@@ -1,5 +1,5 @@
/* Register names and numbers for i386 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
@@ -72,9 +72,9 @@ i386_register_name (Ebl *ebl __attribute__ ((unused)),
break;
case 9:
- return stpcpy (name, "eflags") - name;
+ return stpcpy (name, "eflags") + 1 - name;
case 10:
- return stpcpy (name, "trapno") - name;
+ return stpcpy (name, "trapno") + 1 - name;
case 11 ... 18:
name[0] = 's';
@@ -99,11 +99,11 @@ i386_register_name (Ebl *ebl __attribute__ ((unused)),
break;
case 37:
- return stpcpy (name, "fctrl") - name;
+ return stpcpy (name, "fctrl") + 1 - name;
case 38:
- return stpcpy (name, "fstat") - name;
+ return stpcpy (name, "fstat") + 1 - name;
case 39:
- return stpcpy (name, "mxcsr") - name;
+ return stpcpy (name, "mxcsr") + 1 - name;
case 40 ... 45:
name[0] = "ecsdfg"[regno - 40];
diff --git a/backends/ia64_init.c b/backends/ia64_init.c
index 42f0634b..490c774a 100644
--- a/backends/ia64_init.c
+++ b/backends/ia64_init.c
@@ -1,5 +1,5 @@
/* Initialization of IA-64 specific backend library.
- 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 <drepper@redhat.com>, 2002.
@@ -55,6 +55,8 @@ 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, return_value_location);
return MODVERSION;
}
diff --git a/backends/ia64_regs.c b/backends/ia64_regs.c
new file mode 100644
index 00000000..bcb456e9
--- /dev/null
+++ b/backends/ia64_regs.c
@@ -0,0 +1,219 @@
+/* Register names and numbers for IA64 DWARF.
+ Copyright (C) 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
+ it under the terms of the GNU General Public License as published by the
+ Free Software Foundation; version 2 of the License.
+
+ Red Hat elfutils 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 Red Hat elfutils; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+ Red Hat elfutils is an included package of the Open Invention Network.
+ An included package of the Open Invention Network is a package for which
+ Open Invention Network licensees cross-license their patents. No patent
+ license is granted, either expressly or impliedly, by designation as an
+ included package. Should you wish to participate in the Open Invention
+ Network licensing program, please visit www.openinventionnetwork.com
+ <http://www.openinventionnetwork.com>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+ssize_t
+ia64_register_name (Ebl *ebl __attribute__ ((unused)),
+ int regno, char *name, size_t namelen,
+ const char **prefix, const char **setname)
+{
+ if (name == NULL)
+ return 687 + 64;
+
+ if (regno < 0 || regno > 687 + 63 || namelen < 12)
+ return -1;
+
+ *prefix = "";
+
+ *setname = "application";
+ switch (regno)
+ {
+ case 0 ... 9:
+ name[0] = 'r';
+ name[1] = (regno - 0) + '0';
+ namelen = 2;
+ *setname = "integer";
+ break;
+
+ case 10 ... 99:
+ name[0] = 'r';
+ name[1] = (regno - 0) / 10 + '0';
+ name[2] = (regno - 0) % 10 + '0';
+ namelen = 3;
+ *setname = "integer";
+ break;
+
+ case 100 ... 127:
+ name[0] = 'r';
+ name[1] = '1';
+ name[2] = (regno - 100) / 10 + '0';
+ name[3] = (regno - 0) % 10 + '0';
+ namelen = 4;
+ *setname = "integer";
+ break;
+
+ case 128 + 0 ... 128 + 9:
+ name[0] = 'f';
+ name[1] = (regno - 128) + '0';
+ namelen = 2;
+ *setname = "FPU";
+ break;
+
+ case 128 + 10 ... 128 + 99:
+ name[0] = 'f';
+ name[1] = (regno - 128) / 10 + '0';
+ name[2] = (regno - 128) % 10 + '0';
+ namelen = 3;
+ *setname = "FPU";
+ break;
+
+ case 128 + 100 ... 128 + 127:
+ name[0] = 'f';
+ name[1] = '1';
+ name[2] = (regno - 128 - 100) / 10 + '0';
+ name[3] = (regno - 128) % 10 + '0';
+ namelen = 4;
+ *setname = "FPU";
+ break;
+
+ case 320 + 0 ... 320 + 7:
+ name[0] = 'b';
+ name[1] = (regno - 320) + '0';
+ namelen = 2;
+ *setname = "branch";
+ break;
+
+ case 328:
+ return stpcpy (name, "vfp") + 1 - name;
+ case 329:
+ return stpcpy (name, "vrap") + 1 - name;
+ case 330:
+ return stpcpy (name, "pr") + 1 - name;
+ case 331:
+ return stpcpy (name, "ip") + 1 - name;
+ case 332:
+ return stpcpy (name, "psr") + 1 - name;
+ case 333:
+ return stpcpy (name, "cfm") + 1 - name;
+
+ case 334 + 0 ... 334 + 7:
+ name[0] = 'k';
+ name[1] = 'r';
+ name[2] = (regno - 334) + '0';
+ namelen = 3;
+ break;
+
+ case 350:
+ return stpcpy (name, "rsc") + 1 - name;
+ case 351:
+ return stpcpy (name, "bsp") + 1 - name;
+ case 352:
+ return stpcpy (name, "bspstore") + 1 - name;
+ case 353:
+ return stpcpy (name, "rnat") + 1 - name;
+ case 355:
+ return stpcpy (name, "fcr") + 1 - name;
+ case 358:
+ return stpcpy (name, "eflag") + 1 - name;
+ case 359:
+ return stpcpy (name, "csd") + 1 - name;
+ case 360:
+ return stpcpy (name, "ssd") + 1 - name;
+ case 361:
+ return stpcpy (name, "cflg") + 1 - name;
+ case 362:
+ return stpcpy (name, "fsr") + 1 - name;
+ case 363:
+ return stpcpy (name, "fir") + 1 - name;
+ case 364:
+ return stpcpy (name, "fdr") + 1 - name;
+ case 366:
+ return stpcpy (name, "ccv") + 1 - name;
+ case 370:
+ return stpcpy (name, "unat") + 1 - name;
+ case 374:
+ return stpcpy (name, "fpsr") + 1 - name;
+ case 378:
+ return stpcpy (name, "itc") + 1 - name;
+ case 398:
+ return stpcpy (name, "pfs") + 1 - name;
+ case 399:
+ return stpcpy (name, "lc") + 1 - name;
+ case 400:
+ return stpcpy (name, "ec") + 1 - name;
+
+ case 462 + 0 ... 462 + 9:
+ name[0] = 'n';
+ name[1] = 'a';
+ name[2] = 't';
+ name[3] = (regno - 462) + '0';
+ namelen = 4;
+ *setname = "NAT";
+ break;
+
+ case 462 + 10 ... 462 + 99:
+ name[0] = 'n';
+ name[1] = 'a';
+ name[2] = 't';
+ name[3] = (regno - 462) / 10 + '0';
+ name[4] = (regno - 462) % 10 + '0';
+ namelen = 5;
+ *setname = "NAT";
+ break;
+
+ case 462 + 100 ... 462 + 127:
+ name[0] = 'n';
+ name[1] = 'a';
+ name[2] = 't';
+ name[3] = (regno - 462 - 100) / 10 + '0';
+ name[4] = (regno - 462) % 10 + '0';
+ namelen = 5;
+ *setname = "NAT";
+ break;
+
+ case 590:
+ return stpcpy (name, "bof") + 1 - name;
+
+ case 687 + 0 ... 687 + 9:
+ name[0] = 'p';
+ name[1] = (regno - 687) + '0';
+ namelen = 2;
+ *setname = "predicate";
+ break;
+
+ case 687 + 10 ... 687 + 63:
+ name[0] = 'p';
+ name[1] = (regno - 687) / 10 + '0';
+ name[2] = (regno - 687) % 10 + '0';
+ namelen = 3;
+ *setname = "predicate";
+ break;
+
+ default:
+ *setname = NULL;
+ return 0;
+ }
+
+ name[namelen++] = '\0';
+ return namelen;
+}
diff --git a/backends/ia64_retval.c b/backends/ia64_retval.c
new file mode 100644
index 00000000..b66fe5c2
--- /dev/null
+++ b/backends/ia64_retval.c
@@ -0,0 +1,223 @@
+/* Function return value location for IA64 ABI.
+ Copyright (C) 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
+ it under the terms of the GNU General Public License as published by the
+ Free Software Foundation; version 2 of the License.
+
+ Red Hat elfutils 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 Red Hat elfutils; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+ Red Hat elfutils is an included package of the Open Invention Network.
+ An included package of the Open Invention Network is a package for which
+ Open Invention Network licensees cross-license their patents. No patent
+ license is granted, either expressly or impliedly, by designation as an
+ included package. Should you wish to participate in the Open Invention
+ Network licensing program, please visit www.openinventionnetwork.com
+ <http://www.openinventionnetwork.com>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND ia64_
+#include "libebl_CPU.h"
+
+
+/* r8, or pair r8, r9, or aggregate up to r8-r11. */
+static const Dwarf_Op loc_intreg[] =
+ {
+ { .atom = DW_OP_reg8 }, { .atom = DW_OP_piece, .number = 8 },
+ { .atom = DW_OP_reg9 }, { .atom = DW_OP_piece, .number = 8 },
+ { .atom = DW_OP_reg10 }, { .atom = DW_OP_piece, .number = 8 },
+ { .atom = DW_OP_reg11 }, { .atom = DW_OP_piece, .number = 8 },
+ };
+#define nloc_intreg 1
+#define nloc_intregs(n) (2 * (n))
+
+/* f8, or aggregate up to f8-f15. */
+#define DEFINE_FPREG(size) \
+ static const Dwarf_Op loc_fpreg_##size[] = \
+ { \
+ { .atom = DW_OP_regx, .number = 128 + 8 }, \
+ { .atom = DW_OP_piece, .number = size }, \
+ { .atom = DW_OP_regx, .number = 128 + 9 }, \
+ { .atom = DW_OP_piece, .number = size }, \
+ { .atom = DW_OP_regx, .number = 128 + 10 }, \
+ { .atom = DW_OP_piece, .number = size }, \
+ { .atom = DW_OP_regx, .number = 128 + 11 }, \
+ { .atom = DW_OP_piece, .number = size }, \
+ { .atom = DW_OP_regx, .number = 128 + 12 }, \
+ { .atom = DW_OP_piece, .number = size }, \
+ { .atom = DW_OP_regx, .number = 128 + 13 }, \
+ { .atom = DW_OP_piece, .number = size }, \
+ { .atom = DW_OP_regx, .number = 128 + 14 }, \
+ { .atom = DW_OP_piece, .number = size }, \
+ { .atom = DW_OP_regx, .number = 128 + 15 }, \
+ { .atom = DW_OP_piece, .number = size }, \
+ }
+#define nloc_fpreg 1
+#define nloc_fpregs(n) (2 * (n))
+
+DEFINE_FPREG (4);
+DEFINE_FPREG (8);
+DEFINE_FPREG (10);
+
+#undef DEFINE_FPREG
+
+
+/* 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 r8. */
+static const Dwarf_Op loc_aggregate[] =
+ {
+ { .atom = DW_OP_breg8, .number = 0 }
+ };
+#define nloc_aggregate 1
+
+
+int
+ia64_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)
+ {
+ if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ size = 8;
+ 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;
+
+ switch (encoding)
+ {
+ case DW_ATE_float:
+ switch (size)
+ {
+ case 4: /* float */
+ *locp = loc_fpreg_4;
+ return nloc_fpreg;
+ case 8: /* double */
+ *locp = loc_fpreg_8;
+ return nloc_fpreg;
+ case 10: /* x86-style long double, not really used */
+ *locp = loc_fpreg_10;
+ return nloc_fpreg;
+ case 16: /* long double, IEEE quad format */
+ *locp = loc_intreg;
+ return nloc_intregs (2);
+ }
+ return -2;
+
+ case DW_ATE_complex_float:
+ switch (size)
+ {
+ case 4 * 2: /* complex float */
+ *locp = loc_fpreg_4;
+ return nloc_fpregs (2);
+ case 8 * 2: /* complex double */
+ *locp = loc_fpreg_8;
+ return nloc_fpregs (2);
+ case 10 * 2: /* complex long double (x86-style) */
+ *locp = loc_fpreg_10;
+ return nloc_fpregs (2);
+ case 16 * 2: /* complex long double (IEEE quad) */
+ *locp = loc_intreg;
+ return nloc_intregs (4);
+ }
+ return -2;
+ }
+ }
+
+ intreg:
+ *locp = loc_intreg;
+ if (size <= 8)
+ return nloc_intreg;
+ if (size <= 32)
+ return nloc_intregs ((size + 7) / 8);
+
+ large:
+ *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)
+ return -1;
+ if (size > 32)
+ goto large;
+
+ /* XXX
+ Must examine the fields in picayune ways to determine the
+ actual answer. If it qualifies as an HFA (all floats)
+ then it should be returned in fp regs.
+ */
+
+ goto intreg;
+ }
+
+ /* 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/ppc_regs.c b/backends/ppc_regs.c
index 3d3d904d..bea8d357 100644
--- a/backends/ppc_regs.c
+++ b/backends/ppc_regs.c
@@ -1,5 +1,5 @@
/* Register names and numbers for PowerPC 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
@@ -83,11 +83,11 @@ ppc_register_name (Ebl *ebl __attribute__ ((unused)),
break;
case 64:
- return stpcpy (name, "cr") - name;
+ return stpcpy (name, "cr") + 1 - name;
case 65:
- return stpcpy (name, "fpscr") - name;
+ return stpcpy (name, "fpscr") + 1 - name;
case 66:
- return stpcpy (name, "msr") - name;
+ return stpcpy (name, "msr") + 1 - name;
case 70 + 0 ... 70 + 9:
name[0] = 's';
diff --git a/backends/s390_regs.c b/backends/s390_regs.c
index 61c60744..28b79898 100644
--- a/backends/s390_regs.c
+++ b/backends/s390_regs.c
@@ -114,9 +114,9 @@ s390_register_name (Ebl *ebl __attribute__ ((unused)),
break;
case 64:
- return stpcpy (name, "pswm") - name;
+ return stpcpy (name, "pswm") + 1 - name;
case 65:
- return stpcpy (name, "pswa") - name;
+ return stpcpy (name, "pswa") + 1 - name;
default:
*setname = NULL;
diff --git a/tests/ChangeLog b/tests/ChangeLog
index cbb4ac7e..070b2f52 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,8 @@
+2006-07-21 Roland McGrath <roland@redhat.com>
+
+ * allregs.c (struct reginfo): Increase size of name.
+ (one_register): Assert that it's big enough.
+
2006-04-04 Roland McGrath <roland@redhat.com>
* run-bug1-test.sh: Test a second case, to cover both byte orders.
diff --git a/tests/allregs.c b/tests/allregs.c
index bad4c85e..baec94ed 100644
--- a/tests/allregs.c
+++ b/tests/allregs.c
@@ -1,4 +1,4 @@
-/* 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
@@ -62,7 +62,7 @@ struct reginfo
{
const char *set, *pfx;
int regno;
- char name[8];
+ char name[32];
};
static int
@@ -103,6 +103,7 @@ one_register (void *arg,
state->info[regno].regno = regno;
state->info[regno].set = setname;
state->info[regno].pfx = prefix;
+ assert (strlen (regname) < sizeof state->info[regno].name);
strcpy (state->info[regno].name, regname);
return DWARF_CB_OK;