diff options
| author | Roland McGrath <[email protected]> | 2006-10-10 00:25:21 +0000 |
|---|---|---|
| committer | Roland McGrath <[email protected]> | 2006-10-10 00:25:21 +0000 |
| commit | c373d850ec9ca342f4c71d5e287c8d8bf0723cd6 (patch) | |
| tree | c8f9ea814866cdfb30ac9506ccddbc8629ebe345 /backends | |
| parent | 1dee360aa30fecd20f403f98fd1cb9e543afcca7 (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/ChangeLog | 27 | ||||
| -rw-r--r-- | backends/Makefile.am | 2 | ||||
| -rw-r--r-- | backends/i386_init.c | 4 | ||||
| -rw-r--r-- | backends/i386_regs.c | 42 | ||||
| -rw-r--r-- | backends/ia64_init.c | 2 | ||||
| -rw-r--r-- | backends/ia64_regs.c | 28 | ||||
| -rw-r--r-- | backends/ia64_symbol.c | 11 | ||||
| -rw-r--r-- | backends/ppc64_init.c | 4 | ||||
| -rw-r--r-- | backends/ppc_init.c | 4 | ||||
| -rw-r--r-- | backends/ppc_regs.c | 18 | ||||
| -rw-r--r-- | backends/s390_init.c | 2 | ||||
| -rw-r--r-- | backends/s390_regs.c | 25 | ||||
| -rw-r--r-- | backends/sparc_init.c | 5 | ||||
| -rw-r--r-- | backends/sparc_regs.c | 50 | ||||
| -rw-r--r-- | backends/sparc_retval.c | 154 | ||||
| -rw-r--r-- | backends/x86_64_init.c | 4 | ||||
| -rw-r--r-- | backends/x86_64_regs.c | 33 |
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) { |
