summaryrefslogtreecommitdiffstats
path: root/backends
diff options
context:
space:
mode:
authorRoland McGrath <[email protected]>2005-11-17 03:16:00 +0000
committerRoland McGrath <[email protected]>2005-11-17 03:16:00 +0000
commite47ab76f02c2a4f4d802ec298969ba67956435fe (patch)
tree39dccb25273f15a488632c952738909f860c4b71 /backends
parentd7f8d0caa7a357f9f4765e5dc93255f5057eba2e (diff)
Update new test after merge.
Diffstat (limited to 'backends')
-rw-r--r--backends/ChangeLog3
-rw-r--r--backends/Makefile.am130
-rw-r--r--backends/alpha_init.c47
-rw-r--r--backends/alpha_reloc.def48
-rw-r--r--backends/alpha_retval.c148
-rw-r--r--backends/alpha_symbol.c59
-rw-r--r--backends/arm_init.c44
-rw-r--r--backends/arm_reloc.def65
-rw-r--r--backends/arm_symbol.c40
-rw-r--r--backends/common-reloc.c112
-rw-r--r--backends/i386_corenote.c163
-rw-r--r--backends/i386_init.c48
-rw-r--r--backends/i386_reloc.def51
-rw-r--r--backends/i386_retval.c139
-rw-r--r--backends/i386_symbol.c60
-rw-r--r--backends/ia64_init.c48
-rw-r--r--backends/ia64_reloc.def96
-rw-r--r--backends/ia64_symbol.c119
-rw-r--r--backends/libebl_CPU.h34
-rw-r--r--backends/ppc64_init.c50
-rw-r--r--backends/ppc64_reloc.def119
-rw-r--r--backends/ppc64_retval.c168
-rw-r--r--backends/ppc64_symbol.c97
-rw-r--r--backends/ppc_init.c49
-rw-r--r--backends/ppc_reloc.def107
-rw-r--r--backends/ppc_retval.c141
-rw-r--r--backends/ppc_symbol.c143
-rw-r--r--backends/s390_init.c43
-rw-r--r--backends/s390_reloc.def76
-rw-r--r--backends/s390_symbol.c41
-rw-r--r--backends/sh_init.c44
-rw-r--r--backends/sh_reloc.def52
-rw-r--r--backends/sh_symbol.c44
-rw-r--r--backends/sparc_init.c49
-rw-r--r--backends/sparc_reloc.def94
-rw-r--r--backends/sparc_symbol.c45
-rw-r--r--backends/x86_64_corenote.c172
-rw-r--r--backends/x86_64_init.c47
-rw-r--r--backends/x86_64_reloc.def39
-rw-r--r--backends/x86_64_retval.c189
-rw-r--r--backends/x86_64_symbol.c45
41 files changed, 3308 insertions, 0 deletions
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 <[email protected]>
+
+ * 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/backends/alpha_init.c b/backends/alpha_init.c
new file mode 100644
index 00000000..76a9bfb3
--- /dev/null
+++ b/backends/alpha_init.c
@@ -0,0 +1,47 @@
+/* Initialization of Alpha specific backend library.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2002.
+
+ 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
+
+#define BACKEND alpha_
+#define RELOC_PREFIX R_ALPHA_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on alpha_reloc.def. */
+#include "common-reloc.c"
+
+
+const char *
+alpha_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "Alpha";
+ alpha_init_reloc (eh);
+ 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_reloc.def b/backends/alpha_reloc.def
new file mode 100644
index 00000000..488f448c
--- /dev/null
+++ b/backends/alpha_reloc.def
@@ -0,0 +1,48 @@
+/* List the relocation types for alpha. -*- C -*-
+ 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. */
+
+/* NAME, REL|EXEC|DYN */
+
+RELOC_TYPE (NONE, 0)
+RELOC_TYPE (REFLONG, REL|EXEC|DYN)
+RELOC_TYPE (REFQUAD, REL|EXEC|DYN)
+RELOC_TYPE (GPREL32, REL)
+RELOC_TYPE (LITERAL, REL)
+RELOC_TYPE (LITUSE, REL)
+RELOC_TYPE (GPDISP, REL)
+RELOC_TYPE (BRADDR, REL)
+RELOC_TYPE (HINT, REL)
+RELOC_TYPE (SREL16, REL)
+RELOC_TYPE (SREL32, REL)
+RELOC_TYPE (SREL64, REL)
+RELOC_TYPE (GPRELHIGH, REL)
+RELOC_TYPE (GPRELLOW, REL)
+RELOC_TYPE (GPREL16, REL)
+RELOC_TYPE (COPY, 0)
+RELOC_TYPE (GLOB_DAT, EXEC|DYN)
+RELOC_TYPE (JMP_SLOT, EXEC|DYN)
+RELOC_TYPE (RELATIVE, EXEC|DYN)
+RELOC_TYPE (TLS_GD_HI, REL)
+RELOC_TYPE (TLSGD, REL)
+RELOC_TYPE (TLS_LDM, REL)
+RELOC_TYPE (DTPMOD64, REL|EXEC|DYN)
+RELOC_TYPE (GOTDTPREL, REL)
+RELOC_TYPE (DTPREL64, REL|EXEC|DYN)
+RELOC_TYPE (DTPRELHI, REL)
+RELOC_TYPE (DTPRELLO, REL)
+RELOC_TYPE (DTPREL16, REL)
+RELOC_TYPE (GOTTPREL, REL)
+RELOC_TYPE (TPREL64, REL|EXEC|DYN)
+RELOC_TYPE (TPRELHI, REL)
+RELOC_TYPE (TPRELLO, REL)
+RELOC_TYPE (TPREL16, REL)
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/backends/alpha_symbol.c b/backends/alpha_symbol.c
new file mode 100644
index 00000000..b2e4cf77
--- /dev/null
+++ b/backends/alpha_symbol.c
@@ -0,0 +1,59 @@
+/* Alpha specific symbolic name handling.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2002.
+
+ 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 <elf.h>
+#include <stddef.h>
+
+#define BACKEND alpha_
+#include "libebl_CPU.h"
+
+
+const char *
+alpha_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ switch (tag)
+ {
+ case DT_ALPHA_PLTRO:
+ return "ALPHA_PLTRO";
+ default:
+ break;
+ }
+ return NULL;
+}
+
+bool
+alpha_dynamic_tag_check (int64_t tag)
+{
+ return tag == DT_ALPHA_PLTRO;
+}
+
+/* Check for the simple reloc types. */
+Elf_Type
+alpha_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+ switch (type)
+ {
+ case R_ALPHA_REFLONG:
+ return ELF_T_WORD;
+ case R_ALPHA_REFQUAD:
+ return ELF_T_XWORD;
+ default:
+ return ELF_T_NUM;
+ }
+}
diff --git a/backends/arm_init.c b/backends/arm_init.c
new file mode 100644
index 00000000..ee739078
--- /dev/null
+++ b/backends/arm_init.c
@@ -0,0 +1,44 @@
+/* Initialization of Arm specific backend library.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2002.
+
+ 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
+
+#define BACKEND arm_
+#define RELOC_PREFIX R_ARM_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on arm_reloc.def. */
+#include "common-reloc.c"
+
+
+const char *
+arm_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "ARM";
+ arm_init_reloc (eh);
+ eh->reloc_simple_type = arm_reloc_simple_type;
+
+ return MODVERSION;
+}
diff --git a/backends/arm_reloc.def b/backends/arm_reloc.def
new file mode 100644
index 00000000..b76be778
--- /dev/null
+++ b/backends/arm_reloc.def
@@ -0,0 +1,65 @@
+/* List the relocation types for arm. -*- C -*-
+ 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. */
+
+/* NAME, REL|EXEC|DYN */
+
+RELOC_TYPE (NONE, REL) /* It really is used in ET_REL on ARM. */
+RELOC_TYPE (PC24, REL)
+RELOC_TYPE (ABS32, REL)
+RELOC_TYPE (REL32, REL)
+RELOC_TYPE (PC13, REL)
+RELOC_TYPE (ABS16, REL)
+RELOC_TYPE (ABS12, REL)
+RELOC_TYPE (THM_ABS5, REL)
+RELOC_TYPE (ABS8, REL)
+RELOC_TYPE (SBREL32, REL)
+RELOC_TYPE (THM_PC22, REL)
+RELOC_TYPE (THM_PC8, REL)
+RELOC_TYPE (AMP_VCALL9, REL)
+RELOC_TYPE (SWI24, REL)
+RELOC_TYPE (THM_SWI8, REL)
+RELOC_TYPE (XPC25, REL)
+RELOC_TYPE (THM_XPC22, REL)
+RELOC_TYPE (TLS_DTPMOD32, EXEC|DYN)
+RELOC_TYPE (TLS_DTPOFF32, EXEC|DYN)
+RELOC_TYPE (TLS_TPOFF32, EXEC|DYN)
+RELOC_TYPE (COPY, EXEC)
+RELOC_TYPE (GLOB_DAT, EXEC|DYN)
+RELOC_TYPE (JUMP_SLOT, EXEC|DYN)
+RELOC_TYPE (RELATIVE, EXEC|DYN)
+RELOC_TYPE (GOTOFF, REL)
+RELOC_TYPE (GOTPC, REL)
+RELOC_TYPE (GOT32, REL)
+RELOC_TYPE (PLT32, REL)
+RELOC_TYPE (ALU_PCREL_7_0, REL)
+RELOC_TYPE (ALU_PCREL_15_8, REL)
+RELOC_TYPE (ALU_PCREL_23_15, REL)
+RELOC_TYPE (LDR_SBREL_11_0, REL)
+RELOC_TYPE (ALU_SBREL_19_12, REL)
+RELOC_TYPE (ALU_SBREL_27_20, REL)
+RELOC_TYPE (GNU_VTENTRY, REL)
+RELOC_TYPE (GNU_VTINHERIT, REL)
+RELOC_TYPE (THM_PC11, REL)
+RELOC_TYPE (THM_PC9, REL)
+RELOC_TYPE (TLS_GD32, REL)
+RELOC_TYPE (TLS_LDM32, REL)
+RELOC_TYPE (TLS_LDO32, REL)
+RELOC_TYPE (TLS_IE32, REL)
+RELOC_TYPE (TLS_LE32, REL)
+RELOC_TYPE (RXPC25, REL)
+RELOC_TYPE (RSBREL32, REL)
+RELOC_TYPE (THM_RPC22, REL)
+RELOC_TYPE (RREL32, REL)
+RELOC_TYPE (RABS22, REL)
+RELOC_TYPE (RPC24, REL)
+RELOC_TYPE (RBASE, REL)
diff --git a/backends/arm_symbol.c b/backends/arm_symbol.c
new file mode 100644
index 00000000..6eb40fc5
--- /dev/null
+++ b/backends/arm_symbol.c
@@ -0,0 +1,40 @@
+/* Arm specific symbolic name handling.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2002.
+
+ 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 <elf.h>
+#include <stddef.h>
+
+#define BACKEND arm_
+#include "libebl_CPU.h"
+
+/* Check for the simple reloc types. */
+Elf_Type
+arm_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+ switch (type)
+ {
+ case R_ARM_ABS32:
+ return ELF_T_WORD;
+ case R_ARM_ABS16:
+ return ELF_T_HALF;
+ case R_ARM_ABS8:
+ return ELF_T_BYTE;
+ default:
+ return ELF_T_NUM;
+ }
+}
diff --git a/backends/common-reloc.c b/backends/common-reloc.c
new file mode 100644
index 00000000..0575e131
--- /dev/null
+++ b/backends/common-reloc.c
@@ -0,0 +1,112 @@
+/* Common code for ebl reloc functions.
+ 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 "libebl_CPU.h"
+#include <assert.h>
+
+#define R_TYPE(name) PASTE (RELOC_PREFIX, name)
+#define PASTE(a, b) PASTE_1 (a, b)
+#define PASTE_1(a, b) a##b
+#define R_NAME(name) R_NAME_1 (R_TYPE (name))
+#define R_NAME_1(type) #type
+
+#define RELOC_TYPES STRINGIFIED_PASTE (BACKEND, reloc.def)
+#define STRINGIFIED_PASTE(a, b) STRINGIFY (PASTE (a, b))
+#define STRINGIFY(x) STRINGIFY_1 (x)
+#define STRINGIFY_1(x) #x
+
+/* Provide a table of reloc type names, in a PIC-friendly fashion. */
+
+static const struct EBLHOOK(reloc_nametable)
+{
+ char zero;
+#define RELOC_TYPE(type, uses) \
+ char name_##type[sizeof R_NAME (type)];
+#include RELOC_TYPES
+#undef RELOC_TYPE
+} EBLHOOK(reloc_nametable) =
+ {
+ '\0',
+#define RELOC_TYPE(type, uses) R_NAME (type),
+#include RELOC_TYPES
+#undef RELOC_TYPE
+ };
+#define reloc_namestr (&EBLHOOK(reloc_nametable).zero)
+
+static const uint_fast16_t EBLHOOK(reloc_nameidx)[] =
+{
+#define RELOC_TYPE(type, uses) \
+ [R_TYPE (type)] = offsetof (struct EBLHOOK(reloc_nametable), name_##type),
+#include RELOC_TYPES
+#undef RELOC_TYPE
+};
+#define nreloc \
+ ((int) (sizeof EBLHOOK(reloc_nameidx) / sizeof EBLHOOK(reloc_nameidx)[0]))
+
+#define REL (1 << (ET_REL - 1))
+#define EXEC (1 << (ET_EXEC - 1))
+#define DYN (1 << (ET_DYN - 1))
+static const uint8_t EBLHOOK(reloc_valid)[] =
+{
+#define RELOC_TYPE(type, uses) [R_TYPE (type)] = uses,
+#include RELOC_TYPES
+#undef RELOC_TYPE
+};
+#undef REL
+#undef EXEC
+#undef DYN
+
+const char *
+EBLHOOK(reloc_type_name) (int reloc,
+ char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ if (reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0)
+ return &reloc_namestr[EBLHOOK(reloc_nameidx)[reloc]];
+ return NULL;
+}
+
+bool
+EBLHOOK(reloc_type_check) (int reloc)
+{
+ return reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0;
+}
+
+bool
+EBLHOOK(reloc_valid_use) (Elf *elf, int reloc)
+{
+ uint8_t uses = EBLHOOK(reloc_valid)[reloc];
+
+ GElf_Ehdr ehdr_mem;
+ GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+ assert (ehdr != NULL);
+ uint8_t type = ehdr->e_type;
+
+ return type > ET_NONE && type < ET_CORE && (uses & (1 << (type - 1)));
+}
+
+
+bool
+EBLHOOK(copy_reloc_p) (int reloc)
+{
+ return reloc == R_TYPE (COPY);
+}
+
+static void
+EBLHOOK(init_reloc) (Ebl *ebl)
+{
+ ebl->reloc_type_name = EBLHOOK(reloc_type_name);
+ ebl->reloc_type_check = EBLHOOK(reloc_type_check);
+ ebl->reloc_valid_use = EBLHOOK(reloc_valid_use);
+ ebl->copy_reloc_p = EBLHOOK(copy_reloc_p);
+}
diff --git a/backends/i386_corenote.c b/backends/i386_corenote.c
new file mode 100644
index 00000000..20750a9d
--- /dev/null
+++ b/backends/i386_corenote.c
@@ -0,0 +1,163 @@
+/* i386 specific core note handling.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2002.
+
+ 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 <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+
+/* We cannot include <sys/procfs.h> since the definition would be for
+ the host platform and not always x86 as required here. */
+struct elf_prstatus
+ {
+ struct
+ {
+ int32_t si_signo; /* Signal number. */
+ int32_t si_code; /* Extra code. */
+ int32_t si_errno; /* Errno. */
+ } pr_info; /* Info associated with signal. */
+ int16_t pr_cursig; /* Current signal. */
+ uint32_t pr_sigpend; /* Set of pending signals. */
+ uint32_t pr_sighold; /* Set of held signals. */
+ int32_t pr_pid;
+ int32_t pr_ppid;
+ int32_t pr_pgrp;
+ int32_t pr_sid;
+ struct i386_timeval
+ {
+ int32_t tv_sec;
+ int32_t tv_usec;
+ } pr_utime; /* User time. */
+ struct i386_timeval pr_stime; /* System time. */
+ struct i386_timeval pr_cutime; /* Cumulative user time. */
+ struct i386_timeval pr_cstime; /* Cumulative system time. */
+ uint32_t pr_reg[17]; /* GP registers. */
+ int32_t pr_fpvalid; /* True if math copro being used. */
+ };
+
+
+struct elf_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ uint32_t pr_flag; /* Flags. */
+ uint16_t pr_uid;
+ uint16_t pr_gid;
+ int32_t pr_pid;
+ int32_t pr_ppid;
+ int32_t pr_pgrp;
+ int32_t pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[80]; /* Initial part of arg list. */
+ };
+
+
+bool
+i386_core_note (name, type, descsz, desc)
+ const char *name __attribute__ ((unused));
+ uint32_t type;
+ uint32_t descsz;
+ const char *desc;
+{
+ bool result = false;
+
+ switch (type)
+ {
+ case NT_PRSTATUS:
+ if (descsz < sizeof (struct elf_prstatus))
+ /* Not enough data. */
+ break;
+
+ struct elf_prstatus *stat = (struct elf_prstatus *) desc;
+
+ printf (" SIGINFO: signo: %" PRId32 ", code = %" PRId32
+ ", errno = %" PRId32 "\n"
+ " signal: %" PRId16 ", pending: %08" PRIx32
+ ", holding: %8" PRIx32 "\n"
+ " pid: %" PRId32 ", ppid = %" PRId32 ", pgrp = %" PRId32
+ ", sid = %" PRId32 "\n"
+ " utime: %6" PRId32 ".%06" PRId32
+ "s, stime: %6" PRId32 ".%06" PRId32 "s\n"
+ " cutime: %6" PRId32 ".%06" PRId32
+ "s, cstime: %6" PRId32 ".%06" PRId32 "s\n"
+ " eax: %08" PRIx32 " ebx: %08" PRIx32 " ecx: %08" PRIx32
+ " edx: %08" PRIx32 "\n"
+ " esi: %08" PRIx32 " edi: %08" PRIx32 " ebp: %08" PRIx32
+ " esp: %08" PRIx32 "\n"
+ " eip: %08" PRIx32 " eflags: %08" PRIx32
+ " original eax: %08" PRIx32 "\n"
+ " cs: %04" PRIx32 " ds: %04" PRIx32 " es: %04" PRIx32
+ " fs: %04" PRIx32 " gs: %04" PRIx32 " ss: %04" PRIx32 "\n\n",
+ stat->pr_info.si_signo,
+ stat->pr_info.si_code,
+ stat->pr_info.si_errno,
+ stat->pr_cursig,
+ stat->pr_sigpend, stat->pr_sighold,
+ stat->pr_pid, stat->pr_ppid, stat->pr_pgrp, stat->pr_sid,
+ stat->pr_utime.tv_sec, stat->pr_utime.tv_usec,
+ stat->pr_stime.tv_sec, stat->pr_stime.tv_usec,
+ stat->pr_cutime.tv_sec, stat->pr_cutime.tv_usec,
+ stat->pr_cstime.tv_sec, stat->pr_cstime.tv_usec,
+ stat->pr_reg[6], stat->pr_reg[0], stat->pr_reg[1],
+ stat->pr_reg[2], stat->pr_reg[3], stat->pr_reg[4],
+ stat->pr_reg[5], stat->pr_reg[15], stat->pr_reg[12],
+ stat->pr_reg[14], stat->pr_reg[11], stat->pr_reg[13] & 0xffff,
+ stat->pr_reg[7] & 0xffff, stat->pr_reg[8] & 0xffff,
+ stat->pr_reg[9] & 0xffff, stat->pr_reg[10] & 0xffff,
+ stat->pr_reg[16]);
+
+ /* We handled this entry. */
+ result = true;
+ break;
+
+ case NT_PRPSINFO:
+ if (descsz < sizeof (struct elf_prpsinfo))
+ /* Not enough data. */
+ break;
+
+ struct elf_prpsinfo *info = (struct elf_prpsinfo *) desc;
+
+ printf (" state: %c (%hhd), zombie: %hhd, nice: %hhd\n"
+ " flags: %08" PRIx32 ", uid: %" PRId16 ", gid: %" PRId16"\n"
+ " pid: %" PRId32 ", ppid: %" PRId32 ", pgrp: %" PRId32
+ ", sid: %" PRId32 "\n"
+ " fname: %.16s\n"
+ " args: %.80s\n\n",
+ info->pr_sname, info->pr_state, info->pr_zomb, info->pr_nice,
+ info->pr_flag, info->pr_uid, info->pr_gid,
+ info->pr_pid, info->pr_ppid, info->pr_pgrp, info->pr_sid,
+ info->pr_fname, info->pr_psargs);
+
+ /* We handled this entry. */
+ result = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return result;
+}
diff --git a/backends/i386_init.c b/backends/i386_init.c
new file mode 100644
index 00000000..a1056e73
--- /dev/null
+++ b/backends/i386_init.c
@@ -0,0 +1,48 @@
+/* Initialization of i386 specific backend library.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2000.
+
+ 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
+
+#define BACKEND i386_
+#define RELOC_PREFIX R_386_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on i386_reloc.def. */
+#include "common-reloc.c"
+
+const char *
+i386_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "Intel 80386";
+ i386_init_reloc (eh);
+ eh->reloc_simple_type = i386_reloc_simple_type;
+ eh->gotpc_reloc_check = i386_gotpc_reloc_check;
+ 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_reloc.def b/backends/i386_reloc.def
new file mode 100644
index 00000000..ba750d0d
--- /dev/null
+++ b/backends/i386_reloc.def
@@ -0,0 +1,51 @@
+/* List the relocation types for i386. -*- C -*-
+ Copyright (C) 2000, 2001, 2002, 2003, 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. */
+
+/* NAME, REL|EXEC|DYN */
+
+RELOC_TYPE (NONE, 0)
+RELOC_TYPE (COPY, EXEC)
+RELOC_TYPE (32, REL|EXEC|DYN)
+RELOC_TYPE (PC32, REL|EXEC|DYN)
+RELOC_TYPE (GOT32, REL)
+RELOC_TYPE (PLT32, REL)
+RELOC_TYPE (GLOB_DAT, EXEC|DYN)
+RELOC_TYPE (JMP_SLOT, EXEC|DYN)
+RELOC_TYPE (RELATIVE, EXEC|DYN)
+RELOC_TYPE (GOTOFF, REL)
+RELOC_TYPE (GOTPC, REL)
+RELOC_TYPE (32PLT, REL)
+RELOC_TYPE (TLS_TPOFF, EXEC|DYN)
+RELOC_TYPE (TLS_IE, REL)
+RELOC_TYPE (TLS_GOTIE, REL)
+RELOC_TYPE (TLS_LE, REL)
+RELOC_TYPE (TLS_GD, REL)
+RELOC_TYPE (TLS_LDM, REL)
+RELOC_TYPE (16, REL)
+RELOC_TYPE (PC16, REL)
+RELOC_TYPE (8, REL)
+RELOC_TYPE (PC8, REL)
+RELOC_TYPE (TLS_GD_32, REL)
+RELOC_TYPE (TLS_GD_PUSH, REL)
+RELOC_TYPE (TLS_GD_CALL, REL)
+RELOC_TYPE (TLS_GD_POP, REL)
+RELOC_TYPE (TLS_LDM_32, REL)
+RELOC_TYPE (TLS_LDM_PUSH, REL)
+RELOC_TYPE (TLS_LDM_CALL, REL)
+RELOC_TYPE (TLS_LDM_POP, REL)
+RELOC_TYPE (TLS_LDO_32, REL)
+RELOC_TYPE (TLS_IE_32, REL)
+RELOC_TYPE (TLS_LE_32, REL)
+RELOC_TYPE (TLS_DTPMOD32, EXEC|DYN)
+RELOC_TYPE (TLS_DTPOFF32, EXEC|DYN)
+RELOC_TYPE (TLS_TPOFF32, EXEC|DYN)
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/backends/i386_symbol.c b/backends/i386_symbol.c
new file mode 100644
index 00000000..dadcc107
--- /dev/null
+++ b/backends/i386_symbol.c
@@ -0,0 +1,60 @@
+/* i386 specific symbolic name handling.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2000.
+
+ 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 <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+
+/* Return true if the symbol type is that referencing the GOT. */
+bool
+i386_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), int type)
+{
+ return type == R_386_GOTPC;
+}
+
+/* Check for the simple reloc types. */
+Elf_Type
+i386_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+ switch (type)
+ {
+ case R_386_32:
+ return ELF_T_SWORD;
+ case R_386_16:
+ return ELF_T_HALF;
+ case R_386_8:
+ return ELF_T_BYTE;
+ default:
+ return ELF_T_NUM;
+ }
+}
+
+/* Check section name for being that of a debug information section. */
+bool (*generic_debugscn_p) (const char *);
+bool
+i386_debugscn_p (const char *name)
+{
+ return (generic_debugscn_p (name)
+ || strcmp (name, ".stab") == 0
+ || strcmp (name, ".stabstr") == 0);
+}
diff --git a/backends/ia64_init.c b/backends/ia64_init.c
new file mode 100644
index 00000000..1431f2de
--- /dev/null
+++ b/backends/ia64_init.c
@@ -0,0 +1,48 @@
+/* Initialization of IA-64 specific backend library.
+ Copyright (C) 2002, 2003, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2002.
+
+ 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
+
+#define BACKEND ia64_
+#define RELOC_PREFIX R_IA64_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on ia64_reloc.def. */
+#include "common-reloc.c"
+
+const char *
+ia64_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "Intel IA-64";
+ ia64_init_reloc (eh);
+ eh->reloc_simple_type = ia64_reloc_simple_type;
+ eh->segment_type_name = ia64_segment_type_name;
+ eh->section_type_name = ia64_section_type_name;
+ eh->dynamic_tag_name = ia64_dynamic_tag_name;
+ eh->dynamic_tag_check = ia64_dynamic_tag_check;
+ eh->machine_flag_check = ia64_machine_flag_check;
+
+ return MODVERSION;
+}
diff --git a/backends/ia64_reloc.def b/backends/ia64_reloc.def
new file mode 100644
index 00000000..a0d42155
--- /dev/null
+++ b/backends/ia64_reloc.def
@@ -0,0 +1,96 @@
+/* List the relocation types for ia64. -*- C -*-
+ 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. */
+
+/* NAME, REL|EXEC|DYN */
+
+RELOC_TYPE (NONE, 0)
+RELOC_TYPE (IMM14, REL)
+RELOC_TYPE (IMM22, REL)
+RELOC_TYPE (IMM64, REL)
+RELOC_TYPE (DIR32MSB, REL|EXEC|DYN)
+RELOC_TYPE (DIR32LSB, REL|EXEC|DYN)
+RELOC_TYPE (DIR64MSB, REL|EXEC|DYN)
+RELOC_TYPE (DIR64LSB, REL|EXEC|DYN)
+RELOC_TYPE (GPREL22, REL)
+RELOC_TYPE (GPREL64I, REL)
+RELOC_TYPE (GPREL32MSB, REL)
+RELOC_TYPE (GPREL32LSB, REL)
+RELOC_TYPE (GPREL64MSB, REL)
+RELOC_TYPE (GPREL64LSB, REL)
+RELOC_TYPE (LTOFF22, REL)
+RELOC_TYPE (LTOFF64I, REL)
+RELOC_TYPE (PLTOFF22, REL)
+RELOC_TYPE (PLTOFF64I, REL)
+RELOC_TYPE (PLTOFF64MSB, REL)
+RELOC_TYPE (PLTOFF64LSB, REL)
+RELOC_TYPE (FPTR64I, REL)
+RELOC_TYPE (FPTR32MSB, REL|EXEC|DYN)
+RELOC_TYPE (FPTR32LSB, REL|EXEC|DYN)
+RELOC_TYPE (FPTR64MSB, REL|EXEC|DYN)
+RELOC_TYPE (FPTR64LSB, REL|EXEC|DYN)
+RELOC_TYPE (PCREL60B, REL)
+RELOC_TYPE (PCREL21B, REL)
+RELOC_TYPE (PCREL21M, REL)
+RELOC_TYPE (PCREL21F, REL)
+RELOC_TYPE (PCREL32MSB, REL|EXEC|DYN)
+RELOC_TYPE (PCREL32LSB, REL|EXEC|DYN)
+RELOC_TYPE (PCREL64MSB, REL|EXEC|DYN)
+RELOC_TYPE (PCREL64LSB, REL|EXEC|DYN)
+RELOC_TYPE (LTOFF_FPTR22, REL)
+RELOC_TYPE (LTOFF_FPTR64I, REL)
+RELOC_TYPE (LTOFF_FPTR32MSB, REL)
+RELOC_TYPE (LTOFF_FPTR32LSB, REL)
+RELOC_TYPE (LTOFF_FPTR64MSB, REL)
+RELOC_TYPE (LTOFF_FPTR64LSB, REL)
+RELOC_TYPE (SEGREL32MSB, REL)
+RELOC_TYPE (SEGREL32LSB, REL)
+RELOC_TYPE (SEGREL64MSB, REL)
+RELOC_TYPE (SEGREL64LSB, REL)
+RELOC_TYPE (SECREL32MSB, REL)
+RELOC_TYPE (SECREL32LSB, REL)
+RELOC_TYPE (SECREL64MSB, REL)
+RELOC_TYPE (SECREL64LSB, REL)
+RELOC_TYPE (REL32MSB, EXEC|DYN)
+RELOC_TYPE (REL32LSB, EXEC|DYN)
+RELOC_TYPE (REL64MSB, EXEC|DYN)
+RELOC_TYPE (REL64LSB, EXEC|DYN)
+RELOC_TYPE (LTV32MSB, REL)
+RELOC_TYPE (LTV32LSB, REL)
+RELOC_TYPE (LTV64MSB, REL)
+RELOC_TYPE (LTV64LSB, REL)
+RELOC_TYPE (PCREL21BI, REL)
+RELOC_TYPE (PCREL22, REL)
+RELOC_TYPE (PCREL64I, REL)
+RELOC_TYPE (IPLTMSB, REL|EXEC|DYN)
+RELOC_TYPE (IPLTLSB, REL|EXEC|DYN)
+RELOC_TYPE (COPY, EXEC)
+RELOC_TYPE (SUB, 0)
+RELOC_TYPE (LTOFF22X, REL)
+RELOC_TYPE (LDXMOV, REL)
+RELOC_TYPE (TPREL14, REL)
+RELOC_TYPE (TPREL22, REL)
+RELOC_TYPE (TPREL64I, REL)
+RELOC_TYPE (TPREL64MSB, REL|EXEC|DYN)
+RELOC_TYPE (TPREL64LSB, REL|EXEC|DYN)
+RELOC_TYPE (LTOFF_TPREL22, REL)
+RELOC_TYPE (DTPMOD64MSB, REL|EXEC|DYN)
+RELOC_TYPE (DTPMOD64LSB, REL|EXEC|DYN)
+RELOC_TYPE (LTOFF_DTPMOD22, REL)
+RELOC_TYPE (DTPREL14, REL)
+RELOC_TYPE (DTPREL22, REL)
+RELOC_TYPE (DTPREL64I, REL)
+RELOC_TYPE (DTPREL32MSB, REL|EXEC|DYN)
+RELOC_TYPE (DTPREL32LSB, REL|EXEC|DYN)
+RELOC_TYPE (DTPREL64MSB, REL|EXEC|DYN)
+RELOC_TYPE (DTPREL64LSB, REL|EXEC|DYN)
+RELOC_TYPE (LTOFF_DTPREL22, REL)
diff --git a/backends/ia64_symbol.c b/backends/ia64_symbol.c
new file mode 100644
index 00000000..1b500873
--- /dev/null
+++ b/backends/ia64_symbol.c
@@ -0,0 +1,119 @@
+/* IA-64 specific symbolic name handling.
+ Copyright (C) 2002, 2003, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2002.
+
+ 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 <elf.h>
+#include <stddef.h>
+#include <assert.h>
+
+#define BACKEND ia64_
+#include "libebl_CPU.h"
+
+
+const char *
+ia64_segment_type_name (int segment, char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ switch (segment)
+ {
+ case PT_IA_64_ARCHEXT:
+ return "IA_64_ARCHEXT";
+ case PT_IA_64_UNWIND:
+ return "IA_64_UNWIND";
+ case PT_IA_64_HP_OPT_ANOT:
+ return "IA_64_HP_OPT_ANOT";
+ case PT_IA_64_HP_HSL_ANOT:
+ return "IA_64_HP_HSL_ANOT";
+ case PT_IA_64_HP_STACK:
+ return "IA_64_HP_STACK";
+ default:
+ break;
+ }
+ return NULL;
+}
+
+const char *
+ia64_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ switch (tag)
+ {
+ case DT_IA_64_PLT_RESERVE:
+ return "IA_64_PLT_RESERVE";
+ default:
+ break;
+ }
+ return NULL;
+}
+
+/* Check dynamic tag. */
+bool
+ia64_dynamic_tag_check (int64_t tag)
+{
+ return tag == DT_IA_64_PLT_RESERVE;
+}
+
+/* Check whether machine flags are valid. */
+bool
+ia64_machine_flag_check (GElf_Word flags)
+{
+ return ((flags &~ EF_IA_64_ABI64) == 0);
+}
+
+/* Return symbolic representation of section type. */
+const char *
+ia64_section_type_name (int type,
+ char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ switch (type)
+ {
+ case SHT_IA_64_EXT:
+ return "SHT_IA_64_EXT";
+ case SHT_IA_64_UNWIND:
+ return "HT_IA_64_UNWIND";
+ }
+
+ return NULL;
+}
+
+/* Check for the simple reloc types. */
+Elf_Type
+ia64_reloc_simple_type (Ebl *ebl, int type)
+{
+ switch (type)
+ {
+ case R_IA64_DIR32MSB:
+ if (ebl->data == ELFDATA2MSB)
+ return ELF_T_WORD;
+ break;
+ case R_IA64_DIR32LSB:
+ if (ebl->data == ELFDATA2LSB)
+ return ELF_T_WORD;
+ break;
+ case R_IA64_DIR64MSB:
+ if (ebl->data == ELFDATA2MSB)
+ return ELF_T_XWORD;
+ break;
+ case R_IA64_DIR64LSB:
+ if (ebl->data == ELFDATA2LSB)
+ return ELF_T_XWORD;
+ break;
+ }
+
+ return ELF_T_NUM;
+}
diff --git a/backends/libebl_CPU.h b/backends/libebl_CPU.h
new file mode 100644
index 00000000..607c1543
--- /dev/null
+++ b/backends/libebl_CPU.h
@@ -0,0 +1,34 @@
+/* Common interface for libebl modules.
+ Copyright (C) 2000, 2001, 2002, 2003, 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. */
+
+#ifndef _LIBEBL_CPU_H
+#define _LIBEBL_CPU_H 1
+
+#include <libeblP.h>
+
+#define EBLHOOK(name) EBLHOOK_1(BACKEND, name)
+#define EBLHOOK_1(a, b) EBLHOOK_2(a, b)
+#define EBLHOOK_2(a, b) a##b
+
+/* Constructor. */
+extern const char *EBLHOOK(init) (Elf *elf, GElf_Half machine,
+ Ebl *eh, size_t ehlen);
+
+#include "ebl-hooks.h"
+
+#define HOOK(eh, name) eh->name = EBLHOOK(name)
+
+extern bool (*generic_debugscn_p) (const char *) attribute_hidden;
+
+
+#endif /* libebl_CPU.h */
diff --git a/backends/ppc64_init.c b/backends/ppc64_init.c
new file mode 100644
index 00000000..9024eafa
--- /dev/null
+++ b/backends/ppc64_init.c
@@ -0,0 +1,50 @@
+/* Initialization of PPC64 specific backend library.
+ Copyright (C) 2004, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2004.
+
+ 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
+
+#define BACKEND ppc64_
+#define RELOC_PREFIX R_PPC64_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on ppc64_reloc.def. */
+#include "common-reloc.c"
+
+
+const char *
+ppc64_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "PowerPC 64-bit";
+ ppc64_init_reloc (eh);
+ eh->reloc_simple_type = ppc64_reloc_simple_type;
+ eh->dynamic_tag_name = ppc64_dynamic_tag_name;
+ eh->dynamic_tag_check = ppc64_dynamic_tag_check;
+ 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_reloc.def b/backends/ppc64_reloc.def
new file mode 100644
index 00000000..d0cb2f91
--- /dev/null
+++ b/backends/ppc64_reloc.def
@@ -0,0 +1,119 @@
+/* List the relocation types for ppc64. -*- C -*-
+ 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. */
+
+/* NAME, REL|EXEC|DYN */
+
+RELOC_TYPE (NONE, REL)
+RELOC_TYPE (ADDR32, REL)
+RELOC_TYPE (ADDR24, REL|EXEC|DYN)
+RELOC_TYPE (ADDR16, REL|EXEC|DYN)
+RELOC_TYPE (ADDR16_LO, REL|EXEC|DYN)
+RELOC_TYPE (ADDR16_HI, REL|EXEC|DYN)
+RELOC_TYPE (ADDR16_HA, REL|EXEC|DYN)
+RELOC_TYPE (ADDR14, REL|EXEC|DYN)
+RELOC_TYPE (ADDR14_BRTAKEN, REL|EXEC|DYN)
+RELOC_TYPE (ADDR14_BRNTAKEN, REL|EXEC|DYN)
+RELOC_TYPE (REL24, REL)
+RELOC_TYPE (REL14, REL)
+RELOC_TYPE (REL14_BRTAKEN, REL)
+RELOC_TYPE (REL14_BRNTAKEN, REL)
+RELOC_TYPE (GOT16, REL)
+RELOC_TYPE (GOT16_LO, REL)
+RELOC_TYPE (GOT16_HI, REL)
+RELOC_TYPE (GOT16_HA, REL)
+RELOC_TYPE (COPY, EXEC)
+RELOC_TYPE (GLOB_DAT, EXEC|DYN)
+RELOC_TYPE (JMP_SLOT, EXEC|DYN)
+RELOC_TYPE (RELATIVE, EXEC|DYN)
+RELOC_TYPE (UADDR32, REL|EXEC|DYN)
+RELOC_TYPE (UADDR16, REL|EXEC|DYN)
+RELOC_TYPE (REL32, REL|EXEC|DYN)
+RELOC_TYPE (PLT32, REL)
+RELOC_TYPE (PLTREL32, REL)
+RELOC_TYPE (PLT16_LO, REL)
+RELOC_TYPE (PLT16_HI, REL)
+RELOC_TYPE (PLT16_HA, REL)
+RELOC_TYPE (SECTOFF, REL)
+RELOC_TYPE (SECTOFF_LO, REL)
+RELOC_TYPE (SECTOFF_HI, REL)
+RELOC_TYPE (SECTOFF_HA, REL)
+RELOC_TYPE (ADDR30, REL|EXEC|DYN)
+RELOC_TYPE (ADDR64, REL|EXEC|DYN)
+RELOC_TYPE (ADDR16_HIGHER, REL)
+RELOC_TYPE (ADDR16_HIGHERA, REL)
+RELOC_TYPE (ADDR16_HIGHEST, REL)
+RELOC_TYPE (ADDR16_HIGHESTA, REL)
+RELOC_TYPE (UADDR64, REL|EXEC|DYN)
+RELOC_TYPE (REL64, REL|EXEC|DYN)
+RELOC_TYPE (PLT64, REL)
+RELOC_TYPE (PLTREL64, REL)
+RELOC_TYPE (TOC16, REL)
+RELOC_TYPE (TOC16_LO, REL)
+RELOC_TYPE (TOC16_HI, REL)
+RELOC_TYPE (TOC16_HA, REL)
+RELOC_TYPE (TOC, REL)
+RELOC_TYPE (PLTGOT16, REL)
+RELOC_TYPE (PLTGOT16_LO, REL)
+RELOC_TYPE (PLTGOT16_HI, REL)
+RELOC_TYPE (PLTGOT16_HA, REL)
+RELOC_TYPE (ADDR16_DS, REL)
+RELOC_TYPE (ADDR16_LO_DS, REL|EXEC|DYN)
+RELOC_TYPE (GOT16_DS, REL)
+RELOC_TYPE (GOT16_LO_DS, REL)
+RELOC_TYPE (PLT16_LO_DS, REL)
+RELOC_TYPE (SECTOFF_DS, REL)
+RELOC_TYPE (SECTOFF_LO_DS, REL)
+RELOC_TYPE (TOC16_DS, REL)
+RELOC_TYPE (TOC16_LO_DS, REL)
+RELOC_TYPE (PLTGOT16_DS, REL)
+RELOC_TYPE (PLTGOT16_LO_DS, REL)
+RELOC_TYPE (TLS, REL)
+RELOC_TYPE (DTPMOD64, EXEC|DYN)
+RELOC_TYPE (TPREL16, EXEC|DYN)
+RELOC_TYPE (TPREL16_LO, EXEC|DYN)
+RELOC_TYPE (TPREL16_HI, EXEC|DYN)
+RELOC_TYPE (TPREL16_HA, EXEC|DYN)
+RELOC_TYPE (TPREL64, EXEC|DYN)
+RELOC_TYPE (DTPREL16, REL)
+RELOC_TYPE (DTPREL16_LO, REL)
+RELOC_TYPE (DTPREL16_HI, REL)
+RELOC_TYPE (DTPREL16_HA, REL)
+RELOC_TYPE (DTPREL64, EXEC|DYN)
+RELOC_TYPE (GOT_TLSGD16, REL)
+RELOC_TYPE (GOT_TLSGD16_LO, REL)
+RELOC_TYPE (GOT_TLSGD16_HI, REL)
+RELOC_TYPE (GOT_TLSGD16_HA, REL)
+RELOC_TYPE (GOT_TLSLD16, REL)
+RELOC_TYPE (GOT_TLSLD16_LO, REL)
+RELOC_TYPE (GOT_TLSLD16_HI, REL)
+RELOC_TYPE (GOT_TLSLD16_HA, REL)
+RELOC_TYPE (GOT_TPREL16_DS, REL)
+RELOC_TYPE (GOT_TPREL16_LO_DS, REL)
+RELOC_TYPE (GOT_TPREL16_HI, REL)
+RELOC_TYPE (GOT_TPREL16_HA, REL)
+RELOC_TYPE (GOT_DTPREL16_DS, REL)
+RELOC_TYPE (GOT_DTPREL16_LO_DS, REL)
+RELOC_TYPE (GOT_DTPREL16_HI, REL)
+RELOC_TYPE (GOT_DTPREL16_HA, REL)
+RELOC_TYPE (TPREL16_DS, REL)
+RELOC_TYPE (TPREL16_LO_DS, EXEC|DYN)
+RELOC_TYPE (TPREL16_HIGHER, EXEC|DYN)
+RELOC_TYPE (TPREL16_HIGHERA, EXEC|DYN)
+RELOC_TYPE (TPREL16_HIGHEST, EXEC|DYN)
+RELOC_TYPE (TPREL16_HIGHESTA, EXEC|DYN)
+RELOC_TYPE (DTPREL16_DS, REL)
+RELOC_TYPE (DTPREL16_LO_DS, REL)
+RELOC_TYPE (DTPREL16_HIGHER, REL)
+RELOC_TYPE (DTPREL16_HIGHERA, REL)
+RELOC_TYPE (DTPREL16_HIGHEST, REL)
+RELOC_TYPE (DTPREL16_HIGHESTA, REL)
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/backends/ppc64_symbol.c b/backends/ppc64_symbol.c
new file mode 100644
index 00000000..db486176
--- /dev/null
+++ b/backends/ppc64_symbol.c
@@ -0,0 +1,97 @@
+/* PPC64 specific symbolic name handling.
+ Copyright (C) 2004, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2004.
+
+ 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 <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#define BACKEND ppc64_
+#include "libebl_CPU.h"
+
+
+/* Check for the simple reloc types. */
+Elf_Type
+ppc64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+ switch (type)
+ {
+ case R_PPC64_ADDR64:
+ case R_PPC64_UADDR64:
+ return ELF_T_XWORD;
+ case R_PPC64_ADDR32:
+ case R_PPC64_UADDR32:
+ return ELF_T_WORD;
+ case R_PPC64_UADDR16:
+ return ELF_T_HALF;
+ default:
+ return ELF_T_NUM;
+ }
+}
+
+
+const char *
+ppc64_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ switch (tag)
+ {
+ case DT_PPC64_GLINK:
+ return "PPC64_GLINK";
+ case DT_PPC64_OPD:
+ return "PPC64_OPD";
+ case DT_PPC64_OPDSZ:
+ return "PPC64_OPDSZ";
+ default:
+ break;
+ }
+ return NULL;
+}
+
+
+bool
+ppc64_dynamic_tag_check (int64_t tag)
+{
+ return (tag == DT_PPC64_GLINK
+ || tag == DT_PPC64_OPD
+ || tag == DT_PPC64_OPDSZ);
+}
+
+
+/* Check whether given symbol's st_value and st_size are OK despite failing
+ normal checks. */
+bool
+ppc64_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr,
+ const GElf_Sym *sym __attribute__ ((unused)),
+ const char *name __attribute__ ((unused)),
+ const GElf_Shdr *destshdr)
+{
+ const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name);
+ if (sname == NULL)
+ return false;
+ return strcmp (sname, ".opd") == 0;
+}
+
+
+/* Check if backend uses a bss PLT in this file. */
+bool
+ppc64_bss_plt_p (Elf *elf __attribute__ ((unused)),
+ GElf_Ehdr *ehdr __attribute__ ((unused)))
+{
+ return true;
+}
diff --git a/backends/ppc_init.c b/backends/ppc_init.c
new file mode 100644
index 00000000..36ca7a24
--- /dev/null
+++ b/backends/ppc_init.c
@@ -0,0 +1,49 @@
+/* Initialization of PPC specific backend library.
+ Copyright (C) 2004, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2004.
+
+ 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
+
+#define BACKEND ppc_
+#define RELOC_PREFIX R_PPC_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on ppc_reloc.def. */
+#include "common-reloc.c"
+
+
+const char *
+ppc_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "PowerPC";
+ ppc_init_reloc (eh);
+ eh->reloc_simple_type = ppc_reloc_simple_type;
+ eh->dynamic_tag_name = ppc_dynamic_tag_name;
+ 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/backends/ppc_reloc.def b/backends/ppc_reloc.def
new file mode 100644
index 00000000..97187381
--- /dev/null
+++ b/backends/ppc_reloc.def
@@ -0,0 +1,107 @@
+/* List the relocation types for ppc. -*- C -*-
+ 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. */
+
+/* NAME, REL|EXEC|DYN */
+
+RELOC_TYPE (NONE, 0)
+RELOC_TYPE (ADDR32, REL|EXEC|DYN)
+RELOC_TYPE (ADDR24, REL)
+RELOC_TYPE (ADDR16, REL)
+RELOC_TYPE (ADDR16_LO, REL)
+RELOC_TYPE (ADDR16_HI, REL)
+RELOC_TYPE (ADDR16_HA, REL)
+RELOC_TYPE (ADDR14, REL)
+RELOC_TYPE (ADDR14_BRTAKEN, REL)
+RELOC_TYPE (ADDR14_BRNTAKEN, REL)
+RELOC_TYPE (REL24, REL)
+RELOC_TYPE (REL14, REL)
+RELOC_TYPE (REL14_BRTAKEN, REL)
+RELOC_TYPE (REL14_BRNTAKEN, REL)
+RELOC_TYPE (GOT16, REL)
+RELOC_TYPE (GOT16_LO, REL)
+RELOC_TYPE (GOT16_HI, REL)
+RELOC_TYPE (GOT16_HA, REL)
+RELOC_TYPE (PLTREL24, REL)
+RELOC_TYPE (COPY, EXEC)
+RELOC_TYPE (GLOB_DAT, EXEC|DYN)
+RELOC_TYPE (JMP_SLOT, EXEC|DYN)
+RELOC_TYPE (RELATIVE, EXEC|DYN)
+RELOC_TYPE (LOCAL24PC, REL)
+RELOC_TYPE (UADDR32, REL)
+RELOC_TYPE (UADDR16, REL)
+RELOC_TYPE (REL32, REL)
+RELOC_TYPE (PLT32, REL)
+RELOC_TYPE (PLTREL32, REL)
+RELOC_TYPE (PLT16_LO, REL)
+RELOC_TYPE (PLT16_HI, REL)
+RELOC_TYPE (PLT16_HA, REL)
+RELOC_TYPE (SDAREL16, REL)
+RELOC_TYPE (SECTOFF, REL)
+RELOC_TYPE (SECTOFF_LO, REL)
+RELOC_TYPE (SECTOFF_HI, REL)
+RELOC_TYPE (SECTOFF_HA, REL)
+RELOC_TYPE (TLS, REL)
+RELOC_TYPE (DTPMOD32, EXEC|DYN)
+RELOC_TYPE (TPREL16, REL)
+RELOC_TYPE (TPREL16_LO, REL)
+RELOC_TYPE (TPREL16_HI, REL)
+RELOC_TYPE (TPREL16_HA, REL)
+RELOC_TYPE (TPREL32, EXEC|DYN)
+RELOC_TYPE (DTPREL16, REL)
+RELOC_TYPE (DTPREL16_LO, REL)
+RELOC_TYPE (DTPREL16_HI, REL)
+RELOC_TYPE (DTPREL16_HA, REL)
+RELOC_TYPE (DTPREL32, EXEC|DYN)
+RELOC_TYPE (GOT_TLSGD16, REL)
+RELOC_TYPE (GOT_TLSGD16_LO, REL)
+RELOC_TYPE (GOT_TLSGD16_HI, REL)
+RELOC_TYPE (GOT_TLSGD16_HA, REL)
+RELOC_TYPE (GOT_TLSLD16, REL)
+RELOC_TYPE (GOT_TLSLD16_LO, REL)
+RELOC_TYPE (GOT_TLSLD16_HI, REL)
+RELOC_TYPE (GOT_TLSLD16_HA, REL)
+RELOC_TYPE (GOT_TPREL16, REL)
+RELOC_TYPE (GOT_TPREL16_LO, REL)
+RELOC_TYPE (GOT_TPREL16_HI, REL)
+RELOC_TYPE (GOT_TPREL16_HA, REL)
+RELOC_TYPE (GOT_DTPREL16, REL)
+RELOC_TYPE (GOT_DTPREL16_LO, REL)
+RELOC_TYPE (GOT_DTPREL16_HI, REL)
+RELOC_TYPE (GOT_DTPREL16_HA, REL)
+RELOC_TYPE (EMB_NADDR32, REL)
+RELOC_TYPE (EMB_NADDR16, REL)
+RELOC_TYPE (EMB_NADDR16_LO, REL)
+RELOC_TYPE (EMB_NADDR16_HI, REL)
+RELOC_TYPE (EMB_NADDR16_HA, REL)
+RELOC_TYPE (EMB_SDAI16, REL)
+RELOC_TYPE (EMB_SDA2I16, REL)
+RELOC_TYPE (EMB_SDA2REL, REL)
+RELOC_TYPE (EMB_SDA21, REL)
+RELOC_TYPE (EMB_MRKREF, REL)
+RELOC_TYPE (EMB_RELSEC16, REL)
+RELOC_TYPE (EMB_RELST_LO, REL)
+RELOC_TYPE (EMB_RELST_HI, REL)
+RELOC_TYPE (EMB_RELST_HA, REL)
+RELOC_TYPE (EMB_BIT_FLD, REL)
+RELOC_TYPE (EMB_RELSDA, REL)
+RELOC_TYPE (DIAB_SDA21_LO, REL)
+RELOC_TYPE (DIAB_SDA21_HI, REL)
+RELOC_TYPE (DIAB_SDA21_HA, REL)
+RELOC_TYPE (DIAB_RELSDA_LO, REL)
+RELOC_TYPE (DIAB_RELSDA_HI, REL)
+RELOC_TYPE (DIAB_RELSDA_HA, REL)
+RELOC_TYPE (REL16, REL)
+RELOC_TYPE (REL16_LO, REL)
+RELOC_TYPE (REL16_HI, REL)
+RELOC_TYPE (REL16_HA, REL)
+RELOC_TYPE (TOC16, REL)
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/backends/ppc_symbol.c b/backends/ppc_symbol.c
new file mode 100644
index 00000000..f161d70e
--- /dev/null
+++ b/backends/ppc_symbol.c
@@ -0,0 +1,143 @@
+/* PPC specific symbolic name handling.
+ Copyright (C) 2004, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2004.
+
+ 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 <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#define BACKEND ppc_
+#include "libebl_CPU.h"
+
+
+/* Check for the simple reloc types. */
+Elf_Type
+ppc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+ switch (type)
+ {
+ case R_PPC_ADDR32:
+ case R_PPC_UADDR32:
+ return ELF_T_WORD;
+ case R_PPC_UADDR16:
+ return ELF_T_HALF;
+ default:
+ return ELF_T_NUM;
+ }
+}
+
+
+const char *
+ppc_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ switch (tag)
+ {
+ case DT_PPC_GOT:
+ return "PPC_GOT";
+ default:
+ break;
+ }
+ return NULL;
+}
+
+
+bool
+ppc_dynamic_tag_check (int64_t tag)
+{
+ return tag == DT_PPC_GOT;
+}
+
+
+/* Look for DT_PPC_GOT. */
+static bool
+find_dyn_got (Elf *elf, GElf_Ehdr *ehdr, GElf_Addr *addr)
+{
+ for (int i = 0; i < ehdr->e_phnum; ++i)
+ {
+ GElf_Phdr phdr_mem;
+ GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
+ if (phdr == NULL || phdr->p_type != PT_DYNAMIC)
+ continue;
+
+ Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset);
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ Elf_Data *data = elf_getdata (scn, NULL);
+ if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC && data != NULL)
+ for (unsigned int j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j)
+ {
+ GElf_Dyn dyn_mem;
+ GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
+ if (dyn != NULL && dyn->d_tag == DT_PPC_GOT)
+ {
+ *addr = dyn->d_un.d_ptr;
+ return true;
+ }
+ }
+
+ /* There is only one PT_DYNAMIC entry. */
+ break;
+ }
+
+ return false;
+}
+
+
+/* Check whether given symbol's st_value and st_size are OK despite failing
+ normal checks. */
+bool
+ppc_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym,
+ const char *name, const GElf_Shdr *destshdr)
+{
+ if (name == NULL)
+ return false;
+
+ if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
+ {
+ GElf_Addr gotaddr;
+ if (find_dyn_got (elf, ehdr, &gotaddr))
+ return sym->st_value == gotaddr;
+ return sym->st_value == destshdr->sh_addr + 4;
+ }
+
+ const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name);
+ if (sname == NULL)
+ return false;
+
+ if (strcmp (name, "_SDA_BASE_") == 0)
+ return (strcmp (sname, ".sdata") == 0
+ && sym->st_value == destshdr->sh_addr + 0x8000
+ && sym->st_size == 0);
+
+ if (strcmp (name, "_SDA2_BASE_") == 0)
+ return (strcmp (sname, ".sdata2") == 0
+ && sym->st_value == destshdr->sh_addr + 0x8000
+ && sym->st_size == 0);
+
+ return false;
+}
+
+
+/* Check if backend uses a bss PLT in this file. */
+bool
+ppc_bss_plt_p (Elf *elf, GElf_Ehdr *ehdr)
+{
+ GElf_Addr addr;
+ return ! find_dyn_got (elf, ehdr, &addr);
+}
diff --git a/backends/s390_init.c b/backends/s390_init.c
new file mode 100644
index 00000000..14578660
--- /dev/null
+++ b/backends/s390_init.c
@@ -0,0 +1,43 @@
+/* Initialization of S/390 specific backend library.
+ 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
+
+#define BACKEND s390_
+#define RELOC_PREFIX R_390_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on arm_reloc.def. */
+#include "common-reloc.c"
+
+
+const char *
+s390_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "IBM S/390";
+ s390_init_reloc (eh);
+ eh->reloc_simple_type = s390_reloc_simple_type;
+
+ return MODVERSION;
+}
diff --git a/backends/s390_reloc.def b/backends/s390_reloc.def
new file mode 100644
index 00000000..bee67b33
--- /dev/null
+++ b/backends/s390_reloc.def
@@ -0,0 +1,76 @@
+/* List the relocation types for s390. -*- C -*-
+ 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. */
+
+/* NAME, REL|EXEC|DYN */
+
+RELOC_TYPE (NONE, 0)
+RELOC_TYPE (8, 0)
+RELOC_TYPE (12, 0)
+RELOC_TYPE (16, 0)
+RELOC_TYPE (32, 0)
+RELOC_TYPE (PC32, 0)
+RELOC_TYPE (GOT12, 0)
+RELOC_TYPE (GOT32, 0)
+RELOC_TYPE (PLT32, 0)
+RELOC_TYPE (COPY, EXEC)
+RELOC_TYPE (GLOB_DAT, EXEC|DYN)
+RELOC_TYPE (JMP_SLOT, EXEC|DYN)
+RELOC_TYPE (RELATIVE, EXEC|DYN)
+RELOC_TYPE (GOTOFF32, 0)
+RELOC_TYPE (GOTPC, 0)
+RELOC_TYPE (GOT16, 0)
+RELOC_TYPE (PC16, 0)
+RELOC_TYPE (PC16DBL, 0)
+RELOC_TYPE (PLT16DBL, 0)
+RELOC_TYPE (PC32DBL, 0)
+RELOC_TYPE (PLT32DBL, 0)
+RELOC_TYPE (GOTPCDBL, 0)
+RELOC_TYPE (64, 0)
+RELOC_TYPE (PC64, 0)
+RELOC_TYPE (GOT64, 0)
+RELOC_TYPE (PLT64, 0)
+RELOC_TYPE (GOTENT, 0)
+RELOC_TYPE (GOTOFF16, 0)
+RELOC_TYPE (GOTOFF64, 0)
+RELOC_TYPE (GOTPLT12, 0)
+RELOC_TYPE (GOTPLT16, 0)
+RELOC_TYPE (GOTPLT32, 0)
+RELOC_TYPE (GOTPLT64, 0)
+RELOC_TYPE (GOTPLTENT, 0)
+RELOC_TYPE (PLTOFF16, 0)
+RELOC_TYPE (PLTOFF32, 0)
+RELOC_TYPE (PLTOFF64, 0)
+RELOC_TYPE (TLS_LOAD, 0)
+RELOC_TYPE (TLS_GDCALL, 0)
+RELOC_TYPE (TLS_LDCALL, 0)
+RELOC_TYPE (TLS_GD32, 0)
+RELOC_TYPE (TLS_GD64, 0)
+RELOC_TYPE (TLS_GOTIE12, 0)
+RELOC_TYPE (TLS_GOTIE32, 0)
+RELOC_TYPE (TLS_GOTIE64, 0)
+RELOC_TYPE (TLS_LDM32, 0)
+RELOC_TYPE (TLS_LDM64, 0)
+RELOC_TYPE (TLS_IE32, 0)
+RELOC_TYPE (TLS_IE64, 0)
+RELOC_TYPE (TLS_IEENT, 0)
+RELOC_TYPE (TLS_LE32, 0)
+RELOC_TYPE (TLS_LE64, 0)
+RELOC_TYPE (TLS_LDO32, 0)
+RELOC_TYPE (TLS_LDO64, 0)
+RELOC_TYPE (TLS_DTPMOD, 0)
+RELOC_TYPE (TLS_DTPOFF, 0)
+RELOC_TYPE (TLS_TPOFF, 0)
+RELOC_TYPE (20, 0)
+RELOC_TYPE (GOT20, 0)
+RELOC_TYPE (GOTPLT20, 0)
+RELOC_TYPE (TLS_GOTIE20, 0)
diff --git a/backends/s390_symbol.c b/backends/s390_symbol.c
new file mode 100644
index 00000000..ddfefbb2
--- /dev/null
+++ b/backends/s390_symbol.c
@@ -0,0 +1,41 @@
+/* S/390-specific symbolic name handling.
+ 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 <elf.h>
+#include <stddef.h>
+
+#define BACKEND s390_
+#include "libebl_CPU.h"
+
+/* Check for the simple reloc types. */
+Elf_Type
+s390_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+ switch (type)
+ {
+ case R_390_64:
+ return ELF_T_SXWORD;
+ case R_390_32:
+ return ELF_T_SWORD;
+ case R_390_16:
+ return ELF_T_HALF;
+ case R_390_8:
+ return ELF_T_BYTE;
+ default:
+ return ELF_T_NUM;
+ }
+}
diff --git a/backends/sh_init.c b/backends/sh_init.c
new file mode 100644
index 00000000..4fadd9b4
--- /dev/null
+++ b/backends/sh_init.c
@@ -0,0 +1,44 @@
+/* Initialization of SH specific backend library.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2000.
+
+ 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
+
+#define BACKEND sh_
+#define RELOC_PREFIX R_SH_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on sh_reloc.def. */
+#include "common-reloc.c"
+
+
+const char *
+sh_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "Hitachi SH";
+ sh_init_reloc (eh);
+ eh->reloc_simple_type = sh_reloc_simple_type;
+
+ return MODVERSION;
+}
diff --git a/backends/sh_reloc.def b/backends/sh_reloc.def
new file mode 100644
index 00000000..56db1071
--- /dev/null
+++ b/backends/sh_reloc.def
@@ -0,0 +1,52 @@
+/* List the relocation types for SH. -*- C -*-
+ 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. */
+
+/* NAME, REL|EXEC|DYN */
+
+RELOC_TYPE (NONE, 0)
+RELOC_TYPE (DIR32, REL|DYN)
+RELOC_TYPE (REL32, REL|DYN)
+RELOC_TYPE (DIR8WPN, REL)
+RELOC_TYPE (IND12W, REL)
+RELOC_TYPE (DIR8WPL, REL)
+RELOC_TYPE (DIR8WPZ, REL)
+RELOC_TYPE (DIR8BP, REL)
+RELOC_TYPE (DIR8W, REL)
+RELOC_TYPE (DIR8L, REL)
+RELOC_TYPE (SWITCH16, REL)
+RELOC_TYPE (SWITCH32, REL)
+RELOC_TYPE (USES, REL)
+RELOC_TYPE (COUNT, REL)
+RELOC_TYPE (ALIGN, REL)
+RELOC_TYPE (CODE, REL)
+RELOC_TYPE (DATA, REL)
+RELOC_TYPE (LABEL, REL)
+RELOC_TYPE (SWITCH8, REL)
+RELOC_TYPE (GNU_VTINHERIT, REL)
+RELOC_TYPE (GNU_VTENTRY, REL)
+RELOC_TYPE (TLS_GD_32, REL)
+RELOC_TYPE (TLS_LD_32, REL)
+RELOC_TYPE (TLS_LDO_32, REL)
+RELOC_TYPE (TLS_IE_32, REL)
+RELOC_TYPE (TLS_LE_32, REL)
+RELOC_TYPE (TLS_DTPMOD32, DYN)
+RELOC_TYPE (TLS_DTPOFF32, DYN)
+RELOC_TYPE (TLS_TPOFF32, DYN)
+RELOC_TYPE (GOT32, REL)
+RELOC_TYPE (PLT32, REL)
+RELOC_TYPE (COPY, EXEC)
+RELOC_TYPE (GLOB_DAT, EXEC|DYN)
+RELOC_TYPE (JMP_SLOT, EXEC|DYN)
+RELOC_TYPE (RELATIVE, EXEC|DYN)
+RELOC_TYPE (GOTOFF, REL)
+RELOC_TYPE (GOTPC, REL)
diff --git a/backends/sh_symbol.c b/backends/sh_symbol.c
new file mode 100644
index 00000000..3209d34e
--- /dev/null
+++ b/backends/sh_symbol.c
@@ -0,0 +1,44 @@
+/* SH specific relocation handling.
+ Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2000.
+
+ 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 <elf.h>
+#include <stddef.h>
+
+#define BACKEND sh_
+#include "libebl_CPU.h"
+
+
+/* Return true if the symbol type is that referencing the GOT. */
+bool
+sh_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), int type)
+{
+ return type == R_SH_GOTPC;
+}
+
+/* Check for the simple reloc types. */
+Elf_Type
+sh_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+ switch (type)
+ {
+ case R_SH_DIR32:
+ return ELF_T_WORD;
+ default:
+ return ELF_T_NUM;
+ }
+}
diff --git a/backends/sparc_init.c b/backends/sparc_init.c
new file mode 100644
index 00000000..541df842
--- /dev/null
+++ b/backends/sparc_init.c
@@ -0,0 +1,49 @@
+/* Initialization of SPARC specific backend library.
+ Copyright (C) 2002, 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
+
+#define BACKEND sparc_
+#define RELOC_PREFIX R_SPARC_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on sparc_reloc.def. */
+#include "common-reloc.c"
+
+
+const char *
+sparc_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ if (machine == EM_SPARCV9)
+ eh->name = "SPARC v9";
+ else if (machine == EM_SPARC32PLUS)
+ eh->name = "SPARC v8+";
+ else
+ eh->name = "SPARC";
+ sparc_init_reloc (eh);
+ eh->reloc_simple_type = sparc_reloc_simple_type;
+ //eh->core_note = sparc_core_note;
+
+ return MODVERSION;
+}
diff --git a/backends/sparc_reloc.def b/backends/sparc_reloc.def
new file mode 100644
index 00000000..91fcad74
--- /dev/null
+++ b/backends/sparc_reloc.def
@@ -0,0 +1,94 @@
+/* List the relocation types for sparc. -*- C -*-
+ 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. */
+
+/* NAME, REL|EXEC|DYN */
+
+RELOC_TYPE (NONE, 0)
+RELOC_TYPE (8, 0)
+RELOC_TYPE (16, 0)
+RELOC_TYPE (32, 0)
+RELOC_TYPE (DISP8, 0)
+RELOC_TYPE (DISP16, 0)
+RELOC_TYPE (DISP32, 0)
+RELOC_TYPE (WDISP30, 0)
+RELOC_TYPE (WDISP22, 0)
+RELOC_TYPE (HI22, 0)
+RELOC_TYPE (22, 0)
+RELOC_TYPE (13, 0)
+RELOC_TYPE (LO10, 0)
+RELOC_TYPE (GOT10, 0)
+RELOC_TYPE (GOT13, 0)
+RELOC_TYPE (GOT22, 0)
+RELOC_TYPE (PC10, 0)
+RELOC_TYPE (PC22, 0)
+RELOC_TYPE (WPLT30, 0)
+RELOC_TYPE (COPY, EXEC)
+RELOC_TYPE (GLOB_DAT, EXEC|DYN)
+RELOC_TYPE (JMP_SLOT, EXEC|DYN)
+RELOC_TYPE (RELATIVE, EXEC|DYN)
+RELOC_TYPE (UA32, 0)
+RELOC_TYPE (PLT32, 0)
+RELOC_TYPE (HIPLT22, 0)
+RELOC_TYPE (LOPLT10, 0)
+RELOC_TYPE (PCPLT32, 0)
+RELOC_TYPE (PCPLT22, 0)
+RELOC_TYPE (PCPLT10, 0)
+RELOC_TYPE (10, 0)
+RELOC_TYPE (11, 0)
+RELOC_TYPE (64, 0)
+RELOC_TYPE (OLO10, 0)
+RELOC_TYPE (HH22, 0)
+RELOC_TYPE (HM10, 0)
+RELOC_TYPE (LM22, 0)
+RELOC_TYPE (PC_HH22, 0)
+RELOC_TYPE (PC_HM10, 0)
+RELOC_TYPE (PC_LM22, 0)
+RELOC_TYPE (WDISP16, 0)
+RELOC_TYPE (WDISP19, 0)
+RELOC_TYPE (7, 0)
+RELOC_TYPE (5, 0)
+RELOC_TYPE (6, 0)
+RELOC_TYPE (DISP64, 0)
+RELOC_TYPE (PLT64, 0)
+RELOC_TYPE (HIX22, 0)
+RELOC_TYPE (LOX10, 0)
+RELOC_TYPE (H44, 0)
+RELOC_TYPE (M44, 0)
+RELOC_TYPE (L44, 0)
+RELOC_TYPE (REGISTER, 0)
+RELOC_TYPE (UA64, 0)
+RELOC_TYPE (UA16, 0)
+RELOC_TYPE (TLS_GD_HI22, 0)
+RELOC_TYPE (TLS_GD_LO10, 0)
+RELOC_TYPE (TLS_GD_ADD, 0)
+RELOC_TYPE (TLS_GD_CALL, 0)
+RELOC_TYPE (TLS_LDM_HI22, 0)
+RELOC_TYPE (TLS_LDM_LO10, 0)
+RELOC_TYPE (TLS_LDM_ADD, 0)
+RELOC_TYPE (TLS_LDM_CALL, 0)
+RELOC_TYPE (TLS_LDO_HIX22, 0)
+RELOC_TYPE (TLS_LDO_LOX10, 0)
+RELOC_TYPE (TLS_LDO_ADD, 0)
+RELOC_TYPE (TLS_IE_HI22, 0)
+RELOC_TYPE (TLS_IE_LO10, 0)
+RELOC_TYPE (TLS_IE_LD, 0)
+RELOC_TYPE (TLS_IE_LDX, 0)
+RELOC_TYPE (TLS_IE_ADD, 0)
+RELOC_TYPE (TLS_LE_HIX22, 0)
+RELOC_TYPE (TLS_LE_LOX10, 0)
+RELOC_TYPE (TLS_DTPMOD32, 0)
+RELOC_TYPE (TLS_DTPMOD64, 0)
+RELOC_TYPE (TLS_DTPOFF32, 0)
+RELOC_TYPE (TLS_DTPOFF64, 0)
+RELOC_TYPE (TLS_TPOFF32, 0)
+RELOC_TYPE (TLS_TPOFF64, 0)
diff --git a/backends/sparc_symbol.c b/backends/sparc_symbol.c
new file mode 100644
index 00000000..c83e5d3a
--- /dev/null
+++ b/backends/sparc_symbol.c
@@ -0,0 +1,45 @@
+/* SPARC specific symbolic name handling.
+ Copyright (C) 2002, 2003, 2005 Red Hat, Inc.
+ Written by Jakub Jelinek <[email protected]>, 2002.
+
+ 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 <elf.h>
+#include <stddef.h>
+
+#define BACKEND sparc_
+#include "libebl_CPU.h"
+
+/* Check for the simple reloc types. */
+Elf_Type
+sparc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+ switch (type)
+ {
+ case R_SPARC_8:
+ return ELF_T_BYTE;
+ case R_SPARC_16:
+ case R_SPARC_UA16:
+ return ELF_T_HALF;
+ case R_SPARC_32:
+ case R_SPARC_UA32:
+ return ELF_T_WORD;
+ case R_SPARC_64:
+ case R_SPARC_UA64:
+ return ELF_T_XWORD;
+ default:
+ return ELF_T_NUM;
+ }
+}
diff --git a/backends/x86_64_corenote.c b/backends/x86_64_corenote.c
new file mode 100644
index 00000000..2fd775b6
--- /dev/null
+++ b/backends/x86_64_corenote.c
@@ -0,0 +1,172 @@
+/* x86-64 specific core note handling.
+ Copyright (C) 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2005.
+
+ 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 <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#define BACKEND x86_64_
+#include "libebl_CPU.h"
+
+
+/* We cannot include <sys/procfs.h> since the definition would be for
+ the host platform and not always x86-64 as required here. */
+struct elf_prstatus
+ {
+ struct
+ {
+ int32_t si_signo; /* Signal number. */
+ int32_t si_code; /* Extra code. */
+ int32_t si_errno; /* Errno. */
+ } pr_info; /* Info associated with signal. */
+ int16_t pr_cursig; /* Current signal. */
+ uint64_t pr_sigpend; /* Set of pending signals. */
+ uint64_t pr_sighold; /* Set of held signals. */
+ int32_t pr_pid;
+ int32_t pr_ppid;
+ int32_t pr_pgrp;
+ int32_t pr_sid;
+ struct x86_64_timeval
+ {
+ int64_t tv_sec;
+ int32_t tv_usec;
+ } pr_utime; /* User time. */
+ struct x86_64_timeval pr_stime; /* System time. */
+ struct x86_64_timeval pr_cutime; /* Cumulative user time. */
+ struct x86_64_timeval pr_cstime; /* Cumulative system time. */
+ uint64_t pr_reg[27]; /* GP registers. */
+ int32_t pr_fpvalid; /* True if math copro being used. */
+ };
+
+
+struct elf_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ uint64_t pr_flag; /* Flags. */
+ uint32_t pr_uid;
+ uint32_t pr_gid;
+ int32_t pr_pid;
+ int32_t pr_ppid;
+ int32_t pr_pgrp;
+ int32_t pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[80]; /* Initial part of arg list. */
+ };
+
+
+bool
+x86_64_core_note (name, type, descsz, desc)
+ const char *name __attribute__ ((unused));
+ uint32_t type;
+ uint32_t descsz;
+ const char *desc;
+{
+ bool result = false;
+
+ switch (type)
+ {
+ case NT_PRSTATUS:
+ if (descsz < sizeof (struct elf_prstatus))
+ /* Not enough data. */
+ break;
+
+ struct elf_prstatus *stat = (struct elf_prstatus *) desc;
+
+ printf (" SIGINFO: signo: %" PRId32 ", code = %" PRId32
+ ", errno = %" PRId32 "\n"
+ " signal: %" PRId16 ", pending: %#08" PRIx64 ", holding: %#08"
+ PRIx64 "\n"
+ " pid: %" PRId32 ", ppid = %" PRId32 ", pgrp = %" PRId32
+ ", sid = %" PRId32 "\n"
+ " utime: %6" PRId64 ".%06" PRId32
+ "s, stime: %6" PRId64 ".%06" PRId32 "s\n"
+ " cutime: %6" PRId64 ".%06" PRId32
+ "s, cstime: %6" PRId64 ".%06" PRId32 "s\n"
+ " rax: %016" PRIx64 " rbx: %016" PRIx64 "\n"
+ " rcx: %016" PRIx64 " rdx: %016" PRIx64 "\n"
+ " rsi: %016" PRIx64 " rdi: %016" PRIx64 "\n"
+ " rbp: %016" PRIx64 " rsp: %016" PRIx64 "\n"
+ " r8: %016" PRIx64 " r9: %016" PRIx64 "\n"
+ " r10: %016" PRIx64 " r11: %016" PRIx64 "\n"
+ " r12: %016" PRIx64 " r13: %016" PRIx64 "\n"
+ " r14: %016" PRIx64 " r15: %016" PRIx64 "\n"
+ " rip: %016" PRIx64 " eflags: %08" PRIx64 "\n"
+ " original rax: %016" PRIx64 "\n"
+ " cs: %04" PRIx64 " ds: %04" PRIx64 " es: %04" PRIx64
+ " ss: %04" PRIx64 "\n"
+ " fs: %04" PRIx64 " fs_base: %016" PRIx64
+ " gs: %04" PRIx64 " gs_base: %016" PRIx64 "\n\n",
+ stat->pr_info. si_signo,
+ stat->pr_info. si_code,
+ stat->pr_info. si_errno,
+ stat->pr_cursig,
+ stat->pr_sigpend, stat->pr_sighold,
+ stat->pr_pid, stat->pr_ppid, stat->pr_pgrp, stat->pr_sid,
+ stat->pr_utime.tv_sec, stat->pr_utime.tv_usec,
+ stat->pr_stime.tv_sec, stat->pr_stime.tv_usec,
+ stat->pr_cutime.tv_sec, stat->pr_cutime.tv_usec,
+ stat->pr_cstime.tv_sec, stat->pr_cstime.tv_usec,
+ stat->pr_reg[10], stat->pr_reg[5], stat->pr_reg[11],
+ stat->pr_reg[12], stat->pr_reg[13], stat->pr_reg[14],
+ stat->pr_reg[4], stat->pr_reg[10], stat->pr_reg[9],
+ stat->pr_reg[7], stat->pr_reg[6], stat->pr_reg[5],
+ stat->pr_reg[3], stat->pr_reg[2], stat->pr_reg[1],
+ stat->pr_reg[0], stat->pr_reg[16], stat->pr_reg[18],
+ stat->pr_reg[15], stat->pr_reg[17], stat->pr_reg[23],
+ stat->pr_reg[24], stat->pr_reg[20],
+ stat->pr_reg[25], stat->pr_reg[21],
+ stat->pr_reg[26], stat->pr_reg[22]);
+
+ /* We handled this entry. */
+ result = true;
+ break;
+
+ case NT_PRPSINFO:
+ if (descsz < sizeof (struct elf_prpsinfo))
+ /* Not enough data. */
+ break;
+
+ struct elf_prpsinfo *info = (struct elf_prpsinfo *) desc;
+
+ printf (" state: %c (%hhd), zombie: %hhd, nice: %hhd\n"
+ " flags: %08" PRIx64 " uid: %" PRIu32 " gid: %" PRIu32 "\n"
+ " pid: %" PRId32 " ppid: %" PRId32 " pgrp: %" PRId32
+ " sid: %" PRId32 "\n"
+ " fname: %.16s\n"
+ " args: %.80s\n\n",
+ info->pr_sname, info->pr_state, info->pr_zomb, info->pr_nice,
+ info->pr_flag, info->pr_uid, info->pr_gid,
+ info->pr_pid, info->pr_ppid, info->pr_pgrp, info->pr_sid,
+ info->pr_fname, info->pr_psargs);
+
+ /* We handled this entry. */
+ result = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return result;
+}
diff --git a/backends/x86_64_init.c b/backends/x86_64_init.c
new file mode 100644
index 00000000..22147a1f
--- /dev/null
+++ b/backends/x86_64_init.c
@@ -0,0 +1,47 @@
+/* Initialization of x86-64 specific backend library.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2002.
+
+ 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
+
+#define BACKEND x86_64_
+#define RELOC_PREFIX R_X86_64_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on x86_64_reloc.def. */
+#include "common-reloc.c"
+
+
+
+const char *
+x86_64_init (elf, machine, eh, ehlen)
+ Elf *elf __attribute__ ((unused));
+ GElf_Half machine __attribute__ ((unused));
+ Ebl *eh;
+ size_t ehlen;
+{
+ /* Check whether the Elf_BH object has a sufficent size. */
+ if (ehlen < sizeof (Ebl))
+ return NULL;
+
+ /* We handle it. */
+ eh->name = "AMD x86-64";
+ 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_reloc.def b/backends/x86_64_reloc.def
new file mode 100644
index 00000000..83a18280
--- /dev/null
+++ b/backends/x86_64_reloc.def
@@ -0,0 +1,39 @@
+/* List the relocation types for x86-64. -*- C -*-
+ Copyright (C) 2000, 2001, 2002, 2003, 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. */
+
+/* NAME, REL|EXEC|DYN */
+
+RELOC_TYPE (NONE, 0)
+RELOC_TYPE (64, REL|EXEC|DYN)
+RELOC_TYPE (PC32, REL|EXEC|DYN)
+RELOC_TYPE (GOT32, REL)
+RELOC_TYPE (PLT32, REL)
+RELOC_TYPE (COPY, EXEC)
+RELOC_TYPE (GLOB_DAT, EXEC|DYN)
+RELOC_TYPE (JUMP_SLOT, EXEC|DYN)
+RELOC_TYPE (RELATIVE, EXEC|DYN)
+RELOC_TYPE (GOTPCREL, REL)
+RELOC_TYPE (32, REL|EXEC|DYN)
+RELOC_TYPE (32S, REL)
+RELOC_TYPE (16, REL)
+RELOC_TYPE (PC16, REL)
+RELOC_TYPE (8, REL)
+RELOC_TYPE (PC8, REL)
+RELOC_TYPE (DTPMOD64, EXEC|DYN)
+RELOC_TYPE (DTPOFF64, EXEC|DYN)
+RELOC_TYPE (TPOFF64, EXEC|DYN)
+RELOC_TYPE (TLSGD, REL)
+RELOC_TYPE (TLSLD, REL)
+RELOC_TYPE (DTPOFF32, REL)
+RELOC_TYPE (GOTTPOFF, REL)
+RELOC_TYPE (TPOFF32, REL)
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/backends/x86_64_symbol.c b/backends/x86_64_symbol.c
new file mode 100644
index 00000000..c48af103
--- /dev/null
+++ b/backends/x86_64_symbol.c
@@ -0,0 +1,45 @@
+/* x86_64 specific symbolic name handling.
+ Copyright (C) 2002, 2005 Red Hat, Inc.
+ Written by Ulrich Drepper <[email protected]>, 2002.
+
+ 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 <elf.h>
+#include <stddef.h>
+
+#define BACKEND x86_64_
+#include "libebl_CPU.h"
+
+/* Check for the simple reloc types. */
+Elf_Type
+x86_64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+ switch (type)
+ {
+ case R_X86_64_64:
+ return ELF_T_XWORD;
+ case R_X86_64_32:
+ return ELF_T_WORD;
+ case R_X86_64_32S:
+ return ELF_T_SWORD;
+ case R_X86_64_16:
+ return ELF_T_HALF;
+ case R_X86_64_8:
+ return ELF_T_BYTE;
+ default:
+ return ELF_T_NUM;
+ }
+}