]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
backends/
authorRoland McGrath <roland@redhat.com>
Fri, 21 Jul 2006 10:06:31 +0000 (10:06 +0000)
committerRoland McGrath <roland@redhat.com>
Fri, 21 Jul 2006 10:06:31 +0000 (10:06 +0000)
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.

backends/ChangeLog
backends/Makefile.am
backends/i386_regs.c
backends/ia64_init.c
backends/ia64_regs.c [new file with mode: 0644]
backends/ia64_retval.c [new file with mode: 0644]
backends/ppc_regs.c
backends/s390_regs.c
tests/ChangeLog
tests/allregs.c

index e741633278f62db475b272d687d03eba5390788d..949f837561e7c3317b2a61b114af0c959bc94e95 100644 (file)
@@ -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.
index 13a809de354d42846cf20df98d9d87116fa16c51..95143bcbd94d8d74052f753b81b5a9ffccfeae6d 100644 (file)
@@ -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)
 
index c2c214234ccba5c01669b21b67c280b71e656603..248700b6c83bf5e61c897a82c0fee109efaaa72e 100644 (file)
@@ -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];
index 42f0634b15e8ba39ab0bc0f716e7385758a838b0..490c774a8df4fc5d1db3cbd350f3e643143e7faa 100644 (file)
@@ -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 (file)
index 0000000..bcb456e
--- /dev/null
@@ -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 (file)
index 0000000..b66fe5c
--- /dev/null
@@ -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;
+}
index 3d3d904d768c7c8b0b6324cce4aaa18004bafd5c..bea8d3577a02382eba5aeff58a32b98f7586deab 100644 (file)
@@ -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';
index 61c60744bd5e2f9de48d35ace98af76ceac5ab1c..28b798988d285adda96bc3af0a508599528c3ca6 100644 (file)
@@ -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;
index cbb4ac7e21d50d11ac391f7acd7235b646fc967f..070b2f52b3c1e8b1ef7af82e8ede6e721a0355ab 100644 (file)
@@ -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.
index bad4c85ef053aad7d8cb8595491b296462f3609e..baec94edc8b752fc41056ebca1592fc994928073 100644 (file)
@@ -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;