]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Update new test after merge.
authorRoland McGrath <roland@redhat.com>
Thu, 17 Nov 2005 03:16:00 +0000 (03:16 +0000)
committerRoland McGrath <roland@redhat.com>
Thu, 17 Nov 2005 03:16:00 +0000 (03:16 +0000)
64 files changed:
ChangeLog
Makefile.am
backends/ChangeLog [new file with mode: 0644]
backends/Makefile.am [new file with mode: 0644]
backends/alpha_init.c [moved from libebl/alpha_init.c with 96% similarity]
backends/alpha_reloc.def [moved from libebl/alpha_reloc.def with 100% similarity]
backends/alpha_retval.c [new file with mode: 0644]
backends/alpha_symbol.c [moved from libebl/alpha_symbol.c with 100% similarity]
backends/arm_init.c [moved from libebl/arm_init.c with 100% similarity]
backends/arm_reloc.def [moved from libebl/arm_reloc.def with 100% similarity]
backends/arm_symbol.c [moved from libebl/arm_symbol.c with 100% similarity]
backends/common-reloc.c [moved from libebl/common-reloc.c with 100% similarity]
backends/i386_corenote.c [moved from libebl/i386_corenote.c with 100% similarity]
backends/i386_init.c [moved from libebl/i386_init.c with 96% similarity]
backends/i386_reloc.def [moved from libebl/i386_reloc.def with 100% similarity]
backends/i386_retval.c [new file with mode: 0644]
backends/i386_symbol.c [moved from libebl/i386_symbol.c with 100% similarity]
backends/ia64_init.c [moved from libebl/ia64_init.c with 100% similarity]
backends/ia64_reloc.def [moved from libebl/ia64_reloc.def with 100% similarity]
backends/ia64_symbol.c [moved from libebl/ia64_symbol.c with 100% similarity]
backends/libebl_CPU.h [moved from libebl/libebl_CPU.h with 100% similarity]
backends/ppc64_init.c [moved from libebl/ppc64_init.c with 96% similarity]
backends/ppc64_reloc.def [moved from libebl/ppc64_reloc.def with 100% similarity]
backends/ppc64_retval.c [new file with mode: 0644]
backends/ppc64_symbol.c [moved from libebl/ppc64_symbol.c with 100% similarity]
backends/ppc_init.c [moved from libebl/ppc_init.c with 96% similarity]
backends/ppc_reloc.def [moved from libebl/ppc_reloc.def with 100% similarity]
backends/ppc_retval.c [new file with mode: 0644]
backends/ppc_symbol.c [moved from libebl/ppc_symbol.c with 100% similarity]
backends/s390_init.c [moved from libebl/s390_init.c with 100% similarity]
backends/s390_reloc.def [moved from libebl/s390_reloc.def with 100% similarity]
backends/s390_symbol.c [moved from libebl/s390_symbol.c with 100% similarity]
backends/sh_init.c [moved from libebl/sh_init.c with 100% similarity]
backends/sh_reloc.def [moved from libebl/sh_reloc.def with 100% similarity]
backends/sh_symbol.c [moved from libebl/sh_symbol.c with 100% similarity]
backends/sparc_init.c [moved from libebl/sparc_init.c with 100% similarity]
backends/sparc_reloc.def [moved from libebl/sparc_reloc.def with 100% similarity]
backends/sparc_symbol.c [moved from libebl/sparc_symbol.c with 100% similarity]
backends/x86_64_corenote.c [moved from libebl/x86_64_corenote.c with 100% similarity]
backends/x86_64_init.c [moved from libebl/x86_64_init.c with 95% similarity]
backends/x86_64_reloc.def [moved from libebl/x86_64_reloc.def with 100% similarity]
backends/x86_64_retval.c [new file with mode: 0644]
backends/x86_64_symbol.c [moved from libebl/x86_64_symbol.c with 100% similarity]
configure.ac
libasm/ChangeLog
libasm/Makefile.am
libdw/ChangeLog
libdw/Makefile.am
libdw/libdw.map
libdwfl/ChangeLog
libdwfl/Makefile.am
libdwfl/dwfl_module_return_value_location.c [new file with mode: 0644]
libdwfl/libdwfl.h
libdwfl/libdwflP.h
libebl/ChangeLog
libebl/Makefile.am
libebl/ebl-hooks.h
libebl/eblopenbackend.c
libebl/eblretval.c [new file with mode: 0644]
libebl/libebl.h
tests/ChangeLog
tests/Makefile.am
tests/coverage.sh
tests/funcretval.c [new file with mode: 0644]

