diff options
author | Roland McGrath <roland@redhat.com> | 2005-11-17 03:16:00 +0000 |
---|---|---|
committer | Roland McGrath <roland@redhat.com> | 2005-11-17 03:16:00 +0000 |
commit | e47ab76f02c2a4f4d802ec298969ba67956435fe (patch) | |
tree | 39dccb25273f15a488632c952738909f860c4b71 | |
parent | d7f8d0caa7a357f9f4765e5dc93255f5057eba2e (diff) | |
download | elfutils-e47ab76f02c2a4f4d802ec298969ba67956435fe.tar.gz |
Update new test after merge.
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | backends/ChangeLog | 3 | ||||
-rw-r--r-- | backends/Makefile.am | 130 | ||||
-rw-r--r-- | backends/alpha_init.c (renamed from libebl/alpha_init.c) | 1 | ||||
-rw-r--r-- | backends/alpha_reloc.def (renamed from libebl/alpha_reloc.def) | 0 | ||||
-rw-r--r-- | backends/alpha_retval.c | 148 | ||||
-rw-r--r-- | backends/alpha_symbol.c (renamed from libebl/alpha_symbol.c) | 0 | ||||
-rw-r--r-- | backends/arm_init.c (renamed from libebl/arm_init.c) | 0 | ||||
-rw-r--r-- | backends/arm_reloc.def (renamed from libebl/arm_reloc.def) | 0 | ||||
-rw-r--r-- | backends/arm_symbol.c (renamed from libebl/arm_symbol.c) | 0 | ||||
-rw-r--r-- | backends/common-reloc.c (renamed from libebl/common-reloc.c) | 0 | ||||
-rw-r--r-- | backends/i386_corenote.c (renamed from libebl/i386_corenote.c) | 0 | ||||
-rw-r--r-- | backends/i386_init.c (renamed from libebl/i386_init.c) | 1 | ||||
-rw-r--r-- | backends/i386_reloc.def (renamed from libebl/i386_reloc.def) | 0 | ||||
-rw-r--r-- | backends/i386_retval.c | 139 | ||||
-rw-r--r-- | backends/i386_symbol.c (renamed from libebl/i386_symbol.c) | 0 | ||||
-rw-r--r-- | backends/ia64_init.c (renamed from libebl/ia64_init.c) | 0 | ||||
-rw-r--r-- | backends/ia64_reloc.def (renamed from libebl/ia64_reloc.def) | 0 | ||||
-rw-r--r-- | backends/ia64_symbol.c (renamed from libebl/ia64_symbol.c) | 0 | ||||
-rw-r--r-- | backends/libebl_CPU.h (renamed from libebl/libebl_CPU.h) | 0 | ||||
-rw-r--r-- | backends/ppc64_init.c (renamed from libebl/ppc64_init.c) | 1 | ||||
-rw-r--r-- | backends/ppc64_reloc.def (renamed from libebl/ppc64_reloc.def) | 0 | ||||
-rw-r--r-- | backends/ppc64_retval.c | 168 | ||||
-rw-r--r-- | backends/ppc64_symbol.c (renamed from libebl/ppc64_symbol.c) | 0 | ||||
-rw-r--r-- | backends/ppc_init.c (renamed from libebl/ppc_init.c) | 1 | ||||
-rw-r--r-- | backends/ppc_reloc.def (renamed from libebl/ppc_reloc.def) | 0 | ||||
-rw-r--r-- | backends/ppc_retval.c | 141 | ||||
-rw-r--r-- | backends/ppc_symbol.c (renamed from libebl/ppc_symbol.c) | 0 | ||||
-rw-r--r-- | backends/s390_init.c (renamed from libebl/s390_init.c) | 0 | ||||
-rw-r--r-- | backends/s390_reloc.def (renamed from libebl/s390_reloc.def) | 0 | ||||
-rw-r--r-- | backends/s390_symbol.c (renamed from libebl/s390_symbol.c) | 0 | ||||
-rw-r--r-- | backends/sh_init.c (renamed from libebl/sh_init.c) | 0 | ||||
-rw-r--r-- | backends/sh_reloc.def (renamed from libebl/sh_reloc.def) | 0 | ||||
-rw-r--r-- | backends/sh_symbol.c (renamed from libebl/sh_symbol.c) | 0 | ||||
-rw-r--r-- | backends/sparc_init.c (renamed from libebl/sparc_init.c) | 0 | ||||
-rw-r--r-- | backends/sparc_reloc.def (renamed from libebl/sparc_reloc.def) | 0 | ||||
-rw-r--r-- | backends/sparc_symbol.c (renamed from libebl/sparc_symbol.c) | 0 | ||||
-rw-r--r-- | backends/x86_64_corenote.c (renamed from libebl/x86_64_corenote.c) | 0 | ||||
-rw-r--r-- | backends/x86_64_init.c (renamed from libebl/x86_64_init.c) | 1 | ||||
-rw-r--r-- | backends/x86_64_reloc.def (renamed from libebl/x86_64_reloc.def) | 0 | ||||
-rw-r--r-- | backends/x86_64_retval.c | 189 | ||||
-rw-r--r-- | backends/x86_64_symbol.c (renamed from libebl/x86_64_symbol.c) | 0 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | libasm/ChangeLog | 4 | ||||
-rw-r--r-- | libasm/Makefile.am | 3 | ||||
-rw-r--r-- | libdw/ChangeLog | 8 | ||||
-rw-r--r-- | libdw/Makefile.am | 3 | ||||
-rw-r--r-- | libdw/libdw.map | 3 | ||||
-rw-r--r-- | libdwfl/ChangeLog | 13 | ||||
-rw-r--r-- | libdwfl/Makefile.am | 3 | ||||
-rw-r--r-- | libdwfl/dwfl_module_return_value_location.c | 49 | ||||
-rw-r--r-- | libdwfl/libdwfl.h | 15 | ||||
-rw-r--r-- | libdwfl/libdwflP.h | 3 | ||||
-rw-r--r-- | libebl/ChangeLog | 78 | ||||
-rw-r--r-- | libebl/Makefile.am | 93 | ||||
-rw-r--r-- | libebl/ebl-hooks.h | 5 | ||||
-rw-r--r-- | libebl/eblopenbackend.c | 10 | ||||
-rw-r--r-- | libebl/eblretval.c | 29 | ||||
-rw-r--r-- | libebl/libebl.h | 14 | ||||
-rw-r--r-- | tests/ChangeLog | 14 | ||||
-rw-r--r-- | tests/Makefile.am | 10 | ||||
-rwxr-xr-x | tests/coverage.sh | 2 | ||||
-rw-r--r-- | tests/funcretval.c | 100 |
64 files changed, 1291 insertions, 99 deletions
@@ -5,6 +5,9 @@ 2005-11-15 Roland McGrath <roland@redhat.com> + * Makefile.am (all_SUBDIRS): Add backends. + * configure.ac: Write backends/Makefile. + * configure.ac: Add --enable-tests-rpath option. 2005-09-16 Roland McGrath <roland@redhat.com> diff --git a/Makefile.am b/Makefile.am index ef24c416..e7e93cdf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,7 +20,7 @@ ACLOCAL_AMFLAGS = -I m4 mini_SUBDIRS = config m4 lib libelf libelf-po # Add doc back when we have some real content. -all_SUBDIRS = libebl libdwfl libdw libcpu libasm src po tests +all_SUBDIRS = libebl libdwfl libdw libcpu libasm backends src po tests SUBDIRS = $(mini_SUBDIRS) $(all_SUBDIRS) EXTRA_DIST = elfutils.spec GPG-KEY NOTES COPYING.GPL diff --git a/backends/ChangeLog b/backends/ChangeLog new file mode 100644 index 00000000..3715690d --- /dev/null +++ b/backends/ChangeLog @@ -0,0 +1,3 @@ +2005-11-15 Roland McGrath <roland@redhat.com> + + * Contents moved here from ../libebl. diff --git a/backends/Makefile.am b/backends/Makefile.am new file mode 100644 index 00000000..eed9badd --- /dev/null +++ b/backends/Makefile.am @@ -0,0 +1,130 @@ +## Process this file with automake to create Makefile.in +## +## Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 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. +## +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DOBJDIR=\"$(shell pwd)\" +if MUDFLAP +AM_CFLAGS = -fmudflap +else +AM_CFLAGS = +endif +AM_CFLAGS += -fpic -Wall -Wshadow -Werror -Wunused -Wextra -Wformat=2 \ + -std=gnu99 +INCLUDES = -I$(srcdir) -I$(top_srcdir)/libebl \ + -I$(top_srcdir)/libelf -I$(top_srcdir)/libdw \ + -I$(top_srcdir)/lib -I.. +PACKAGE_VERSION = @PACKAGE_VERSION@ + + +modules = i386 sh x86_64 ia64 alpha arm sparc ppc ppc64 s390 +libebl_pic = libebl_i386_pic.a libebl_sh_pic.a libebl_x86_64_pic.a \ + libebl_ia64_pic.a libebl_alpha_pic.a libebl_arm_pic.a \ + libebl_sparc_pic.a libebl_ppc_pic.a libebl_ppc64_pic.a \ + libebl_s390_pic.a +noinst_LIBRARIES = $(libebl_pic) +noinst_DATA = $(libebl_pic:_pic.a=.so) + + +if MUDFLAP +libelf = ../libelf/libelf.a +libdw = ../libdw/libdw.a +libmudflap = -lmudflap +else +libelf = ../libelf/libelf.so +libdw = ../libdw/libdw.so +libmudflap = +endif + + +textrel_check = if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi + +libebl_%.so: libebl_%_pic.a libebl_%.map $(libelf) $(libdw) + $(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ + -Wl,--version-script,$(word 2,$^) \ + -Wl,-z,defs -Wl,--as-needed $(libelf) $(libdw) $(libmudflap) + $(textrel_check) + +libebl_%.map: Makefile + echo 'ELFUTILS_$(PACKAGE_VERSION) { global: $*_init; local: *; };' > $@ + + +i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_retval.c +libebl_i386_pic_a_SOURCES = $(i386_SRCS) +am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os) + +sh_SRCS = sh_init.c sh_symbol.c +libebl_sh_pic_a_SOURCES = $(sh_SRCS) +am_libebl_sh_pic_a_OBJECTS = $(sh_SRCS:.c=.os) + +x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c x86_64_retval.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 +libebl_ia64_pic_a_SOURCES = $(ia64_SRCS) +am_libebl_ia64_pic_a_OBJECTS = $(ia64_SRCS:.c=.os) + +alpha_SRCS = alpha_init.c alpha_symbol.c alpha_retval.c +libebl_alpha_pic_a_SOURCES = $(alpha_SRCS) +am_libebl_alpha_pic_a_OBJECTS = $(alpha_SRCS:.c=.os) + +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 +libebl_sparc_pic_a_SOURCES = $(sparc_SRCS) +am_libebl_sparc_pic_a_OBJECTS = $(sparc_SRCS:.c=.os) + +ppc_SRCS = ppc_init.c ppc_symbol.c ppc_retval.c +libebl_ppc_pic_a_SOURCES = $(ppc_SRCS) +am_libebl_ppc_pic_a_OBJECTS = $(ppc_SRCS:.c=.os) + +ppc64_SRCS = ppc64_init.c ppc64_symbol.c ppc64_retval.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 +libebl_s390_pic_a_SOURCES = $(s390_SRCS) +am_libebl_s390_pic_a_OBJECTS = $(s390_SRCS:.c=.os) + + +%.os: %.c %.o + if $(COMPILE) -c -o $@ -fpic -DPIC -DSHARED -MT $@ -MD -MP \ + -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ + then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ + rm -f "$(DEPDIR)/$*.Tpo"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ + fi + +install: install-am install-ebl-modules +install-ebl-modules: + $(mkinstalldirs) $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR) + for m in $(modules); do \ + $(INSTALL_PROGRAM) libebl_$${m}.so $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}-$(PACKAGE_VERSION).so; \ + ln -fs libebl_$${m}-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}.so; \ + done + +uninstall: uninstall-am + for m in $(modules); do \ + rm -f $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}-$(PACKAGE_VERSION).so; \ + rm -f $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}.so; \ + done + rmdir --ignore-fail-on-non-empty $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR) + rmdir --ignore-fail-on-non-empty $(DESTDIR)$(pkgincludedir) + +noinst_HEADERS = libebl_CPU.h common-reloc.c +EXTRA_DIST = $(foreach m,$(modules),$($(m)_SRCS)) $(modules:=_reloc.def) + +CLEANFILES = *.gcno *.gcda \ + $(foreach m,$(modules),$(am_libebl_$(m)_pic_a_OBJECTS)) diff --git a/libebl/alpha_init.c b/backends/alpha_init.c index 1ef87d63..76a9bfb3 100644 --- a/libebl/alpha_init.c +++ b/backends/alpha_init.c @@ -41,6 +41,7 @@ alpha_init (elf, machine, eh, ehlen) eh->dynamic_tag_name = alpha_dynamic_tag_name; eh->dynamic_tag_check = alpha_dynamic_tag_check; eh->reloc_simple_type = alpha_reloc_simple_type; + eh->return_value_location = alpha_return_value_location; return MODVERSION; } diff --git a/libebl/alpha_reloc.def b/backends/alpha_reloc.def index 488f448c..488f448c 100644 --- a/libebl/alpha_reloc.def +++ b/backends/alpha_reloc.def diff --git a/backends/alpha_retval.c b/backends/alpha_retval.c new file mode 100644 index 00000000..e1301515 --- /dev/null +++ b/backends/alpha_retval.c @@ -0,0 +1,148 @@ +/* Function return value location for Alpha ELF ABI. + Copyright (C) 2005 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 alpha_ +#include "libebl_CPU.h" + + +/* $0. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg0 } + }; +#define nloc_intreg 1 + +/* $f0, or pair $f0, $f1. */ +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 }, + }; +#define nloc_fpreg 1 +#define nloc_fpregpair 4 + +/* 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 $0. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_breg0, .number = 0 } + }; +#define nloc_aggregate 1 + +int +alpha_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); + } + + 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_Word size; + 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; + + *locp = loc_fpreg; + if (encoding == DW_ATE_float) + { + if (size <= 8) + return nloc_fpreg; + goto aggregate; + } + if (encoding == DW_ATE_complex_float) + { + if (size <= 8 * 2) + return nloc_fpregpair; + goto aggregate; + } + } + if (size <= 8) + { + *locp = loc_intreg; + return nloc_intreg; + } + } + + /* Else fall through. */ + + case DW_TAG_structure_type: + case DW_TAG_class_type: + case DW_TAG_union_type: + case DW_TAG_string_type: + case DW_TAG_array_type: + aggregate: + *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/libebl/alpha_symbol.c b/backends/alpha_symbol.c index b2e4cf77..b2e4cf77 100644 --- a/libebl/alpha_symbol.c +++ b/backends/alpha_symbol.c diff --git a/libebl/arm_init.c b/backends/arm_init.c index ee739078..ee739078 100644 --- a/libebl/arm_init.c +++ b/backends/arm_init.c diff --git a/libebl/arm_reloc.def b/backends/arm_reloc.def index b76be778..b76be778 100644 --- a/libebl/arm_reloc.def +++ b/backends/arm_reloc.def diff --git a/libebl/arm_symbol.c b/backends/arm_symbol.c index 6eb40fc5..6eb40fc5 100644 --- a/libebl/arm_symbol.c +++ b/backends/arm_symbol.c diff --git a/libebl/common-reloc.c b/backends/common-reloc.c index 0575e131..0575e131 100644 --- a/libebl/common-reloc.c +++ b/backends/common-reloc.c diff --git a/libebl/i386_corenote.c b/backends/i386_corenote.c index 20750a9d..20750a9d 100644 --- a/libebl/i386_corenote.c +++ b/backends/i386_corenote.c diff --git a/libebl/i386_init.c b/backends/i386_init.c index 477243f3..a1056e73 100644 --- a/libebl/i386_init.c +++ b/backends/i386_init.c @@ -42,6 +42,7 @@ i386_init (elf, machine, eh, ehlen) eh->core_note = i386_core_note; generic_debugscn_p = eh->debugscn_p; eh->debugscn_p = i386_debugscn_p; + eh->return_value_location = i386_return_value_location; return MODVERSION; } diff --git a/libebl/i386_reloc.def b/backends/i386_reloc.def index ba750d0d..ba750d0d 100644 --- a/libebl/i386_reloc.def +++ b/backends/i386_reloc.def diff --git a/backends/i386_retval.c b/backends/i386_retval.c new file mode 100644 index 00000000..34cae064 --- /dev/null +++ b/backends/i386_retval.c @@ -0,0 +1,139 @@ +/* Function return value location for Linux/i386 ABI. + Copyright (C) 2005 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 i386_ +#include "libebl_CPU.h" + + +/* %eax, or pair %eax, %edx. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg1 }, { .atom = DW_OP_piece, .number = 4 }, + }; +#define nloc_intreg 1 +#define nloc_intregpair 4 + +/* %st(0). */ +static const Dwarf_Op loc_fpreg[] = + { + { .atom = DW_OP_reg11 } + }; +#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 %eax. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_breg0, .number = 0 } + }; +#define nloc_aggregate 1 + +int +i386_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); + } + + 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_Word size; + 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 = 4; + 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) + { + if (size > 16) + return -2; + *locp = loc_fpreg; + return nloc_fpreg; + } + } + *locp = loc_intreg; + if (size <= 4) + return nloc_intreg; + if (size <= 8) + return nloc_intregpair; + + /* Else 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/libebl/i386_symbol.c b/backends/i386_symbol.c index dadcc107..dadcc107 100644 --- a/libebl/i386_symbol.c +++ b/backends/i386_symbol.c diff --git a/libebl/ia64_init.c b/backends/ia64_init.c index 1431f2de..1431f2de 100644 --- a/libebl/ia64_init.c +++ b/backends/ia64_init.c diff --git a/libebl/ia64_reloc.def b/backends/ia64_reloc.def index a0d42155..a0d42155 100644 --- a/libebl/ia64_reloc.def +++ b/backends/ia64_reloc.def diff --git a/libebl/ia64_symbol.c b/backends/ia64_symbol.c index 1b500873..1b500873 100644 --- a/libebl/ia64_symbol.c +++ b/backends/ia64_symbol.c diff --git a/libebl/libebl_CPU.h b/backends/libebl_CPU.h index 607c1543..607c1543 100644 --- a/libebl/libebl_CPU.h +++ b/backends/libebl_CPU.h diff --git a/libebl/ppc64_init.c b/backends/ppc64_init.c index c8a93546..9024eafa 100644 --- a/libebl/ppc64_init.c +++ b/backends/ppc64_init.c @@ -44,6 +44,7 @@ ppc64_init (elf, machine, eh, ehlen) eh->copy_reloc_p = ppc64_copy_reloc_p; eh->check_special_symbol = ppc64_check_special_symbol; eh->bss_plt_p = ppc64_bss_plt_p; + eh->return_value_location = ppc64_return_value_location; return MODVERSION; } diff --git a/libebl/ppc64_reloc.def b/backends/ppc64_reloc.def index d0cb2f91..d0cb2f91 100644 --- a/libebl/ppc64_reloc.def +++ b/backends/ppc64_reloc.def diff --git a/backends/ppc64_retval.c b/backends/ppc64_retval.c new file mode 100644 index 00000000..81852915 --- /dev/null +++ b/backends/ppc64_retval.c @@ -0,0 +1,168 @@ +/* Function return value location for Linux/PPC64 ABI. + Copyright (C) 2005 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 ppc64_ +#include "libebl_CPU.h" + + +/* r3. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg3 } + }; +#define nloc_intreg 1 + +/* f1, or f1:f2, or f1:f4. */ +static const Dwarf_Op loc_fpreg[] = + { + { .atom = DW_OP_regx, .number = 33 }, { .atom = DW_OP_piece, .number = 8 }, + { .atom = DW_OP_regx, .number = 34 }, { .atom = DW_OP_piece, .number = 8 }, + { .atom = DW_OP_regx, .number = 35 }, { .atom = DW_OP_piece, .number = 8 }, + { .atom = DW_OP_regx, .number = 36 }, { .atom = DW_OP_piece, .number = 8 }, + }; +#define nloc_fpreg 1 +#define nloc_fp2regs 4 +#define nloc_fp4regs 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 r3. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_breg3, .number = 0 } + }; +#define nloc_aggregate 1 + +int +ppc64_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; + + if (encoding == DW_ATE_float || encoding == DW_ATE_complex_float) + { + *locp = loc_fpreg; + if (size <= 8) + return nloc_fpreg; + if (size <= 16) + return nloc_fp2regs; + if (size <= 32) + return nloc_fp4regs; + } + } + if (size <= 8) + { + intreg: + *locp = loc_intreg; + return nloc_intreg; + } + + /* Else fall through. */ + case DW_TAG_structure_type: + case DW_TAG_class_type: + case DW_TAG_union_type: + aggregate: + *locp = loc_aggregate; + return nloc_aggregate; + + case DW_TAG_string_type: + case DW_TAG_array_type: + if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size, + &attr_mem), &size) == 0 + && size <= 8) + { + if (tag == DW_TAG_array_type) + { + /* Check if it's a character array. */ + attr = dwarf_attr (typedie, DW_AT_type, &attr_mem); + typedie = dwarf_formref_die (attr, &die_mem); + tag = dwarf_tag (typedie); + if (tag != DW_TAG_base_type) + goto aggregate; + if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size, + &attr_mem), &size) != 0) + return -1; + if (size != 1) + goto aggregate; + } + 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/libebl/ppc64_symbol.c b/backends/ppc64_symbol.c index db486176..db486176 100644 --- a/libebl/ppc64_symbol.c +++ b/backends/ppc64_symbol.c diff --git a/libebl/ppc_init.c b/backends/ppc_init.c index 375b79ed..36ca7a24 100644 --- a/libebl/ppc_init.c +++ b/backends/ppc_init.c @@ -43,6 +43,7 @@ ppc_init (elf, machine, eh, ehlen) eh->dynamic_tag_check = ppc_dynamic_tag_check; eh->check_special_symbol = ppc_check_special_symbol; eh->bss_plt_p = ppc_bss_plt_p; + eh->return_value_location = ppc_return_value_location; return MODVERSION; } diff --git a/libebl/ppc_reloc.def b/backends/ppc_reloc.def index 97187381..97187381 100644 --- a/libebl/ppc_reloc.def +++ b/backends/ppc_reloc.def diff --git a/backends/ppc_retval.c b/backends/ppc_retval.c new file mode 100644 index 00000000..369c5997 --- /dev/null +++ b/backends/ppc_retval.c @@ -0,0 +1,141 @@ +/* Function return value location for Linux/PPC ABI. + Copyright (C) 2005 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 ppc_ +#include "libebl_CPU.h" + + +/* r3, or pair r3, r4. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg4 }, { .atom = DW_OP_piece, .number = 4 }, + }; +#define nloc_intreg 1 +#define nloc_intregpair 4 + +/* f1. */ +static const Dwarf_Op loc_fpreg[] = + { + { .atom = DW_OP_regx, .number = 33 } + }; +#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 r3. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_breg3, .number = 0 } + }; +#define nloc_aggregate 1 + +int +ppc_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 = 4; + else + return -1; + } + if (size <= 8) + { + 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; + return nloc_fpreg; + } + } + 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/libebl/ppc_symbol.c b/backends/ppc_symbol.c index f161d70e..f161d70e 100644 --- a/libebl/ppc_symbol.c +++ b/backends/ppc_symbol.c diff --git a/libebl/s390_init.c b/backends/s390_init.c index 14578660..14578660 100644 --- a/libebl/s390_init.c +++ b/backends/s390_init.c diff --git a/libebl/s390_reloc.def b/backends/s390_reloc.def index bee67b33..bee67b33 100644 --- a/libebl/s390_reloc.def +++ b/backends/s390_reloc.def diff --git a/libebl/s390_symbol.c b/backends/s390_symbol.c index ddfefbb2..ddfefbb2 100644 --- a/libebl/s390_symbol.c +++ b/backends/s390_symbol.c diff --git a/libebl/sh_init.c b/backends/sh_init.c index 4fadd9b4..4fadd9b4 100644 --- a/libebl/sh_init.c +++ b/backends/sh_init.c diff --git a/libebl/sh_reloc.def b/backends/sh_reloc.def index 56db1071..56db1071 100644 --- a/libebl/sh_reloc.def +++ b/backends/sh_reloc.def diff --git a/libebl/sh_symbol.c b/backends/sh_symbol.c index 3209d34e..3209d34e 100644 --- a/libebl/sh_symbol.c +++ b/backends/sh_symbol.c diff --git a/libebl/sparc_init.c b/backends/sparc_init.c index 541df842..541df842 100644 --- a/libebl/sparc_init.c +++ b/backends/sparc_init.c diff --git a/libebl/sparc_reloc.def b/backends/sparc_reloc.def index 91fcad74..91fcad74 100644 --- a/libebl/sparc_reloc.def +++ b/backends/sparc_reloc.def diff --git a/libebl/sparc_symbol.c b/backends/sparc_symbol.c index c83e5d3a..c83e5d3a 100644 --- a/libebl/sparc_symbol.c +++ b/backends/sparc_symbol.c diff --git a/libebl/x86_64_corenote.c b/backends/x86_64_corenote.c index 2fd775b6..2fd775b6 100644 --- a/libebl/x86_64_corenote.c +++ b/backends/x86_64_corenote.c diff --git a/libebl/x86_64_init.c b/backends/x86_64_init.c index e4799725..22147a1f 100644 --- a/libebl/x86_64_init.c +++ b/backends/x86_64_init.c @@ -41,6 +41,7 @@ x86_64_init (elf, machine, eh, ehlen) x86_64_init_reloc (eh); eh->reloc_simple_type = x86_64_reloc_simple_type; eh->core_note = x86_64_core_note; + eh->return_value_location = x86_64_return_value_location; return MODVERSION; } diff --git a/libebl/x86_64_reloc.def b/backends/x86_64_reloc.def index 83a18280..83a18280 100644 --- a/libebl/x86_64_reloc.def +++ b/backends/x86_64_reloc.def diff --git a/backends/x86_64_retval.c b/backends/x86_64_retval.c new file mode 100644 index 00000000..210d5392 --- /dev/null +++ b/backends/x86_64_retval.c @@ -0,0 +1,189 @@ +/* Function return value location for Linux/x86-64 ABI. + Copyright (C) 2005 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 x86_64_ +#include "libebl_CPU.h" + + +/* %rax, or pair %rax, %rdx. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 8 }, + { .atom = DW_OP_reg1 }, { .atom = DW_OP_piece, .number = 8 }, + }; +#define nloc_intreg 1 +#define nloc_intregpair 4 + +/* %st(0), or pair %st(0), %st(1). */ +static const Dwarf_Op loc_x87reg[] = + { + { .atom = DW_OP_regx, .number = 33 }, + { .atom = DW_OP_piece, .number = 10 }, + { .atom = DW_OP_regx, .number = 34 }, + { .atom = DW_OP_piece, .number = 10 }, + }; +#define nloc_x87reg 1 +#define nloc_x87regpair 4 + +/* %xmm0, or pair %xmm0, %xmm1. */ +static const Dwarf_Op loc_ssereg[] = + { + { .atom = DW_OP_reg17 }, { .atom = DW_OP_piece, .number = 16 }, + { .atom = DW_OP_reg18 }, { .atom = DW_OP_piece, .number = 16 }, + }; +#define nloc_ssereg 1 +#define nloc_sseregpair 4 + +/* 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 %rax. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_breg0, .number = 0 } + }; +#define nloc_aggregate 1 + + +int +x86_64_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_complex_float: + switch (size) + { + case 4 * 2: /* complex float */ + case 8 * 2: /* complex double */ + *locp = loc_ssereg; + return nloc_sseregpair; + case 16 * 2: /* complex long double */ + *locp = loc_x87reg; + return nloc_x87regpair; + } + return -2; + + case DW_ATE_float: + switch (size) + { + case 4: /* float */ + case 8: /* double */ + *locp = loc_ssereg; + return nloc_ssereg; + case 16: /* long double */ + /* XXX distinguish __float128, which is sseregpair?? */ + *locp = loc_x87reg; + return nloc_x87reg; + } + return -2; + } + } + + intreg: + *locp = loc_intreg; + if (size <= 8) + return nloc_intreg; + if (size <= 16) + return nloc_intregpair; + + 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 > 16) + goto large; + + /* XXX + Must examine the fields in picayune ways to determine the + actual answer. This will be right for small C structs + containing integer types and similarly simple cases. + */ + + 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/libebl/x86_64_symbol.c b/backends/x86_64_symbol.c index c48af103..c48af103 100644 --- a/libebl/x86_64_symbol.c +++ b/backends/x86_64_symbol.c diff --git a/configure.ac b/configure.ac index 53e33ea2..2d6f2b6a 100644 --- a/configure.ac +++ b/configure.ac @@ -194,6 +194,9 @@ dnl Assembler library. AM_CONDITIONAL(HAVE_LIBASM, true)dnl Used in tests/Makefile.am, which see. AC_CONFIG_FILES([libasm/Makefile]) +dnl CPU-specific backend libraries. +AC_CONFIG_FILES([backends/Makefile]) + dnl Tools. AC_CONFIG_FILES([src/Makefile po/Makefile.in]) diff --git a/libasm/ChangeLog b/libasm/ChangeLog index e25e197b..56d2961e 100644 --- a/libasm/ChangeLog +++ b/libasm/ChangeLog @@ -1,3 +1,7 @@ +2005-11-13 Roland McGrath <roland@redhat.com> + + * Makefile.am (INCLUDES): Search in libdw. + 2005-09-02 Ulrich Drepper <drepper@redhat.com> * asm_error.c (asm_errmsg): Unify error message. diff --git a/libasm/Makefile.am b/libasm/Makefile.am index e9b99397..03c4ce04 100644 --- a/libasm/Makefile.am +++ b/libasm/Makefile.am @@ -19,7 +19,8 @@ else AM_CFLAGS = endif AM_CFLAGS += -std=gnu99 -Wall -Wshadow -Werror -Wunused -Wextra -Wformat=2 -INCLUDES = -I. -I$(srcdir) -I.. -I$(top_srcdir)/libelf -I$(top_srcdir)/libebl \ +INCLUDES = -I. -I$(srcdir) -I.. \ + -I$(top_srcdir)/libelf -I$(top_srcdir)/libebl -I$(top_srcdir)/libdw\ -I$(top_srcdir)/lib GCC_INCLUDE = -I$(shell $(CC) -print-file-name=include) VERSION = 1 diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 0c8539ef..4ccaf95a 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,11 @@ +2005-11-15 Roland McGrath <roland@redhat.com> + + * Makefile.am [BUILD_STATIC] (AM_CFLAGS): Add -fpic. + +2005-11-13 Roland McGrath <roland@redhat.com> + + * libdw.map: Bump to 0.117; export dwfl_module_return_value_location. + 2005-10-27 Roland McGrath <roland@redhat.com> * dwarf_entry_breakpoints.c (search_range): Fix binary search code; diff --git a/libdw/Makefile.am b/libdw/Makefile.am index 6e53312e..daa807cd 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -18,6 +18,9 @@ AM_CFLAGS = -fmudflap else AM_CFLAGS = endif +if BUILD_STATIC +AM_CFLAGS += -fpic +endif AM_CFLAGS += -Wall -Werror -Wshadow -Wunused -Wformat=2 -Wextra -std=gnu99 INCLUDES = -I. -I$(srcdir) -I$(srcdir)/../libelf -I.. -I$(srcdir)/../lib VERSION = 1 diff --git a/libdw/libdw.map b/libdw/libdw.map index 493df48e..15e5d0ae 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -1,5 +1,5 @@ ELFUTILS_0 { }; -ELFUTILS_0.116 { +ELFUTILS_0.117 { global: dwarf_abbrevhaschildren; dwarf_addrdie; @@ -124,6 +124,7 @@ ELFUTILS_0.116 { dwfl_module_relocate_address; dwfl_module_relocation_info; dwfl_module_relocations; + dwfl_module_return_value_location; dwfl_nextcu; dwfl_offline_section_address; dwfl_onesrcline; diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 60bd68b3..0a015e76 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,16 @@ +2005-11-15 Roland McGrath <roland@redhat.com> + + * libdwfl.h: Comment fixes. + + * dwfl_module_return_value_location.c: Add unlikely for error case. + +2005-11-13 Roland McGrath <roland@redhat.com> + + * dwfl_return_value_location.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + * libdwfl.h: Declare dwfl_module_return_value_location. + * libdwflP.h (DWFL_ERRORS): Add DWFL_E_WEIRD_TYPE. + 2005-10-20 Roland McGrath <roland@redhat.com> * libdwflP.h (DWFL_ERRORS): New error UNKNOWN_MACHINE. diff --git a/libdwfl/Makefile.am b/libdwfl/Makefile.am index 510e7599..b2f4e9d2 100644 --- a/libdwfl/Makefile.am +++ b/libdwfl/Makefile.am @@ -52,7 +52,8 @@ libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c \ dwfl_module_getsrc.c dwfl_getsrc.c \ dwfl_module_getsrc_file.c \ libdwfl_crc32.c libdwfl_crc32_file.c \ - elf-from-memory.c + elf-from-memory.c \ + dwfl_module_return_value_location.c if MUDFLAP diff --git a/libdwfl/dwfl_module_return_value_location.c b/libdwfl/dwfl_module_return_value_location.c new file mode 100644 index 00000000..336e8f39 --- /dev/null +++ b/libdwfl/dwfl_module_return_value_location.c @@ -0,0 +1,49 @@ +/* Return location expression to find return value given a function type DIE. + Copyright (C) 2005 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. */ + +#include "libdwflP.h" + + +int +dwfl_module_return_value_location (mod, functypedie, locops) + Dwfl_Module *mod; + Dwarf_Die *functypedie; + const Dwarf_Op **locops; +{ + if (mod == NULL) + return -1; + + if (mod->ebl == NULL) + { + mod->ebl = ebl_openbackend (mod->main.elf); + if (mod->ebl == NULL) + { + __libdwfl_seterrno (DWFL_E_LIBEBL); + return -1; + } + } + + int nops = ebl_return_value_location (mod->ebl, functypedie, locops); + if (unlikely (nops < 0)) + { + if (nops == -1) + __libdwfl_seterrno (DWFL_E_LIBDW); + else if (nops == -2) + __libdwfl_seterrno (DWFL_E_WEIRD_TYPE); + else + __libdwfl_seterrno (DWFL_E_LIBEBL); + nops = -1; + } + + return nops; +} diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h index 64e38d59..8b069e27 100644 --- a/libdwfl/libdwfl.h +++ b/libdwfl/libdwfl.h @@ -328,8 +328,21 @@ extern const char *dwfl_lineinfo (Dwfl_Line *line, Dwarf_Addr *addr, /* Find the symbol that ADDRESS lies inside, and return its name. */ -const char *dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr address); +extern const char *dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr address); +/* Return location expression to find return value given a + DW_TAG_subprogram, DW_TAG_subroutine_type, or similar DIE describing + function itself (whose DW_AT_type attribute describes its return type). + The given DIE must come from the given module. Returns -1 for errors. + Returns zero if the function has no return value (e.g. "void" in C). + Otherwise, *LOCOPS gets a location expression to find the return value, + and returns the number of operations in the expression. The pointer is + permanently allocated at least as long as the module is live. */ +extern int dwfl_module_return_value_location (Dwfl_Module *mod, + Dwarf_Die *functypedie, + const Dwarf_Op **locops); + + #endif /* libdwfl.h */ diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index c4f303ed..6c1bcd8e 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -52,7 +52,8 @@ DWFL_ERROR (ADDR_OUTOFRANGE, N_("address out of range")) \ DWFL_ERROR (NO_MATCH, N_("no matching address range")) \ DWFL_ERROR (TRUNCATED, N_("image truncated")) \ - DWFL_ERROR (BADELF, N_("not a valid ELF file")) + DWFL_ERROR (BADELF, N_("not a valid ELF file")) \ + DWFL_ERROR (WEIRD_TYPE, N_("cannot handle DWARF type description")) #define DWFL_ERROR(name, text) DWFL_E_##name, typedef enum { DWFL_ERRORS DWFL_E_NUM } Dwfl_Error; diff --git a/libebl/ChangeLog b/libebl/ChangeLog index 5c66d56f..be170608 100644 --- a/libebl/ChangeLog +++ b/libebl/ChangeLog @@ -2,6 +2,64 @@ * libebl.h: Use "" for elf-knowledge.h, not <>. +2005-11-15 Roland McGrath <roland@redhat.com> + + * Makefile.am: Removed everything for building libebl_*.so modules, + now in ../backends/Makefile.am instead. + * alpha_init.c: Moved to ../backends. + * alpha_reloc.def: Likewise. + * alpha_retval.c: Likewise. + * alpha_symbol.c: Likewise. + * arm_init.c: Likewise. + * arm_reloc.def: Likewise. + * arm_symbol.c: Likewise. + * common-reloc.c: Likewise. + * i386_corenote.c: Likewise. + * i386_init.c: Likewise. + * i386_reloc.def: Likewise. + * i386_retval.c: Likewise. + * i386_symbol.c: Likewise. + * ia64_init.c: Likewise. + * ia64_reloc.def: Likewise. + * ia64_symbol.c: Likewise. + * libebl_CPU.h: Likewise. + * ppc64_init.c: Likewise. + * ppc64_reloc.def: Likewise. + * ppc64_retval.c: Likewise. + * ppc64_symbol.c: Likewise. + * ppc_init.c: Likewise. + * ppc_reloc.def: Likewise. + * ppc_retval.c: Likewise. + * ppc_symbol.c: Likewise. + * s390_init.c: Likewise. + * s390_reloc.def: Likewise. + * s390_symbol.c: Likewise. + * sh_init.c: Likewise. + * sh_reloc.def: Likewise. + * sh_symbol.c: Likewise. + * sparc_init.c: Likewise. + * sparc_reloc.def: Likewise. + * sparc_symbol.c: Likewise. + * x86_64_corenote.c: Likewise. + * x86_64_init.c: Likewise. + * x86_64_reloc.def: Likewise. + * x86_64_retval.c: Likewise. + * x86_64_symbol.c: Likewise. + + * libebl.h: Comment fixes. + + * alpha_retval.c: New file. + * Makefile.am (alpha_SRCS): Add it. + * alpha_init.c (alpha_init): Initialize return_value_location hook. + + * ppc64_retval.c: New file. + * Makefile.am (ppc64_SRCS): Add it. + * ppc64_init.c (ppc64_init): Initialize return_value_location hook. + + * ppc_retval.c: New file. + * Makefile.am (ppc_SRCS): Add it. + * ppc_init.c (ppc_init): Initialize return_value_location hook. + 2005-11-14 Roland McGrath <roland@redhat.com> * ia64_init.c (ia64_init): Initialize EH->reloc_simple_type. @@ -23,6 +81,26 @@ * alpha_reloc.def: Update bits per Richard Henderson <rth@redhat.com>. +2005-11-13 Roland McGrath <roland@redhat.com> + + * x86_64_retval.c: New file. + * Makefile.am (x86_64_SRCS): Add it. + * x86_64_init.c (x86_64_init): Use x86_64_return_value_location. + + * i386_retval.c: New file. + * Makefile.am (i386_SRCS): Add it. + (libdw): New variable. + (libebl_%.so): Use $(libdw) in link; use --as-needed. + * i386_init.c (i386_init): Use i386_return_value_location. + + * eblretval.c: New file. + * Makefile.am (gen_SOURCES): Add it. + (INCLUDES): Search in libdw. + * libebl.h: Include <libdw.h>. Declare ebl_return_value_location. + * ebl-hooks.h: Declare return_value_location hook. + * eblopenbackend.c (default_return_value_location): New function. + (fill_defaults): Use it. + 2005-11-10 Roland McGrath <roland@redhat.com> * s390_init.c: New file. diff --git a/libebl/Makefile.am b/libebl/Makefile.am index 51b97ff2..f7c4a953 100644 --- a/libebl/Makefile.am +++ b/libebl/Makefile.am @@ -21,19 +21,13 @@ endif AM_CFLAGS += -fpic -Wall -Wshadow -Werror -Wunused -Wextra -Wformat=2 \ -std=gnu99 -INCLUDES = -I$(srcdir) -I$(top_srcdir)/libelf -I$(top_srcdir)/lib -I.. +INCLUDES = -I$(srcdir) -I$(top_srcdir)/libelf -I$(top_srcdir)/libdw \ + -I$(top_srcdir)/lib -I.. VERSION = 1 PACKAGE_VERSION = @PACKAGE_VERSION@ LIBEBL_SUBDIR = @LIBEBL_SUBDIR@ lib_LIBRARIES = libebl.a -modules = i386 sh x86_64 ia64 alpha arm sparc ppc ppc64 s390 -libebl_pic = libebl_i386_pic.a libebl_sh_pic.a libebl_x86_64_pic.a \ - libebl_ia64_pic.a libebl_alpha_pic.a libebl_arm_pic.a \ - libebl_sparc_pic.a libebl_ppc_pic.a libebl_ppc64_pic.a \ - libebl_s390_pic.a -noinst_LIBRARIES = $(libebl_pic) -noinst_DATA = $(libebl_pic:_pic.a=.so) pkginclude_HEADERS = libebl.h @@ -49,69 +43,10 @@ gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \ eblcorenote.c eblobjnote.c ebldebugscnp.c \ eblgotpcreloccheck.c eblcopyrelocp.c eblsectionstripp.c \ eblelfclass.c eblelfdata.c eblelfmachine.c \ - ebl_check_special_symbol.c eblbsspltp.c + ebl_check_special_symbol.c eblbsspltp.c eblretval.c libebl_a_SOURCES = $(gen_SOURCES) -i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c -libebl_i386_pic_a_SOURCES = $(i386_SRCS) -am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os) - -if MUDFLAP -libelf = ../libelf/libelf.a -libmudflap = -lmudflap -else -libelf = ../libelf/libelf.so -libmudflap = -endif - -textrel_check = if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi - -libebl_%.so: libebl_%_pic.a libebl_%.map - $(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ - -Wl,--version-script,$(word 2,$^) \ - -Wl,-z,defs $(libelf) $(libmudflap) - $(textrel_check) - -libebl_%.map: Makefile - echo 'ELFUTILS_$(PACKAGE_VERSION) { global: $*_init; local: *; };' > $@ - -sh_SRCS = sh_init.c sh_symbol.c -libebl_sh_pic_a_SOURCES = $(sh_SRCS) -am_libebl_sh_pic_a_OBJECTS = $(sh_SRCS:.c=.os) - -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 -libebl_ia64_pic_a_SOURCES = $(ia64_SRCS) -am_libebl_ia64_pic_a_OBJECTS = $(ia64_SRCS:.c=.os) - -alpha_SRCS = alpha_init.c alpha_symbol.c -libebl_alpha_pic_a_SOURCES = $(alpha_SRCS) -am_libebl_alpha_pic_a_OBJECTS = $(alpha_SRCS:.c=.os) - -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 -libebl_sparc_pic_a_SOURCES = $(sparc_SRCS) -am_libebl_sparc_pic_a_OBJECTS = $(sparc_SRCS:.c=.os) - -ppc_SRCS = ppc_init.c ppc_symbol.c -libebl_ppc_pic_a_SOURCES = $(ppc_SRCS) -am_libebl_ppc_pic_a_OBJECTS = $(ppc_SRCS:.c=.os) - -ppc64_SRCS = ppc64_init.c ppc64_symbol.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 -libebl_s390_pic_a_SOURCES = $(s390_SRCS) -am_libebl_s390_pic_a_OBJECTS = $(s390_SRCS:.c=.os) - %.os: %.c %.o if $(COMPILE) -c -o $@ -fpic -DPIC -DSHARED -MT $@ -MD -MP \ @@ -121,24 +56,6 @@ am_libebl_s390_pic_a_OBJECTS = $(s390_SRCS:.c=.os) else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ fi -install: install-am install-ebl-modules -install-ebl-modules: - $(mkinstalldirs) $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR) - for m in $(modules); do \ - $(INSTALL_PROGRAM) libebl_$${m}.so $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}-$(PACKAGE_VERSION).so; \ - ln -fs libebl_$${m}-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}.so; \ - done - -uninstall: uninstall-am - for m in $(modules); do \ - rm -f $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}-$(PACKAGE_VERSION).so; \ - rm -f $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}.so; \ - done - rmdir --ignore-fail-on-non-empty $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR) - rmdir --ignore-fail-on-non-empty $(DESTDIR)$(pkgincludedir) - -noinst_HEADERS = libeblP.h ebl-hooks.h libebl_CPU.h common-reloc.c -EXTRA_DIST = $(foreach m,$(modules),$($(m)_SRCS)) $(modules:=_reloc.def) +noinst_HEADERS = libeblP.h ebl-hooks.h -CLEANFILES = $(am_libebl_pic_a_OBJECTS) *.gcno *.gcda \ - $(foreach m,$(modules),$(am_libebl_$(m)_pic_a_OBJECTS)) +CLEANFILES = $(am_libebl_pic_a_OBJECTS) *.gcno *.gcda diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h index 1056c42b..90a66c18 100644 --- a/libebl/ebl-hooks.h +++ b/libebl/ebl-hooks.h @@ -87,5 +87,10 @@ bool EBLHOOK(check_special_symbol) (Elf *, GElf_Ehdr *, const GElf_Sym *, /* Check if backend uses a bss PLT in this file. */ bool EBLHOOK(bss_plt_p) (Elf *, GElf_Ehdr *); +/* Return location expression to find return value given the + DW_AT_type DIE of a DW_TAG_subprogram DIE. */ +int EBLHOOK(return_value_location) (Dwarf_Die *functypedie, + const Dwarf_Op **locp); + /* Destructor for ELF backend handle. */ void EBLHOOK(destr) (struct ebl *); diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c index 9afbc88b..092cb97a 100644 --- a/libebl/eblopenbackend.c +++ b/libebl/eblopenbackend.c @@ -158,6 +158,8 @@ static bool default_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const char *name, const GElf_Shdr *destshdr); static bool default_bss_plt_p (Elf *elf, GElf_Ehdr *ehdr); +static int default_return_value_location (Dwarf_Die *functypedie, + const Dwarf_Op **locops); static void @@ -188,6 +190,7 @@ fill_defaults (Ebl *result) result->copy_reloc_p = default_copy_reloc_p; result->check_special_symbol = default_check_special_symbol; result->bss_plt_p = default_bss_plt_p; + result->return_value_location = default_return_value_location; result->destr = default_destr; } @@ -577,3 +580,10 @@ default_bss_plt_p (Elf *elf __attribute__ ((unused)), { return false; } + +static int +default_return_value_location (Dwarf_Die *functypedie __attribute__ ((unused)), + const Dwarf_Op **locops __attribute__ ((unused))) +{ + return -2; +} diff --git a/libebl/eblretval.c b/libebl/eblretval.c new file mode 100644 index 00000000..d23d9805 --- /dev/null +++ b/libebl/eblretval.c @@ -0,0 +1,29 @@ +/* Return location expression to find return value given a function type DIE. + Copyright (C) 2005 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 <inttypes.h> +#include <libeblP.h> + + +int +ebl_return_value_location (ebl, functypedie, locops) + Ebl *ebl; + Dwarf_Die *functypedie; + const Dwarf_Op **locops; +{ + return ebl == NULL ? -1 : ebl->return_value_location (functypedie, locops); +} diff --git a/libebl/libebl.h b/libebl/libebl.h index 1f9a5a25..7e91b308 100644 --- a/libebl/libebl.h +++ b/libebl/libebl.h @@ -15,6 +15,7 @@ #define _LIBEBL_H 1 #include <gelf.h> +#include "libdw.h" #include <stdbool.h> #include <stddef.h> #include <stdint.h> @@ -156,6 +157,19 @@ extern bool ebl_section_strip_p (Ebl *ebl, const GElf_Ehdr *ehdr, /* Check if backend uses a bss PLT in this file. */ extern bool ebl_bss_plt_p (Ebl *ebl, GElf_Ehdr *ehdr); +/* Return location expression to find return value given a + DW_TAG_subprogram, DW_TAG_subroutine_type, or similar DIE describing + function itself (whose DW_AT_type attribute describes its return type). + Returns -1 for a libdw error (see dwarf_errno). + Returns -2 for an unrecognized type formation. + Returns zero if the function has no return value (e.g. "void" in C). + Otherwise, *LOCOPS gets a location expression to find the return value, + and returns the number of operations in the expression. The pointer is + permanently allocated at least as long as the Ebl handle is open. */ +extern int ebl_return_value_location (Ebl *ebl, + Dwarf_Die *functypedie, + const Dwarf_Op **locops); + /* ELF string table handling. */ struct Ebl_Strtab; diff --git a/tests/ChangeLog b/tests/ChangeLog index e74b639c..956955c5 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -34,12 +34,20 @@ * show-die-info.c: Likewise. * update3.c: Likewise. * update4.c: Likewise. + * funcretval.c: Likewise. * dwflmodtest.c (print_instance): Don't use INTUSE. (options): Don't use N_ macro. 2005-11-15 Roland McGrath <roland@redhat.com> + * coverage.sh: Look in backends. + * Makefile.am (BUILD_RPATH): Search ../backends, not ../libebl. + (TESTS_ENVIRONMENT): Likewise. + + * funcretval.c (handle_function): Don't take DW_AT_type of FUNCDIE, + pass FUNCDIE direclty to dwfl_module_return_value_location. + * Makefile.am (BUILD_RPATH): New variable. [TESTS_RPATH] (AM_LDFLAGS): Pass -rpath option using that value. (tests_rpath): New variable. @@ -79,6 +87,12 @@ * run-strings-test.sh: Likewise. * run-strip-test.sh: Likewise. +2005-11-13 Roland McGrath <roland@redhat.com> + + * funcretval.c: New file. + * Makefile.am (noinst_PROGRAMS): Add it. + (funcretval_LDADD): New variable. + 2005-11-09 Ulrich Drepper <drepper@redhat.com> * line2addr.c (handle_module): Add missing parameter to printf. diff --git a/tests/Makefile.am b/tests/Makefile.am index 98e6f035..8cc73284 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -16,11 +16,11 @@ DEFS = -DHAVE_CONFIG_H -D_GNU_SOURCE if MUDFLAP AM_CFLAGS = -Wall -Werror -Wextra -std=gnu99 -fmudflap\ $(if $($(*F)_no_Wformat),-Wno-format,-Wformat=2) -BUILD_RPATH = \$$ORIGIN/../libebl +BUILD_RPATH = \$$ORIGIN/../backends else AM_CFLAGS = -Wall -Werror -Wextra -std=gnu99 \ $(if $($(*F)_no_Wformat),-Wno-format,-Wformat=2) -BUILT_RPATH = \$$ORIGIN/../libasm:\$$ORIGIN/../libdw:\$$ORIGIN/../libebl:\$$ORIGIN/../libelf +BUILT_RPATH = \$$ORIGIN/../libasm:\$$ORIGIN/../libdw:\$$ORIGIN/../backends:\$$ORIGIN/../libelf endif if !STANDALONE @@ -41,7 +41,8 @@ noinst_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \ showptable update1 update2 update3 update4 test-nlist \ show-die-info get-files get-lines get-pubnames \ get-aranges allfcts line2addr addrscopes funcscopes \ - show-abbrev hash newscn ecp dwflmodtest find-prologues + show-abbrev hash newscn ecp dwflmodtest \ + find-prologues funcretval # get-ciefde asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \ asm-tst6 asm-tst7 asm-tst8 asm-tst9 @@ -102,7 +103,7 @@ if STANDALONE TESTS_ENVIRONMENT = $(installed_TESTS_ENVIRONMENT) else !STANDALONE TESTS_ENVIRONMENT = $(srcdir)/test-wrapper.sh \ - ../libdw:../libebl:../libelf:../libasm + ../libdw:../backends:../libelf:../libasm installcheck-local: $(MAKE) $(AM_MAKEFLAGS) \ @@ -159,6 +160,7 @@ line2addr_no_Wformat = yes line2addr_LDADD = $(libdw) $(libmudflap) addrscopes_LDADD = $(libdw) $(libmudflap) funcscopes_LDADD = $(libdw) $(libmudflap) +funcretval_LDADD = $(libdw) $(libmudflap) find_prologues_LDADD = $(libdw) $(libmudflap) #show_ciefde_LDADD = ../libdwarf/libdwarf.so $(libelf) $(libmudflap) asm_tst1_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl diff --git a/tests/coverage.sh b/tests/coverage.sh index f09f644f..288ee990 100755 --- a/tests/coverage.sh +++ b/tests/coverage.sh @@ -2,7 +2,7 @@ cd .. -for d in lib libasm libdw libdwfl libebl libelf src; do +for d in lib libasm libdw libdwfl libebl libelf backends src; do tmp=$d-data cd $d unused=0 diff --git a/tests/funcretval.c b/tests/funcretval.c new file mode 100644 index 00000000..66e04f6b --- /dev/null +++ b/tests/funcretval.c @@ -0,0 +1,100 @@ +/* Test program for dwfl_module_return_value_location. + Copyright (C) 2005 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. */ + +#include <config.h> +#include <assert.h> +#include <inttypes.h> +#include ELFUTILS_HEADER(dwfl) +#include <dwarf.h> +#include <argp.h> +#include <stdio.h> +#include <stdio_ext.h> +#include <locale.h> +#include <stdlib.h> +#include <error.h> +#include <string.h> +#include <fnmatch.h> + + +struct args +{ + Dwfl *dwfl; + Dwarf_Die *cu; + Dwarf_Addr dwbias; + char **argv; +}; + +static int +handle_function (Dwarf_Die *funcdie, void *arg) +{ + struct args *a = arg; + + const char *name = dwarf_diename (funcdie); + char **argv = a->argv; + if (argv[0] != NULL) + { + bool match; + do + match = fnmatch (*argv, name, 0) == 0; + while (!match && *++argv); + if (!match) + return 0; + } + + printf ("(%s) %s: ", dwfl_module_info (dwfl_cumodule (a->cu), NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL), name); + + const Dwarf_Op *locops; + int nlocops = dwfl_module_return_value_location (dwfl_cumodule (a->cu), + funcdie, &locops); + if (nlocops < 0) + error (EXIT_FAILURE, 0, "dwfl_module_return_value_location: %s", + dwfl_errmsg (-1)); + else if (nlocops == 0) + puts ("returns no value"); + else + { + printf ("return value location:"); + for (int i = 0; i < nlocops; ++i) + printf (" {%#x, %#" PRIx64 "}", locops[i].atom, locops[i].number); + puts (""); + } + + return 0; +} + + +int +main (int argc, char *argv[]) +{ + int remaining; + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + struct args a = { .dwfl = NULL, .cu = NULL }; + + (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, + &a.dwfl); + assert (a.dwfl != NULL); + a.argv = &argv[remaining]; + + int result = 0; + + while ((a.cu = dwfl_nextcu (a.dwfl, a.cu, &a.dwbias)) != NULL) + dwarf_getfuncs (a.cu, &handle_function, &a, 0); + + return result; +} |