From: Roland McGrath Date: Fri, 13 Jan 2006 00:51:21 +0000 (+0000) Subject: 2006-01-12 Roland McGrath X-Git-Tag: elfutils-0.120~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=321327a975d245ae83d71132b9b8832448aa5400;p=thirdparty%2Felfutils.git 2006-01-12 Roland McGrath * s390_retval.c: New file. * Makefile.am (s390_SRCS): Add it. * s390_init.c (s390_init): Install return_value_location hook. --- diff --git a/backends/ChangeLog b/backends/ChangeLog index c7f82a979..84515e51d 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,9 @@ +2006-01-12 Roland McGrath + + * s390_retval.c: New file. + * Makefile.am (s390_SRCS): Add it. + * s390_init.c (s390_init): Install return_value_location hook. + 2006-01-11 Roland McGrath * s390_regs.c: New file. diff --git a/backends/Makefile.am b/backends/Makefile.am index 7719b6f27..d85d52fc7 100644 --- a/backends/Makefile.am +++ b/backends/Makefile.am @@ -96,7 +96,7 @@ ppc64_SRCS = ppc64_init.c ppc64_symbol.c ppc64_retval.c ppc_regs.c libebl_ppc64_pic_a_SOURCES = $(ppc64_SRCS) am_libebl_ppc64_pic_a_OBJECTS = $(ppc64_SRCS:.c=.os) -s390_SRCS = s390_init.c s390_symbol.c s390_regs.c +s390_SRCS = s390_init.c s390_symbol.c s390_regs.c s390_retval.c libebl_s390_pic_a_SOURCES = $(s390_SRCS) am_libebl_s390_pic_a_OBJECTS = $(s390_SRCS:.c=.os) diff --git a/backends/s390_init.c b/backends/s390_init.c index d39495cf4..c956e82aa 100644 --- a/backends/s390_init.c +++ b/backends/s390_init.c @@ -39,6 +39,7 @@ s390_init (elf, machine, eh, ehlen) s390_init_reloc (eh); HOOK (eh, reloc_simple_type); HOOK (eh, register_name); + HOOK (eh, return_value_location); return MODVERSION; } diff --git a/backends/s390_retval.c b/backends/s390_retval.c new file mode 100644 index 000000000..ca4da9ced --- /dev/null +++ b/backends/s390_retval.c @@ -0,0 +1,142 @@ +/* Function return value location for S/390 ABI. + 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 +#endif + +#include +#include + +#define BACKEND s390_ +#include "libebl_CPU.h" + + +/* %r2, or pair %r2, %r3. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg2 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 4 }, + }; +#define nloc_intreg 1 +#define nloc_intregpair 4 + +/* %f0. */ +static const Dwarf_Op loc_fpreg[] = + { + { .atom = DW_OP_reg16 }, + }; +#define nloc_fpreg 1 + +/* 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 %r2. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_breg2, .number = 0 } + }; +#define nloc_aggregate 1 + + +int +s390_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: + { + Dwarf_Die cudie; + uint8_t asize; + if (dwarf_diecu (typedie, &cudie, &asize, NULL) == NULL) + return -1; + + 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 = 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 && size <= 8) + { + *locp = loc_fpreg; + return nloc_fpreg; + } + } + if (size <= 8) + { + *locp = loc_intreg; + return size <= asize ? nloc_intreg : nloc_intregpair; + } + } + /* Fall through. */ + + case DW_TAG_structure_type: + case DW_TAG_class_type: + case DW_TAG_union_type: + case DW_TAG_array_type: + *locp = loc_aggregate; + return nloc_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/config/elfutils.spec.in b/config/elfutils.spec.in index 2c8245eb2..70bdd79ad 100644 --- a/config/elfutils.spec.in +++ b/config/elfutils.spec.in @@ -185,6 +185,11 @@ rm -rf ${RPM_BUILD_ROOT} %{_libdir}/libelf.so %changelog +* Thu Jan 12 2006 Roland McGrath 0.118-1 +- elflint: more tests. +- libdwfl: New function dwfl_module_register_names. +- libebl: New backend hook for register names. + * Tue Dec 6 2005 Ulrich Drepper 0.118-1 - elflint: more tests. - libdwfl: New function dwfl_module_register_names.