index ae80f975e471eb2d619cecf5f942722d39d6b35c..92384a2db2a1b87e454820f323ee07aa2c921320 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
index ef24c4169660350698fad0757b17cba78bba853b..e7e93cdf673a5a4584cee297fc8c5cc40dbda8f5 100644 (file)
@@ -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 (file)
index 0000000..3715690
--- /dev/null
@@ -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 (file)
index 0000000..eed9bad
--- /dev/null
@@ -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))
similarity index 96%
rename from libebl/alpha_init.c
rename to backends/alpha_init.c
index 1ef87d634102004115e7f14e1fc388c302fbd69a..76a9bfb31a2f7baf8f1630c398f9d6261163983b 100644 (file)
@@ -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/backends/alpha_retval.c b/backends/alpha_retval.c
new file mode 100644 (file)
index 0000000..e130151
--- /dev/null
@@ -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;
+}
similarity index 100%
rename from libebl/arm_init.c
rename to backends/arm_init.c
similarity index 100%
rename from libebl/arm_reloc.def
rename to backends/arm_reloc.def
similarity index 100%
rename from libebl/arm_symbol.c
rename to backends/arm_symbol.c
similarity index 96%
rename from libebl/i386_init.c
rename to backends/i386_init.c
index 477243f3b3c5bb1d4cc13e0ef4ee4c3b12c619ce..a1056e73b2607daa956f512d07f25b3743fd4e59 100644 (file)
@@ -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/backends/i386_retval.c b/backends/i386_retval.c
new file mode 100644 (file)
index 0000000..34cae06
--- /dev/null
@@ -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;
+}
similarity index 100%
rename from libebl/i386_symbol.c
rename to backends/i386_symbol.c
similarity index 100%
rename from libebl/ia64_init.c
rename to backends/ia64_init.c
similarity index 100%
rename from libebl/ia64_symbol.c
rename to backends/ia64_symbol.c
similarity index 100%
rename from libebl/libebl_CPU.h
rename to backends/libebl_CPU.h
similarity index 96%
rename from libebl/ppc64_init.c
rename to backends/ppc64_init.c
index c8a93546b49ca9c6bb5189ac977b4cbff051ad25..9024eafae8ec86a2a47d66157ad0aaf996b0363e 100644 (file)
@@ -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/backends/ppc64_retval.c b/backends/ppc64_retval.c
new file mode 100644 (file)
index 0000000..8185291
--- /dev/null
@@ -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;
+}
similarity index 96%
rename from libebl/ppc_init.c
rename to backends/ppc_init.c
index 375b79edc433a98dcc4f2f629a9569c261fa959c..36ca7a240550c03e1e2771ed9ef7adfeefcdc6cd 100644 (file)
@@ -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;
 }
similarity index 100%
rename from libebl/ppc_reloc.def
rename to backends/ppc_reloc.def
diff --git a/backends/ppc_retval.c b/backends/ppc_retval.c
new file mode 100644 (file)
index 0000000..369c599
--- /dev/null
@@ -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;
+}
similarity index 100%
rename from libebl/ppc_symbol.c
rename to backends/ppc_symbol.c
similarity index 100%
rename from libebl/s390_init.c
rename to backends/s390_init.c
similarity index 100%
rename from libebl/s390_symbol.c
rename to backends/s390_symbol.c
similarity index 100%
rename from libebl/sh_init.c
rename to backends/sh_init.c
similarity index 100%
rename from libebl/sh_reloc.def
rename to backends/sh_reloc.def
similarity index 100%
rename from libebl/sh_symbol.c
rename to backends/sh_symbol.c
similarity index 100%
rename from libebl/sparc_init.c
rename to backends/sparc_init.c
similarity index 95%
rename from libebl/x86_64_init.c
rename to backends/x86_64_init.c
index e4799725d3ec9f60d00b9448bb743898701133da..22147a1f04378444ef9803bb3ca80ac5ca0a2a83 100644 (file)
@@ -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/backends/x86_64_retval.c b/backends/x86_64_retval.c
new file mode 100644 (file)
index 0000000..210d539
--- /dev/null
@@ -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;
+}
index 53e33ea2ef12fe0664686e1afc672046ba125983..2d6f2b6ae18f745f558c5faa60db3d61c477e2c9 100644 (file)
@@ -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])
 
index e25e197b5832d02272764335ebad94900d8b1d96..56d2961eed333e51f645e51fc3ca9d8581bd328c 100644 (file)
@@ -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.
index e9b993975a838645fbae8ea3f08b6420444d74a4..03c4ce040e5a59f0fd53ae01a80746ceec1fa5f7 100644 (file)
@@ -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
index 0c8539efde0f8ca5da25ce23a5a9425ac25d5589..4ccaf95afde00ebd42129a4eb9ff44f019b034fb 100644 (file)
@@ -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;
index 6e53312e10bf9de36c879fb7ac61af59308d2458..daa807cdfc89e4f8a9ef1d9cc542ea9ef6128867 100644 (file)
@@ -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
index 493df48e78b0716b8627555f2b8705e582b3f95d..15e5d0ae4e0f68f14408a8b25695c34351cf7ee6 100644 (file)
@@ -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;
index 60bd68b3199316c9e7c0b8d7bba60264e0f58de9..0a015e76d2f2c3024b249c45743304b8cab76425 100644 (file)
@@ -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.
index 510e7599fee99d714120178a55fb124148b8c628..b2f4e9d2a8718f770442f7ba9857653b23a20cdb 100644 (file)
@@ -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 (file)
index 0000000..336e8f3
--- /dev/null
@@ -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;
+}
index 64e38d5938fc945d526073c9c38b6ff39b0f28fe..8b069e27b188986e984d27fe17637cb88d4d8e07 100644 (file)
@@ -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 */
index c4f303ed9faa16208b8845be84222d1e10fc1603..6c1bcd8e627f4b869ef76b919bc7950723d5c345 100644 (file)
@@ -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;
index 5c66d56f6fdc1416b355df64dd1dad310745a008..be1706087e51aa48565125e4e40c9ca64856897b 100644 (file)
@@ -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.
 
        * 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.
index 51b97ff29c07d34b5fe20733d6a5a23c686d3f6f..f7c4a95302286e996104a00cb3696f4badbe5002 100644 (file)
@@ -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
index 1056c42bf463020eb4815575ab231b4fc478a5c4..90a66c18b0e4a29fdd65523b4c6efeb74b0e3f36 100644 (file)
@@ -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 *);
index 9afbc88b91b146e3dd5de655280f9587c672d519..092cb97abd7cf3bd707fb42135d9ce19a8898f72 100644 (file)
@@ -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 (file)
index 0000000..d23d980
--- /dev/null
@@ -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);
+}
index 1f9a5a257c0d9404c582af381f22d94d002b518a..7e91b308589c4af7961fbdac262f6a1568f8ba77 100644 (file)
@@ -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;
index e74b639c9d06fc491aaa76f05d9bbb933b6b8dd4..956955c521af1fea66287facf8db851d52925f97 100644 (file)
        * 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.
        * 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.
index 98e6f035344e910f2cdb237efce7b988488cefe7..8cc732844f0e386e49a808ba7bfebe153cbcf495 100644 (file)
@@ -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
index f09f644ff26d2d09a2cfc2406014a62a52d50b1c..288ee990989cb9efa086985729d8d741db539326 100755 (executable)
@@ -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 (file)
index 0000000..66e04f6
--- /dev/null
@@ -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;
+}