Revamp libebl/common-reloc.c code to share source at compile time only and not extend the libebl.a behavior itself.
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
index d524829..f8e16eb 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,3 +1,160 @@
+2005-11-14  Roland McGrath  <roland@redhat.com>
+
+	* ia64_init.c (ia64_init): Initialize EH->reloc_simple_type.
+	* sh_init.c (sh_init): Likewise.
+	* x86_64_init.c (x86_64_init): Likewise.
+
+	* sparc_symbol.c (sparc_reloc_simple_type): New function.
+	* sparc_init.c (sparc_init): Use it.
+
+	* arm_symbol.c (arm_reloc_simple_type): New function.
+	* arm_init.c (arm_init): Use it.
+
+	* alpha_symbol.c (alpha_reloc_simple_type): New function.
+	* alpha_init.c (alpha_init): Use it.
+
+	* ia64_reloc.def: Update bits per H. J. Lu <hjl@lucon.org>.
+
+	* arm_reloc.def: Update bits per Daniel Jacobowitz <drow@false.org>.
+
+	* alpha_reloc.def: Update bits per Richard Henderson <rth@redhat.com>.
+
+2005-11-10  Roland McGrath  <roland@redhat.com>
+
+	* s390_init.c: New file.
+	* s390_reloc.def: New file.
+	* s390_symbol.c: New file.
+	* Makefile.am (modules, libebl_pic): Add s390.
+	(s390_SRCS, libebl_s390_pic_a_SOURCES): New variables.
+	(am_libebl_s390_pic_a_OBJECTS): New variable.
+
+	* ppc64_init.c: Use common-reloc.c.
+	* ppc64_symbol.c (ppc64_backend_name): Removed.
+	(ppc64_reloc_type_check, ppc64_reloc_type_name): Likewise.
+	(ppc64_copy_reloc_p, ppc64_reloc_valid_use): Likewise.
+
+	* ppc_init.c: Use common-reloc.c.
+	* ppc_symbol.c (ppc_backend_name): Removed.
+	(ppc_reloc_type_name, ppc_reloc_type_check): Likewise.
+	(ppc_reloc_valid_use, ppc_copy_reloc_p): Likewise.
+
+	* sparc_init.c: Use common-reloc.c.
+	* sparc_symbol.c (sparc_backend_name): Removed.
+	(sparc_reloc_type_name, sparc_reloc_type_check): Likewise.
+	(sparc_copy_reloc_p): Likewise.
+
+	* arm_init.c: Use common-reloc.c.
+	* arm_symbol.c (arm_backend_name): Removed.
+	(arm_reloc_type_name, arm_reloc_type_check, arm_copy_reloc_p): Removed.
+
+	* alpha_init.c: Use common-reloc.c.
+	* alpha_symbol.c (alpha_backend_name): Removed.
+	(alpha_reloc_type_name, alpha_reloc_type_check): Likewise.
+	(alpha_copy_reloc_p): Likewise.
+
+	* ia64_symbol.c (ia64_backend_name): Removed.
+	(ia64_reloc_type_name, ia64_reloc_type_check): Likewise.
+	(ia64_copy_reloc_p): Likewise.
+
+	* x86_64_init.c: Use common-reloc.c.
+	* x86_64_symbol.c (x86_64_backend_name): Removed.
+	(x86_64_copy_reloc_p, x86_64_reloc_valid_use): Likewise.
+	(x86_64_reloc_type_check, x86_64_reloc_type_name): Likewise.
+
+	* sh_init.c: Use common-reloc.c.
+	* sh_symbol.c: All functions removed.
+	(sh_reloc_simple_type): New function.
+	(sh_gotpc_reloc_check): New function.
+
+	* common-reloc.c: New file.
+	* Makefile.am (noinst_HEADERS): Add it.
+	* i386_init.c: Include it.
+
+	* sh_reloc.def: New file.
+	* i386_reloc.def: New file.
+	* alpha_reloc.def: New file.
+	* arm_reloc.def: New file.
+	* i386_reloc.def: New file.
+	* ia64_reloc.def: New file.
+	* ppc64_reloc.def: New file.
+	* ppc_reloc.def: New file.
+	* sh_reloc.def: New file.
+	* sparc_reloc.def: New file.
+	* x86_64_reloc.def: New file.
+	* Makefile.am (EXTRA_DIST): Add $(modules:=_reloc.def).
+
+	* libebl_alpha.map: Removed.
+	* libebl_ia64.map: Removed.
+	* libebl_ppc.map: Removed.
+	* libebl_sparc.map: Removed.
+	* libebl_arm.map: Removed.
+	* libebl_i386.map: Removed.
+	* libebl_ppc64.map: Removed.
+	* libebl_sh.map: Removed.
+	* libebl_x86_64.map: Removed.
+	* Makefile.am (EXTRA_DIST): Remove them.
+	(libebl_%.map, libebl_%.so): New pattern rules.
+
+	* libebl_alpha.h: Removed.
+	* libebl_ia64.h: Removed.
+	* libebl_ppc.h: Removed.
+	* libebl_sparc.h: Removed.
+	* libebl_arm.h: Removed.
+	* libebl_i386.h: Removed.
+	* libebl_ppc64.h: Removed.
+	* libebl_sh.h: Removed.
+	* libebl_x86_64.h: Removed.
+	* Makefile.am (noinst_HEADERS): Remove them.
+
+	* x86_64_corenote.c: Use libebl_CPU.h instead.
+	* x86_64_symbol.c: Likewise.
+	* i386_corenote.c: Likewise.
+
+2005-11-09  Roland McGrath  <roland@redhat.com>
+
+	* ia64_symbol.c (ia64_reloc_simple_type): New function.
+
+	* ebl-hooks.h (reloc_simple_type): Take the Ebl handle, not Elf handle.
+	* eblrelocsimpletype.c (ebl_reloc_simple_type): Update caller.
+	* eblopenbackend.c (default_reloc_simple_type): Update signature.
+	* i386_symbol.c (i386_reloc_simple_type): Likewise.
+	* ppc64_symbol.c (ppc64_reloc_simple_type): Likewise.
+	* ppc_symbol.c (ppc_reloc_simple_type): Likewise.
+	* x86_64_symbol.c (x86_64_reloc_simple_type): Likewise.
+
+	* i386_symbol.c (i386_backend_name): Removed.
+	(i386_reloc_type_name, i386_reloc_type_check): Likewise.
+	(i386_reloc_valid_use): Removed.
+	(i386_copy_reloc_p): Removed.
+
+	* alpha_destr.c: Removed.
+	* arm_destr.c: Removed.
+	* i386_destr.c: Removed.
+	* ia64_destr.c: Removed.
+	* ppc64_destr.c: Removed.
+	* ppc_destr.c: Removed.
+	* sh_destr.c: Removed.
+	* sparc_destr.c: Removed.
+	* x86_64_destr.c: Removed.
+
+	* ebl-hooks.h: New file, broken out of ...
+	* libeblP.h (struct ebl): ... here.  #include that for hook
+	declarations, after defining EBLHOOK macro.
+	* libebl_CPU.h: New file.
+	* Makefile.am (noinst_HEADERS): Add them.
+
+	* libeblP.h (struct ebl): Use uint_fast16_t for machine,
+	and uint_fast8_t for class and data.
+
+2005-08-14  Roland McGrath  <roland@redhat.com>
+
+	* ia64_symbol.c (ia64_section_type_name): New function.
+	(ia64_dynamic_tag_check): New function.
+	(ia64_reloc_valid_use): New function.
+	* libebl_ia64.h: Declare them.
+	* ia64_init.c (ia64_init): Use them.
+	* Makefile.am (libebl_ia64.so): Link with libelf.
+
 2005-08-28  Ulrich Drepper  <drepper@redhat.com>
 
 	* Makefile.am: Use $(LINK) not $(CC) when creating DSOs.
diff --git a/libebl/Makefile.am b/libebl/Makefile.am
index 93271e5..51b97ff 100644
--- a/libebl/Makefile.am
+++ b/libebl/Makefile.am
@@ -27,15 +27,15 @@
 LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
 
 lib_LIBRARIES = libebl.a
-modules = i386 sh x86_64 ia64 alpha arm sparc ppc ppc64
-noinst_LIBRARIES = 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
-noinst_PROGRAMS = $(noinst_LIBRARIES:_pic.a=.so)
+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)
 
-euincludedir = $(includedir)/elfutils
-euinclude_HEADERS = libebl.h
+pkginclude_HEADERS = libebl.h
 
 gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \
 	      eblreloctypename.c eblsegmenttypename.c \
@@ -53,7 +53,7 @@
 
 libebl_a_SOURCES = $(gen_SOURCES)
 
-i386_SRCS = i386_init.c i386_destr.c i386_symbol.c i386_corenote.c
+i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c
 libebl_i386_pic_a_SOURCES = $(i386_SRCS)
 am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os)
 
@@ -67,108 +67,50 @@
 
 textrel_check = if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi
 
-libebl_i386_so_SOURCES =
-libebl_i386.so: libebl_i386_pic.a libebl_i386.map
+libebl_%.so: libebl_%_pic.a libebl_%.map
 	$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-		-Wl,--version-script,$(srcdir)/libebl_i386.map \
+		-Wl,--version-script,$(word 2,$^) \
 		-Wl,-z,defs $(libelf) $(libmudflap)
 	$(textrel_check)
 
+libebl_%.map: Makefile
+	echo 'ELFUTILS_$(PACKAGE_VERSION) { global: $*_init; local: *; };' > $@
 
-sh_SRCS = sh_init.c sh_destr.c sh_symbol.c
+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)
 
-libebl_sh_so_SOURCES =
-libebl_sh.so: libebl_sh_pic.a libebl_sh.map
-	$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-		-Wl,--version-script,$(srcdir)/libebl_sh.map \
-		-Wl,-z,defs $(libmudflap)
-	$(textrel_check)
-
-
-x86_64_SRCS = x86_64_init.c x86_64_destr.c x86_64_symbol.c x86_64_corenote.c
+x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c
 libebl_x86_64_pic_a_SOURCES = $(x86_64_SRCS)
 am_libebl_x86_64_pic_a_OBJECTS = $(x86_64_SRCS:.c=.os)
 
-libebl_x86_64_so_SOURCES =
-libebl_x86_64.so: libebl_x86_64_pic.a libebl_x86_64.map
-	$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-		-Wl,--version-script,$(srcdir)/libebl_x86_64.map \
-		-Wl,-z,defs $(libelf) $(libmudflap)
-	$(textrel_check)
-
-
-ia64_SRCS = ia64_init.c ia64_destr.c ia64_symbol.c
+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)
 
-libebl_ia64_so_SOURCES =
-libebl_ia64.so: libebl_ia64_pic.a libebl_ia64.map
-	$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-		-Wl,--version-script,$(srcdir)/libebl_ia64.map \
-		-Wl,-z,defs $(libmudflap)
-	$(textrel_check)
-
-
-alpha_SRCS = alpha_init.c alpha_destr.c alpha_symbol.c
+alpha_SRCS = alpha_init.c alpha_symbol.c
 libebl_alpha_pic_a_SOURCES = $(alpha_SRCS)
 am_libebl_alpha_pic_a_OBJECTS = $(alpha_SRCS:.c=.os)
 
-libebl_alpha_so_SOURCES =
-libebl_alpha.so: libebl_alpha_pic.a libebl_alpha.map
-	$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-		-Wl,--version-script,$(srcdir)/libebl_alpha.map \
-		-Wl,-z,defs $(libmudflap)
-	$(textrel_check)
-
-
-arm_SRCS = arm_init.c arm_destr.c arm_symbol.c
+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)
 
-libebl_arm_so_SOURCES =
-libebl_arm.so: libebl_arm_pic.a libebl_arm.map
-	$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-		-Wl,--version-script,$(srcdir)/libebl_arm.map \
-		-Wl,-z,defs $(libmudflap)
-	$(textrel_check)
-
-
-sparc_SRCS = sparc_init.c sparc_destr.c sparc_symbol.c
+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)
 
-libebl_sparc_so_SOURCES =
-libebl_sparc.so: libebl_sparc_pic.a libebl_sparc.map
-	$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-		-Wl,--version-script,$(srcdir)/libebl_sparc.map \
-		-Wl,-z,defs $(libmudflap)
-	$(textrel_check)
-
-
-ppc_SRCS = ppc_init.c ppc_destr.c ppc_symbol.c
+ppc_SRCS = ppc_init.c ppc_symbol.c
 libebl_ppc_pic_a_SOURCES = $(ppc_SRCS)
 am_libebl_ppc_pic_a_OBJECTS = $(ppc_SRCS:.c=.os)
 
-libebl_ppc_so_SOURCES =
-libebl_ppc.so: libebl_ppc_pic.a libebl_ppc.map
-	$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-		-Wl,--version-script,$(srcdir)/libebl_ppc.map \
-		-Wl,-z,defs $(libelf) $(libmudflap)
-	$(textrel_check)
-
-
-ppc64_SRCS = ppc64_init.c ppc64_destr.c ppc64_symbol.c
+ppc64_SRCS = ppc64_init.c ppc64_symbol.c
 libebl_ppc64_pic_a_SOURCES = $(ppc64_SRCS)
 am_libebl_ppc64_pic_a_OBJECTS = $(ppc64_SRCS:.c=.os)
 
-libebl_ppc64_so_SOURCES =
-libebl_ppc64.so: libebl_ppc64_pic.a libebl_ppc64.map
-	$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-		-Wl,--version-script,$(srcdir)/libebl_ppc64.map \
-		-Wl,-z,defs $(libelf) $(libmudflap)
-	$(textrel_check)
+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
@@ -193,11 +135,10 @@
 	  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)$(includedir)/elfutils
+	rmdir --ignore-fail-on-non-empty $(DESTDIR)$(pkgincludedir)
 
-noinst_HEADERS = libeblP.h $(noinst_LIBRARIES:%_pic.a=%.h)
-EXTRA_DIST = $(noinst_LIBRARIES:%_pic.a=%.map) \
-	     $(foreach m,$(modules),$($(m)_SRCS))
+noinst_HEADERS = libeblP.h ebl-hooks.h libebl_CPU.h common-reloc.c
+EXTRA_DIST = $(foreach m,$(modules),$($(m)_SRCS)) $(modules:=_reloc.def)
 
 CLEANFILES = $(am_libebl_pic_a_OBJECTS) *.gcno *.gcda \
 	     $(foreach m,$(modules),$(am_libebl_$(m)_pic_a_OBJECTS))
diff --git a/libebl/alpha_destr.c b/libebl/alpha_destr.c
deleted file mode 100644
index 4fc5cf8..0000000
--- a/libebl/alpha_destr.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Destructor for Alpha specific backend library.
-   Copyright (C) 2002, 2005 Red Hat, Inc.
-   Written by Ulrich Drepper <drepper@redhat.com>, 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 <libebl_alpha.h>
-
-
-void
-alpha_destr (bh)
-     Ebl *bh __attribute__ ((unused));
-{
-  /* Nothing to do so far.  */
-}
diff --git a/libebl/alpha_init.c b/libebl/alpha_init.c
index 327f3bd..1ef87d6 100644
--- a/libebl/alpha_init.c
+++ b/libebl/alpha_init.c
@@ -16,7 +16,12 @@
 # include <config.h>
 #endif
 
-#include <libebl_alpha.h>
+#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 *
@@ -32,12 +37,10 @@
 
   /* We handle it.  */
   eh->name = "Alpha";
-  eh->reloc_type_name = alpha_reloc_type_name;
-  eh->reloc_type_check = alpha_reloc_type_check;
+  alpha_init_reloc (eh);
   eh->dynamic_tag_name = alpha_dynamic_tag_name;
   eh->dynamic_tag_check = alpha_dynamic_tag_check;
-  eh->copy_reloc_p = alpha_copy_reloc_p;
-  eh->destr = alpha_destr;
+  eh->reloc_simple_type = alpha_reloc_simple_type;
 
   return MODVERSION;
 }
diff --git a/libebl/alpha_reloc.def b/libebl/alpha_reloc.def
new file mode 100644
index 0000000..488f448
--- /dev/null
+++ b/libebl/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/libebl/alpha_symbol.c b/libebl/alpha_symbol.c
index 3fcd184..b2e4cf7 100644
--- a/libebl/alpha_symbol.c
+++ b/libebl/alpha_symbol.c
@@ -19,79 +19,8 @@
 #include <elf.h>
 #include <stddef.h>
 
-#include <libebl_alpha.h>
-
-
-/* Return of the backend.  */
-const char *
-alpha_backend_name (void)
-{
-  return "alpha";
-}
-
-
-/* Relocation mapping table.  */
-static const char *reloc_map_table[] =
-  {
-    [R_ALPHA_NONE] = "R_ALPHA_NONE",
-    [R_ALPHA_REFLONG] = "R_ALPHA_REFLONG",
-    [R_ALPHA_REFQUAD] = "R_ALPHA_REFQUAD",
-    [R_ALPHA_GPREL32] = "R_ALPHA_GPREL32",
-    [R_ALPHA_LITERAL] = "R_ALPHA_LITERAL",
-    [R_ALPHA_LITUSE] = "R_ALPHA_LITUSE",
-    [R_ALPHA_GPDISP] = "R_ALPHA_GPDISP",
-    [R_ALPHA_BRADDR] = "R_ALPHA_BRADDR",
-    [R_ALPHA_HINT] = "R_ALPHA_HINT",
-    [R_ALPHA_SREL16] = "R_ALPHA_SREL16",
-    [R_ALPHA_SREL32] = "R_ALPHA_SREL32",
-    [R_ALPHA_SREL64] = "R_ALPHA_SREL64",
-    [R_ALPHA_GPRELHIGH] = "R_ALPHA_GPRELHIGH",
-    [R_ALPHA_GPRELLOW] = "R_ALPHA_GPRELLOW",
-    [R_ALPHA_GPREL16] = "R_ALPHA_GPREL16",
-    [R_ALPHA_COPY] = "R_ALPHA_COPY",
-    [R_ALPHA_GLOB_DAT] = "R_ALPHA_GLOB_DAT",
-    [R_ALPHA_JMP_SLOT] = "R_ALPHA_JMP_SLOT",
-    [R_ALPHA_RELATIVE] = "R_ALPHA_RELATIVE",
-    [R_ALPHA_TLS_GD_HI] = "R_ALPHA_TLS_GD_HI",
-    [R_ALPHA_TLSGD] = "R_ALPHA_TLSGD",
-    [R_ALPHA_TLS_LDM] = "R_ALPHA_TLS_LDM",
-    [R_ALPHA_DTPMOD64] = "R_ALPHA_DTPMOD64",
-    [R_ALPHA_GOTDTPREL] = "R_ALPHA_GOTDTPREL",
-    [R_ALPHA_DTPREL64] = "R_ALPHA_DTPREL64",
-    [R_ALPHA_DTPRELHI] = "R_ALPHA_DTPRELHI",
-    [R_ALPHA_DTPRELLO] = "R_ALPHA_DTPRELLO",
-    [R_ALPHA_DTPREL16] = "R_ALPHA_DTPREL16",
-    [R_ALPHA_GOTTPREL] = "R_ALPHA_GOTTPREL",
-    [R_ALPHA_TPREL64] = "R_ALPHA_TPREL64",
-    [R_ALPHA_TPRELHI] = "R_ALPHA_TPRELHI",
-    [R_ALPHA_TPRELLO] = "R_ALPHA_TPRELLO",
-    [R_ALPHA_TPREL16] = "R_ALPHA_TPREL16"
-  };
-
-
-/* Determine relocation type string for Alpha.  */
-const char *
-alpha_reloc_type_name (int type, char *buf __attribute__ ((unused)),
-		       size_t len __attribute__ ((unused)))
-{
-  if (type < 0
-      || ((size_t) type
-	  >= sizeof (reloc_map_table) / sizeof (reloc_map_table[0])))
-    return NULL;
-
-  return reloc_map_table[type];
-}
-
-
-/* Check for correct relocation type.  */
-bool
-alpha_reloc_type_check (int type)
-{
-  return (type >= R_ALPHA_NONE
-	  && ((size_t) type
-	      < sizeof (reloc_map_table) / sizeof (reloc_map_table[0]))
-	  && reloc_map_table[type] != NULL) ? true : false;
-}
+#define BACKEND		alpha_
+#include "libebl_CPU.h"
 
 
 const char *
@@ -108,17 +37,23 @@
   return NULL;
 }
 
-
 bool
 alpha_dynamic_tag_check (int64_t tag)
 {
   return tag == DT_ALPHA_PLTRO;
 }
 
-
-/* Check whether given relocation is a copy relocation.  */
-bool
-alpha_copy_reloc_p (int reloc)
+/* Check for the simple reloc types.  */
+Elf_Type
+alpha_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
 {
-  return reloc == R_ALPHA_COPY;
+  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/libebl/arm_destr.c b/libebl/arm_destr.c
deleted file mode 100644
index 2675720..0000000
--- a/libebl/arm_destr.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Destructor for Arm specific backend library.
-   Copyright (C) 2002, 2005 Red Hat, Inc.
-   Written by Ulrich Drepper <drepper@redhat.com>, 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 <libebl_arm.h>
-
-
-void
-arm_destr (bh)
-     Ebl *bh __attribute__ ((unused));
-{
-  /* Nothing to do so far.  */
-}
diff --git a/libebl/arm_init.c b/libebl/arm_init.c
index a0a65f8..ee73907 100644
--- a/libebl/arm_init.c
+++ b/libebl/arm_init.c
@@ -16,7 +16,12 @@
 # include <config.h>
 #endif
 
-#include <libebl_arm.h>
+#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 *
@@ -31,11 +36,9 @@
     return NULL;
 
   /* We handle it.  */
-  eh->name = "Arm";
-  eh->reloc_type_name = arm_reloc_type_name;
-  eh->reloc_type_check = arm_reloc_type_check;
-  eh->copy_reloc_p = arm_copy_reloc_p;
-  eh->destr = arm_destr;
+  eh->name = "ARM";
+  arm_init_reloc (eh);
+  eh->reloc_simple_type = arm_reloc_simple_type;
 
   return MODVERSION;
 }
diff --git a/libebl/arm_reloc.def b/libebl/arm_reloc.def
new file mode 100644
index 0000000..b76be77
--- /dev/null
+++ b/libebl/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/libebl/arm_symbol.c b/libebl/arm_symbol.c
index f4de8be..6eb40fc 100644
--- a/libebl/arm_symbol.c
+++ b/libebl/arm_symbol.c
@@ -19,103 +19,22 @@
 #include <elf.h>
 #include <stddef.h>
 
-#include <libebl_arm.h>
+#define BACKEND		arm_
+#include "libebl_CPU.h"
 
-
-/* Return of the backend.  */
-const char *
-arm_backend_name (void)
+/* Check for the simple reloc types.  */
+Elf_Type
+arm_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
 {
-  return "arm";
-}
-
-
-/* Relocation mapping table.  */
-static const char *reloc_map_table[] =
-  {
-    [R_ARM_NONE] = "R_ARM_NONE",
-    [R_ARM_PC24] = "R_ARM_PC24",
-    [R_ARM_ABS32] = "R_ARM_ABS32",
-    [R_ARM_REL32] = "R_ARM_REL32",
-    [R_ARM_PC13] = "R_ARM_PC13",
-    [R_ARM_ABS16] = "R_ARM_ABS16",
-    [R_ARM_ABS12] = "R_ARM_ABS12",
-    [R_ARM_THM_ABS5] = "R_ARM_THM_ABS5",
-    [R_ARM_ABS8] = "R_ARM_ABS8",
-    [R_ARM_SBREL32] = "R_ARM_SBREL32",
-    [R_ARM_THM_PC22] = "R_ARM_THM_PC22",
-    [R_ARM_THM_PC8] = "R_ARM_THM_PC8",
-    [R_ARM_AMP_VCALL9] = "R_ARM_AMP_VCALL9",
-    [R_ARM_SWI24] = "R_ARM_SWI24",
-    [R_ARM_THM_SWI8] = "R_ARM_THM_SWI8",
-    [R_ARM_XPC25] = "R_ARM_XPC25",
-    [R_ARM_THM_XPC22] = "R_ARM_THM_XPC22",
-    [R_ARM_COPY] = "R_ARM_COPY",
-    [R_ARM_GLOB_DAT] = "R_ARM_GLOB_DAT",
-    [R_ARM_JUMP_SLOT] = "R_ARM_JUMP_SLOT",
-    [R_ARM_RELATIVE] = "R_ARM_RELATIVE",
-    [R_ARM_GOTOFF] = "R_ARM_GOTOFF",
-    [R_ARM_GOTPC] = "R_ARM_GOTPC",
-    [R_ARM_GOT32] = "R_ARM_GOT32",
-    [R_ARM_PLT32] = "R_ARM_PLT32",
-    [R_ARM_ALU_PCREL_7_0] = "R_ARM_ALU_PCREL_7_0",
-    [R_ARM_ALU_PCREL_15_8] = "R_ARM_ALU_PCREL_15_8",
-    [R_ARM_ALU_PCREL_23_15] = "R_ARM_ALU_PCREL_23_15",
-    [R_ARM_LDR_SBREL_11_0] = "R_ARM_LDR_SBREL_11_0",
-    [R_ARM_ALU_SBREL_19_12] = "R_ARM_ALU_SBREL_19_12",
-    [R_ARM_ALU_SBREL_27_20] = "R_ARM_ALU_SBREL_27_20"
-  };
-
-static const char *reloc_map_table2[] =
-  {
-    [R_ARM_GNU_VTENTRY] = "R_ARM_GNU_VTENTRY",
-    [R_ARM_GNU_VTINHERIT] = "R_ARM_GNU_VTINHERIT",
-    [R_ARM_THM_PC11] = "R_ARM_THM_PC11",
-    [R_ARM_THM_PC9] = "R_ARM_THM_PC9"
-  };
-
-static const char *reloc_map_table3[] =
-  {
-    [R_ARM_RXPC25] = "R_ARM_RXPC25",
-    [R_ARM_RSBREL32] = "R_ARM_RSBREL32",
-    [R_ARM_THM_RPC22] = "R_ARM_THM_RPC22",
-    [R_ARM_RREL32] = "R_ARM_RREL32",
-    [R_ARM_RABS22] = "R_ARM_RABS22",
-    [R_ARM_RPC24] = "R_ARM_RPC24",
-    [R_ARM_RBASE] = "R_ARM_RBASE"
-  };
-
-
-/* Determine relocation type string for Alpha.  */
-const char *
-arm_reloc_type_name (int type, char *buf __attribute__ ((unused)),
-		     size_t len __attribute__ ((unused)))
-{
-  if (type >= R_ARM_NONE && type <= R_ARM_ALU_SBREL_27_20)
-    return reloc_map_table[type];
-
-  if (type >= R_ARM_GNU_VTENTRY && type <= R_ARM_THM_PC9)
-    return reloc_map_table2[type - R_ARM_GNU_VTENTRY];
-
-  if (type >= R_ARM_RXPC25 && type <= R_ARM_RBASE)
-    return reloc_map_table3[type - R_ARM_RXPC25];
-
-  return NULL;
-}
-
-
-/* Check for correct relocation type.  */
-bool
-arm_reloc_type_check (int type)
-{
-  return ((type >= R_ARM_NONE && type <= R_ARM_ALU_SBREL_27_20)
-	  || (type >= R_ARM_GNU_VTENTRY && type <= R_ARM_THM_PC9)
-	  || (type >= R_ARM_RXPC25 && type <= R_ARM_RBASE)) ? true : false;
-}
-
-/* Check whether given relocation is a copy relocation.  */
-bool
-arm_copy_reloc_p (int reloc)
-{
-  return reloc == R_ARM_COPY;
+  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/libebl/common-reloc.c b/libebl/common-reloc.c
new file mode 100644
index 0000000..0575e13
--- /dev/null
+++ b/libebl/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/libebl/ebl-hooks.h b/libebl/ebl-hooks.h
new file mode 100644
index 0000000..1056c42
--- /dev/null
+++ b/libebl/ebl-hooks.h
@@ -0,0 +1,91 @@
+/* Backend hook signatures internal interface for libebl.
+   Copyright (C) 2000, 2001, 2002, 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.   */
+
+/* Return symbol representaton of object file type.  */
+const char *EBLHOOK(object_type_name) (int, char *, size_t);
+
+/* Return symbolic representation of relocation type.  */
+const char *EBLHOOK(reloc_type_name) (int, char *, size_t);
+
+/* Check relocation type.  */
+bool EBLHOOK(reloc_type_check) (int);
+
+/* Check if relocation type is for simple absolute relocations.  */
+Elf_Type EBLHOOK(reloc_simple_type) (Ebl *, int);
+
+/* Check relocation type use.  */
+bool EBLHOOK(reloc_valid_use) (Elf *, int);
+
+/* Return true if the symbol type is that referencing the GOT.  */
+bool EBLHOOK(gotpc_reloc_check) (Elf *, int);
+
+/* Return symbolic representation of segment type.  */
+const char *EBLHOOK(segment_type_name) (int, char *, size_t);
+
+/* Return symbolic representation of section type.  */
+const char *EBLHOOK(section_type_name) (int, char *, size_t);
+
+/* Return section name.  */
+const char *EBLHOOK(section_name) (int, int, char *, size_t);
+
+/* Return next machine flag name.  */
+const char *EBLHOOK(machine_flag_name) (GElf_Word *);
+
+/* Check whether machine flags are valid.  */
+bool EBLHOOK(machine_flag_check) (GElf_Word);
+
+/* Return symbolic representation of symbol type.  */
+const char *EBLHOOK(symbol_type_name) (int, char *, size_t);
+
+/* Return symbolic representation of symbol binding.  */
+const char *EBLHOOK(symbol_binding_name) (int, char *, size_t);
+
+/* Return symbolic representation of dynamic tag.  */
+const char *EBLHOOK(dynamic_tag_name) (int64_t, char *, size_t);
+
+/* Check dynamic tag.  */
+bool EBLHOOK(dynamic_tag_check) (int64_t);
+
+/* Combine section header flags values.  */
+GElf_Word EBLHOOK(sh_flags_combine) (GElf_Word, GElf_Word);
+
+/* Return symbolic representation of OS ABI.  */
+const char *EBLHOOK(osabi_name) (int, char *, size_t);
+
+/* Name of a note entry type for core files.  */
+const char *EBLHOOK(core_note_type_name) (uint32_t, char *, size_t);
+
+/* Name of a note entry type for object files.  */
+const char *EBLHOOK(object_note_type_name) (uint32_t, char *, size_t);
+
+/* Handle core note.  */
+bool EBLHOOK(core_note) (const char *, uint32_t, uint32_t, const char *);
+
+/* Handle object file note.  */
+bool EBLHOOK(object_note) (const char *, uint32_t, uint32_t, const char *);
+
+/* Check section name for being that of a debug informatino section.  */
+bool EBLHOOK(debugscn_p) (const char *);
+
+/* Check whether given relocation is a copy relocation.  */
+bool EBLHOOK(copy_reloc_p) (int);
+
+/* Check whether given symbol's value is ok despite normal checks.  */
+bool EBLHOOK(check_special_symbol) (Elf *, GElf_Ehdr *, const GElf_Sym *,
+			      const char *, const GElf_Shdr *);
+
+/* Check if backend uses a bss PLT in this file.  */
+bool EBLHOOK(bss_plt_p) (Elf *, GElf_Ehdr *);
+
+/* Destructor for ELF backend handle.  */
+void EBLHOOK(destr) (struct ebl *);
diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c
index aef289c..9afbc88 100644
--- a/libebl/eblopenbackend.c
+++ b/libebl/eblopenbackend.c
@@ -123,7 +123,7 @@
 static const char *default_reloc_type_name (int ignore, char *buf, size_t len);
 static bool default_reloc_type_check (int ignore);
 static bool default_reloc_valid_use (Elf *elf, int ignore);
-static Elf_Type default_reloc_simple_type (Elf *elf, int ignore);
+static Elf_Type default_reloc_simple_type (Ebl *ebl, int ignore);
 static bool default_gotpc_reloc_check (Elf *elf, int ignore);
 static const char *default_segment_type_name (int ignore, char *buf,
 					      size_t len);
@@ -381,7 +381,7 @@
 }
 
 static Elf_Type
-default_reloc_simple_type (Elf *elf __attribute__ ((unused)),
+default_reloc_simple_type (Ebl *eh __attribute__ ((unused)),
 			   int ignore __attribute__ ((unused)))
 {
   return ELF_T_NUM;
diff --git a/libebl/eblrelocsimpletype.c b/libebl/eblrelocsimpletype.c
index 3e048d1..65b9b37 100644
--- a/libebl/eblrelocsimpletype.c
+++ b/libebl/eblrelocsimpletype.c
@@ -23,5 +23,5 @@
      Ebl *ebl;
      int reloc;
 {
-  return ebl != NULL ? ebl->reloc_simple_type (ebl->elf, reloc) : ELF_T_NUM;
+  return ebl != NULL ? ebl->reloc_simple_type (ebl, reloc) : ELF_T_NUM;
 }
diff --git a/libebl/i386_corenote.c b/libebl/i386_corenote.c
index 3a123e9..20750a9 100644
--- a/libebl/i386_corenote.c
+++ b/libebl/i386_corenote.c
@@ -22,7 +22,8 @@
 #include <stdio.h>
 #include <sys/time.h>
 
-#include <libebl_i386.h>
+#define BACKEND i386_
+#include "libebl_CPU.h"
 
 
 /* We cannot include <sys/procfs.h> since the definition would be for
diff --git a/libebl/i386_destr.c b/libebl/i386_destr.c
deleted file mode 100644
index 50c0fd4..0000000
--- a/libebl/i386_destr.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Destructor for i386 specific backend library.
-   Copyright (C) 2000, 2002, 2005 Red Hat, Inc.
-   Written by Ulrich Drepper <drepper@redhat.com>, 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 <libebl_i386.h>
-
-
-void
-i386_destr (bh)
-     Ebl *bh __attribute__ ((unused));
-{
-  /* Nothing to do so far.  */
-}
diff --git a/libebl/i386_init.c b/libebl/i386_init.c
index 264f3ef..477243f 100644
--- a/libebl/i386_init.c
+++ b/libebl/i386_init.c
@@ -16,8 +16,12 @@
 # include <config.h>
 #endif
 
-#include <libebl_i386.h>
+#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)
@@ -32,16 +36,12 @@
 
   /* We handle it.  */
   eh->name = "Intel 80386";
-  eh->reloc_type_name = i386_reloc_type_name;
-  eh->reloc_type_check = i386_reloc_type_check;
-  eh->reloc_valid_use = i386_reloc_valid_use;
+  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->copy_reloc_p = i386_copy_reloc_p;
-  eh->destr = i386_destr;
 
   return MODVERSION;
 }
diff --git a/libebl/i386_reloc.def b/libebl/i386_reloc.def
new file mode 100644
index 0000000..ba750d0
--- /dev/null
+++ b/libebl/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/libebl/i386_symbol.c b/libebl/i386_symbol.c
index e9eded2..dadcc10 100644
--- a/libebl/i386_symbol.c
+++ b/libebl/i386_symbol.c
@@ -21,104 +21,8 @@
 #include <stddef.h>
 #include <string.h>
 
-#include <libebl_i386.h>
-
-
-/* Return of the backend.  */
-const char *
-i386_backend_name (void)
-{
-  return "i386";
-}
-
-
-/* Relocation mapping table.  */
-static struct
-{
-  const char *name;
-  enum { both = 0, rel = 1, exec = 2 } appear;
-} reloc_map_table[] =
-  {
-    [R_386_NONE] = { "R_386_NONE", both },
-    [R_386_32] = { "R_386_32", both },
-    [R_386_PC32] = { "R_386_PC32", rel },
-    [R_386_GOT32] = { "R_386_GOT32", rel },
-    [R_386_PLT32] = { "R_386_PLT32", rel },
-    [R_386_COPY] = { "R_386_COPY", exec },
-    [R_386_GLOB_DAT] = { "R_386_GLOB_DAT", exec },
-    [R_386_JMP_SLOT] = { "R_386_JMP_SLOT", exec },
-    [R_386_RELATIVE] = { "R_386_RELATIVE", exec },
-    [R_386_GOTOFF] = { "R_386_GOTOFF", rel },
-    [R_386_GOTPC] = { "R_386_GOTPC", rel },
-    [R_386_32PLT] = { "R_386_32PLT", rel },
-    [R_386_TLS_TPOFF] = { "R_386_TLS_TPOFF", rel },
-    [R_386_TLS_IE] = { "R_386_TLS_IE", rel },
-    [R_386_TLS_GOTIE] = { "R_386_TLS_GOTIE", rel },
-    [R_386_TLS_LE] = { "R_386_TLS_LE", rel },
-    [R_386_TLS_GD] = { "R_386_TLS_GD", rel },
-    [R_386_TLS_LDM] = { "R_386_TLS_LDM", rel },
-    [R_386_16] = { "R_386_16", rel },
-    [R_386_PC16] = { "R_386_PC16", rel },
-    [R_386_8] = { "R_386_8", rel },
-    [R_386_PC8] = { "R_386_PC8", rel },
-    [R_386_TLS_GD_32] = { "R_386_TLS_GD_32", rel },
-    [R_386_TLS_GD_PUSH] = { "R_386_TLS_GD_PUSH", rel },
-    [R_386_TLS_GD_CALL] = { "R_386_TLS_GD_CALL", rel },
-    [R_386_TLS_GD_POP] = { "R_386_TLS_GD_POP", rel },
-    [R_386_TLS_LDM_32] = { "R_386_TLS_LDM_32", rel },
-    [R_386_TLS_LDM_PUSH] = { "R_386_TLS_LDM_PUSH", rel },
-    [R_386_TLS_LDM_CALL] = { "R_386_TLS_LDM_CALL", rel },
-    [R_386_TLS_LDM_POP] = { "R_386_TLS_LDM_POP", rel },
-    [R_386_TLS_LDO_32] = { "R_386_TLS_LDO_32", rel },
-    [R_386_TLS_IE_32] = { "R_386_TLS_IE_32", rel },
-    [R_386_TLS_LE_32] = { "R_386_TLS_LE_32", rel },
-    [R_386_TLS_DTPMOD32] = { "R_386_TLS_DTPMOD32", rel },
-    [R_386_TLS_DTPOFF32] = { "R_386_TLS_DTPOFF32", rel },
-    [R_386_TLS_TPOFF32] = { "R_386_TLS_TPOFF32", rel }
-  };
-
-
-/* Determine relocation type string for x86.  */
-const char *
-i386_reloc_type_name (int type, char *buf __attribute__ ((unused)),
-		      size_t len __attribute__ ((unused)))
-{
-  if (type < 0 || type >= R_386_NUM)
-    return NULL;
-
-  return reloc_map_table[type].name;
-}
-
-
-/* Check for correct relocation type.  */
-bool
-i386_reloc_type_check (int type)
-{
-  return (type >= R_386_NONE && type < R_386_NUM
-	  && reloc_map_table[type].name != NULL) ? true : false;
-}
-
-
-/* Check for correct relocation type use.  */
-bool
-i386_reloc_valid_use (Elf *elf, int type)
-{
-  if (type < R_386_NONE || type >= R_386_NUM
-      || reloc_map_table[type].name == NULL)
-    return false;
-
-  Elf32_Ehdr *ehdr = elf32_getehdr (elf);
-  assert (ehdr != NULL);
-
-  if (reloc_map_table[type].appear == rel)
-    return ehdr->e_type == ET_REL;
-
-  if (reloc_map_table[type].appear == exec)
-    return ehdr->e_type != ET_REL;
-
-  assert (reloc_map_table[type].appear == both);
-  return true;
-}
+#define BACKEND i386_
+#include "libebl_CPU.h"
 
 
 /* Return true if the symbol type is that referencing the GOT.  */
@@ -130,7 +34,7 @@
 
 /* Check for the simple reloc types.  */
 Elf_Type
-i386_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type)
+i386_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
 {
   switch (type)
     {
@@ -145,7 +49,7 @@
     }
 }
 
-/* Check section name for being that of a debug informatino section.  */
+/* Check section name for being that of a debug information section.  */
 bool (*generic_debugscn_p) (const char *);
 bool
 i386_debugscn_p (const char *name)
@@ -154,10 +58,3 @@
 	  || strcmp (name, ".stab") == 0
 	  || strcmp (name, ".stabstr") == 0);
 }
-
-/* Check whether given relocation is a copy relocation.  */
-bool
-i386_copy_reloc_p (int reloc)
-{
-  return reloc == R_386_COPY;
-}
diff --git a/libebl/ia64_destr.c b/libebl/ia64_destr.c
deleted file mode 100644
index cb105f6..0000000
--- a/libebl/ia64_destr.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Destructor for IA-64 specific backend library.
-   Copyright (C) 2002, 2005 Red Hat, Inc.
-   Written by Ulrich Drepper <drepper@redhat.com>, 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 <libebl_ia64.h>
-
-
-void
-ia64_destr (bh)
-     Ebl *bh __attribute__ ((unused));
-{
-  /* Nothing to do so far.  */
-}
diff --git a/libebl/ia64_init.c b/libebl/ia64_init.c
index f5c3f36..1431f2d 100644
--- a/libebl/ia64_init.c
+++ b/libebl/ia64_init.c
@@ -16,8 +16,12 @@
 # include <config.h>
 #endif
 
-#include <libebl_ia64.h>
+#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)
@@ -32,13 +36,13 @@
 
   /* We handle it.  */
   eh->name = "Intel IA-64";
-  eh->reloc_type_name = ia64_reloc_type_name;
-  eh->reloc_type_check = ia64_reloc_type_check;
+  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->copy_reloc_p = ia64_copy_reloc_p;
+  eh->dynamic_tag_check = ia64_dynamic_tag_check;
   eh->machine_flag_check = ia64_machine_flag_check;
-  eh->destr = ia64_destr;
 
   return MODVERSION;
 }
diff --git a/libebl/ia64_reloc.def b/libebl/ia64_reloc.def
new file mode 100644
index 0000000..a0d4215
--- /dev/null
+++ b/libebl/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/libebl/ia64_symbol.c b/libebl/ia64_symbol.c
index 2975285..1b50087 100644
--- a/libebl/ia64_symbol.c
+++ b/libebl/ia64_symbol.c
@@ -18,128 +18,10 @@
 
 #include <elf.h>
 #include <stddef.h>
+#include <assert.h>
 
-#include <libebl_ia64.h>
-
-
-/* Return of the backend.  */
-const char *
-ia64_backend_name (void)
-{
-  return "ia64";
-}
-
-
-/* Relocation mapping table.  */
-static const char *reloc_map_table[] =
-  {
-    [R_IA64_NONE] = "R_IA64_NONE",
-    [R_IA64_IMM14] = "R_IA64_IMM14",
-    [R_IA64_IMM22] = "R_IA64_IMM22",
-    [R_IA64_IMM64] = "R_IA64_IMM64",
-    [R_IA64_DIR32MSB] = "R_IA64_DIR32MSB",
-    [R_IA64_DIR32LSB] = "R_IA64_DIR32LSB",
-    [R_IA64_DIR64MSB] = "R_IA64_DIR64MSB",
-    [R_IA64_DIR64LSB] = "R_IA64_DIR64LSB",
-    [R_IA64_GPREL22] = "R_IA64_GPREL22",
-    [R_IA64_GPREL64I] = "R_IA64_GPREL64I",
-    [R_IA64_GPREL32MSB] = "R_IA64_GPREL32MSB",
-    [R_IA64_GPREL32LSB] = "R_IA64_GPREL32LSB",
-    [R_IA64_GPREL64MSB] = "R_IA64_GPREL64MSB",
-    [R_IA64_GPREL64LSB] = "R_IA64_GPREL64LSB",
-    [R_IA64_LTOFF22] = "R_IA64_LTOFF22",
-    [R_IA64_LTOFF64I] = "R_IA64_LTOFF64I",
-    [R_IA64_PLTOFF22] = "R_IA64_PLTOFF22",
-    [R_IA64_PLTOFF64I] = "R_IA64_PLTOFF64I",
-    [R_IA64_PLTOFF64MSB] = "R_IA64_PLTOFF64MSB",
-    [R_IA64_PLTOFF64LSB] = "R_IA64_PLTOFF64LSB",
-    [R_IA64_FPTR64I] = "R_IA64_FPTR64I",
-    [R_IA64_FPTR32MSB] = "R_IA64_FPTR32MSB",
-    [R_IA64_FPTR32LSB] = "R_IA64_FPTR32LSB",
-    [R_IA64_FPTR64MSB] = "R_IA64_FPTR64MSB",
-    [R_IA64_FPTR64LSB] = "R_IA64_FPTR64LSB",
-    [R_IA64_PCREL60B] = "R_IA64_PCREL60B",
-    [R_IA64_PCREL21B] = "R_IA64_PCREL21B",
-    [R_IA64_PCREL21M] = "R_IA64_PCREL21M",
-    [R_IA64_PCREL21F] = "R_IA64_PCREL21F",
-    [R_IA64_PCREL32MSB] = "R_IA64_PCREL32MSB",
-    [R_IA64_PCREL32LSB] = "R_IA64_PCREL32LSB",
-    [R_IA64_PCREL64MSB] = "R_IA64_PCREL64MSB",
-    [R_IA64_PCREL64LSB] = "R_IA64_PCREL64LSB",
-    [R_IA64_LTOFF_FPTR22] = "R_IA64_LTOFF_FPTR22",
-    [R_IA64_LTOFF_FPTR64I] = "R_IA64_LTOFF_FPTR64I",
-    [R_IA64_LTOFF_FPTR32MSB] = "R_IA64_LTOFF_FPTR32MSB",
-    [R_IA64_LTOFF_FPTR32LSB] = "R_IA64_LTOFF_FPTR32LSB",
-    [R_IA64_LTOFF_FPTR64MSB] = "R_IA64_LTOFF_FPTR64MSB",
-    [R_IA64_LTOFF_FPTR64LSB] = "R_IA64_LTOFF_FPTR64LSB",
-    [R_IA64_SEGREL32MSB] = "R_IA64_SEGREL32MSB",
-    [R_IA64_SEGREL32LSB] = "R_IA64_SEGREL32LSB",
-    [R_IA64_SEGREL64MSB] = "R_IA64_SEGREL64MSB",
-    [R_IA64_SEGREL64LSB] = "R_IA64_SEGREL64LSB",
-    [R_IA64_SECREL32MSB] = "R_IA64_SECREL32MSB",
-    [R_IA64_SECREL32LSB] = "R_IA64_SECREL32LSB",
-    [R_IA64_SECREL64MSB] = "R_IA64_SECREL64MSB",
-    [R_IA64_SECREL64LSB] = "R_IA64_SECREL64LSB",
-    [R_IA64_REL32MSB] = "R_IA64_REL32MSB",
-    [R_IA64_REL32LSB] = "R_IA64_REL32LSB",
-    [R_IA64_REL64MSB] = "R_IA64_REL64MSB",
-    [R_IA64_REL64LSB] = "R_IA64_REL64LSB",
-    [R_IA64_LTV32MSB] = "R_IA64_LTV32MSB",
-    [R_IA64_LTV32LSB] = "R_IA64_LTV32LSB",
-    [R_IA64_LTV64MSB] = "R_IA64_LTV64MSB",
-    [R_IA64_LTV64LSB] = "R_IA64_LTV64LSB",
-    [R_IA64_PCREL21BI] = "R_IA64_PCREL21BI",
-    [R_IA64_PCREL22] = "R_IA64_PCREL22",
-    [R_IA64_PCREL64I] = "R_IA64_PCREL64I",
-    [R_IA64_IPLTMSB] = "R_IA64_IPLTMSB",
-    [R_IA64_IPLTLSB] = "R_IA64_IPLTLSB",
-    [R_IA64_COPY] = "R_IA64_COPY",
-    [R_IA64_SUB] = "R_IA64_SUB",
-    [R_IA64_LTOFF22X] = "R_IA64_LTOFF22X",
-    [R_IA64_LDXMOV] = "R_IA64_LDXMOV",
-    [R_IA64_TPREL14] = "R_IA64_TPREL14",
-    [R_IA64_TPREL22] = "R_IA64_TPREL22",
-    [R_IA64_TPREL64I] = "R_IA64_TPREL64I",
-    [R_IA64_TPREL64MSB] = "R_IA64_TPREL64MSB",
-    [R_IA64_TPREL64LSB] = "R_IA64_TPREL64LSB",
-    [R_IA64_LTOFF_TPREL22] = "R_IA64_LTOFF_TPREL22",
-    [R_IA64_DTPMOD64MSB] = "R_IA64_DTPMOD64MSB",
-    [R_IA64_DTPMOD64LSB] = "R_IA64_DTPMOD64LSB",
-    [R_IA64_LTOFF_DTPMOD22] = "R_IA64_LTOFF_DTPMOD22",
-    [R_IA64_DTPREL14] = "R_IA64_DTPREL14",
-    [R_IA64_DTPREL22] = "R_IA64_DTPREL22",
-    [R_IA64_DTPREL64I] = "R_IA64_DTPREL64I",
-    [R_IA64_DTPREL32MSB] = "R_IA64_DTPREL32MSB",
-    [R_IA64_DTPREL32LSB] = "R_IA64_DTPREL32LSB",
-    [R_IA64_DTPREL64MSB] = "R_IA64_DTPREL64MSB",
-    [R_IA64_DTPREL64LSB] = "R_IA64_DTPREL64LSB",
-    [R_IA64_LTOFF_DTPREL22] = "R_IA64_LTOFF_DTPREL22"
-  };
-
-
-/* Determine relocation type string for IA-64.  */
-const char *
-ia64_reloc_type_name (int type, char *buf __attribute__ ((unused)),
-		      size_t len __attribute__ ((unused)))
-{
-  if (type < 0
-      || ((size_t) type
-	  >= sizeof (reloc_map_table) / sizeof (reloc_map_table[0])))
-    return NULL;
-
-  return reloc_map_table[type];
-}
-
-
-/* Check for correct relocation type.  */
-bool
-ia64_reloc_type_check (int type)
-{
-  return (type >= R_IA64_NONE
-	  && ((size_t) type
-	      < sizeof (reloc_map_table) / sizeof (reloc_map_table[0]))
-	  && reloc_map_table[type] != NULL) ? true : false;
-}
+#define BACKEND		ia64_
+#include "libebl_CPU.h"
 
 
 const char *
@@ -164,7 +46,6 @@
   return NULL;
 }
 
-
 const char *
 ia64_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
 		       size_t len __attribute__ ((unused)))
@@ -179,11 +60,11 @@
   return NULL;
 }
 
-/* Check whether given relocation is a copy relocation.  */
+/* Check dynamic tag.  */
 bool
-ia64_copy_reloc_p (int reloc)
+ia64_dynamic_tag_check (int64_t tag)
 {
-  return reloc == R_IA64_COPY;
+  return tag == DT_IA_64_PLT_RESERVE;
 }
 
 /* Check whether machine flags are valid.  */
@@ -192,3 +73,47 @@
 {
   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/libebl/libeblP.h b/libebl/libeblP.h
index e3696f9..134b600 100644
--- a/libebl/libeblP.h
+++ b/libebl/libeblP.h
@@ -29,91 +29,17 @@
   const char *emulation;
 
   /* ELF machine, class, and data encoding.  */
-  int machine;
-  int class;
-  int data;
+  uint_fast16_t machine;
+  uint_fast8_t class;
+  uint_fast8_t data;
 
   /* The libelf handle (if known).  */
   Elf *elf;
 
-  /* Return symbol representaton of object file type.  */
-  const char *(*object_type_name) (int, char *, size_t);
-
-  /* Return symbolic representation of relocation type.  */
-  const char *(*reloc_type_name) (int, char *, size_t);
-
-  /* Check relocation type.  */
-  bool (*reloc_type_check) (int);
-
-  /* Check if relocation type is for simple absolute relocations.  */
-  Elf_Type (*reloc_simple_type) (Elf *, int);
-
-  /* Check relocation type use.  */
-  bool (*reloc_valid_use) (Elf *, int);
-
-  /* Return true if the symbol type is that referencing the GOT.  */
-  bool (*gotpc_reloc_check) (Elf *, int);
-
-  /* Return symbolic representation of segment type.  */
-  const char *(*segment_type_name) (int, char *, size_t);
-
-  /* Return symbolic representation of section type.  */
-  const char *(*section_type_name) (int, char *, size_t);
-
-  /* Return section name.  */
-  const char *(*section_name) (int, int, char *, size_t);
-
-  /* Return next machine flag name.  */
-  const char *(*machine_flag_name) (GElf_Word *);
-
-  /* Check whether machine flags are valid.  */
-  bool (*machine_flag_check) (GElf_Word);
-
-  /* Return symbolic representation of symbol type.  */
-  const char *(*symbol_type_name) (int, char *, size_t);
-
-  /* Return symbolic representation of symbol binding.  */
-  const char *(*symbol_binding_name) (int, char *, size_t);
-
-  /* Return symbolic representation of dynamic tag.  */
-  const char *(*dynamic_tag_name) (int64_t, char *, size_t);
-
-  /* Check dynamic tag.  */
-  bool (*dynamic_tag_check) (int64_t);
-
-  /* Combine section header flags values.  */
-  GElf_Word (*sh_flags_combine) (GElf_Word, GElf_Word);
-
-  /* Return symbolic representation of OS ABI.  */
-  const char *(*osabi_name) (int, char *, size_t);
-
-  /* Name of a note entry type for core files.  */
-  const char *(*core_note_type_name) (uint32_t, char *, size_t);
-
-  /* Name of a note entry type for object files.  */
-  const char *(*object_note_type_name) (uint32_t, char *, size_t);
-
-  /* Handle core note.  */
-  bool (*core_note) (const char *, uint32_t, uint32_t, const char *);
-
-  /* Handle object file note.  */
-  bool (*object_note) (const char *, uint32_t, uint32_t, const char *);
-
-  /* Check section name for being that of a debug informatino section.  */
-  bool (*debugscn_p) (const char *);
-
-  /* Check whether given relocation is a copy relocation.  */
-  bool (*copy_reloc_p) (int);
-
-  /* Check whether given symbol's value is ok despite normal checks.  */
-  bool (*check_special_symbol) (Elf *, GElf_Ehdr *, const GElf_Sym *,
-				const char *, const GElf_Shdr *);
-
-  /* Check if backend uses a bss PLT in this file.  */
-  bool (*bss_plt_p) (Elf *, GElf_Ehdr *);
-
-  /* Destructor for ELF backend handle.  */
-  void (*destr) (struct ebl *);
+  /* See ebl-hooks.h for the declarations of the hook functions.  */
+# define EBLHOOK(name) (*name)
+# include "ebl-hooks.h"
+# undef EBLHOOK
 
   /* Internal data.  */
   void *dlhandle;
diff --git a/libebl/libebl_CPU.h b/libebl/libebl_CPU.h
new file mode 100644
index 0000000..607c154
--- /dev/null
+++ b/libebl/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/libebl/libebl_alpha.h b/libebl/libebl_alpha.h
deleted file mode 100644
index 24a3500..0000000
--- a/libebl/libebl_alpha.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Interface for libebl_alpha module.
-   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.   */
-
-#ifndef _LIBEBL_ALPHA_H
-#define _LIBEBL_ALPHA_H 1
-
-#include <libeblP.h>
-
-
-/* Constructor.  */
-extern const char *alpha_init (Elf *elf, GElf_Half machine, Ebl *eh,
-			       size_t ehlen);
-
-/* Destructor.  */
-extern void alpha_destr (Ebl *bh);
-
-
-/* Function to get relocation type name.  */
-extern const char *alpha_reloc_type_name (int type, char *buf, size_t len);
-
-/* Check relocation type.  */
-extern bool alpha_reloc_type_check (int type);
-
-/* Name of dynamic tag.  */
-extern const char *alpha_dynamic_tag_name (int64_t tag, char *buf, size_t len);
-
-/* Check dynamic tag.  */
-extern bool alpha_dynamic_tag_check (int64_t tag);
-
-/* Check whether given relocation is a copy relocation.  */
-extern bool alpha_copy_reloc_p (int reloc);
-
-#endif	/* libebl_alpha.h */
diff --git a/libebl/libebl_alpha.map b/libebl/libebl_alpha.map
deleted file mode 100644
index fa092c6..0000000
--- a/libebl/libebl_alpha.map
+++ /dev/null
@@ -1,7 +0,0 @@
-ELFUTILS_1.0 {
-  global:
-    alpha_init;
-
-  local:
-    *;
-};
diff --git a/libebl/libebl_arm.h b/libebl/libebl_arm.h
deleted file mode 100644
index 18bb99c..0000000
--- a/libebl/libebl_arm.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Interface for libebl_arm module.
-   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.   */
-
-#ifndef _LIBEBL_ARM_H
-#define _LIBEBL_ARM_H 1
-
-#include <libeblP.h>
-
-
-/* Constructor.  */
-extern const char *arm_init (Elf *elf, GElf_Half machine, Ebl *eh,
-			     size_t ehlen);
-
-/* Destructor.  */
-extern void arm_destr (Ebl *bh);
-
-
-/* Function to get relocation type name.  */
-extern const char *arm_reloc_type_name (int type, char *buf, size_t len);
-
-/* Check relocation type.  */
-extern bool arm_reloc_type_check (int type);
-
-/* Check whether given relocation is a copy relocation.  */
-extern bool arm_copy_reloc_p (int reloc);
-
-#endif	/* libebl_arm.h */
diff --git a/libebl/libebl_arm.map b/libebl/libebl_arm.map
deleted file mode 100644
index 51c7726..0000000
--- a/libebl/libebl_arm.map
+++ /dev/null
@@ -1,7 +0,0 @@
-ELFUTILS_1.0 {
-  global:
-    arm_init;
-
-  local:
-    *;
-};
diff --git a/libebl/libebl_i386.h b/libebl/libebl_i386.h
deleted file mode 100644
index ef2b319..0000000
--- a/libebl/libebl_i386.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Interface for libebl_i386 module.
-   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_I386_H
-#define _LIBEBL_I386_H 1
-
-#include <libeblP.h>
-
-
-/* Constructor.  */
-extern const char *i386_init (Elf *elf, GElf_Half machine, Ebl *eh,
-			      size_t ehlen);
-
-/* Destructor.  */
-extern void i386_destr (Ebl *bh);
-
-
-/* Function to get relocation type name.  */
-extern const char *i386_reloc_type_name (int type, char *buf, size_t len);
-
-/* Check relocation type.  */
-extern bool i386_reloc_type_check (int type);
-
-/* Check relocation type use.  */
-extern bool i386_reloc_valid_use (Elf *elf, int type);
-
-/* Check for the simple reloc types.  */
-extern Elf_Type i386_reloc_simple_type (Elf *elf, int type);
-
-/* Check relocation type use.  */
-extern bool i386_gotpc_reloc_check (Elf *elf, int type);
-
-/* Code note handling.  */
-extern bool i386_core_note (const char *name, uint32_t type, uint32_t descsz,
-			    const char *desc);
-
-/* Check section name for being that of a debug informatino section.  */
-extern bool i386_debugscn_p (const char *name);
-extern bool (*generic_debugscn_p) (const char *);
-
-/* Check whether given relocation is a copy relocation.  */
-extern bool i386_copy_reloc_p (int reloc);
-
-#endif	/* libebl_i386.h */
diff --git a/libebl/libebl_i386.map b/libebl/libebl_i386.map
deleted file mode 100644
index 48b4b04..0000000
--- a/libebl/libebl_i386.map
+++ /dev/null
@@ -1,7 +0,0 @@
-ELFUTILS_1.0 {
-  global:
-    i386_init;
-
-  local:
-    *;
-};
diff --git a/libebl/libebl_ia64.h b/libebl/libebl_ia64.h
deleted file mode 100644
index e5cf49d..0000000
--- a/libebl/libebl_ia64.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Interface for libebl_ia64 module.
-   Copyright (C) 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_IA64_H
-#define _LIBEBL_IA64_H 1
-
-#include <libeblP.h>
-
-
-/* Constructor.  */
-extern const char *ia64_init (Elf *elf, GElf_Half machine, Ebl *eh,
-			      size_t ehlen);
-
-/* Destructor.  */
-extern void ia64_destr (Ebl *bh);
-
-
-/* Function to get relocation type name.  */
-extern const char *ia64_reloc_type_name (int type, char *buf, size_t len);
-
-/* Check relocation type.  */
-extern bool ia64_reloc_type_check (int type);
-
-/* Name of segment type.  */
-extern const char *ia64_segment_type_name (int segment, char *buf, size_t len);
-
-/* Name of dynamic tag.  */
-extern const char *ia64_dynamic_tag_name (int64_t tag, char *buf, size_t len);
-
-/* Check whether given relocation is a copy relocation.  */
-extern bool ia64_copy_reloc_p (int reloc);
-
-/* Check whether machine flags are valid.  */
-extern bool ia64_machine_flag_check (GElf_Word flags);
-
-
-#endif	/* libebl_ia64.h */
diff --git a/libebl/libebl_ia64.map b/libebl/libebl_ia64.map
deleted file mode 100644
index 82d65e2..0000000
--- a/libebl/libebl_ia64.map
+++ /dev/null
@@ -1,7 +0,0 @@
-ELFUTILS_1.0 {
-  global:
-    ia64_init;
-
-  local:
-    *;
-};
diff --git a/libebl/libebl_ppc.h b/libebl/libebl_ppc.h
deleted file mode 100644
index 67e64af..0000000
--- a/libebl/libebl_ppc.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Interface for libebl_PPC module.
-   Copyright (C) 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.   */
-
-#ifndef _LIBEBL_PPC_H
-#define _LIBEBL_PPC_H 1
-
-#include <libeblP.h>
-
-
-/* Constructor.  */
-extern const char *ppc_init (Elf *elf, GElf_Half machine, Ebl *eh,
-			     size_t ehlen);
-
-/* Destructor.  */
-extern void ppc_destr (Ebl *bh);
-
-
-/* Function to get relocation type name.  */
-extern const char *ppc_reloc_type_name (int type, char *buf, size_t len);
-
-/* Check relocation type.  */
-extern bool ppc_reloc_type_check (int type);
-
-/* Check relocation type use.  */
-extern bool ppc_reloc_valid_use (Elf *elf, int type);
-
-/* Check for the simple reloc types.  */
-extern Elf_Type ppc_reloc_simple_type (Elf *elf, int type);
-
-/* Code note handling.  */
-extern bool ppc_core_note (const char *name, uint32_t type, uint32_t descsz,
-			      const char *desc);
-
-/* Name of dynamic tag.  */
-extern const char *ppc_dynamic_tag_name (int64_t tag, char *buf, size_t len);
-
-/* Check dynamic tag.  */
-extern bool ppc_dynamic_tag_check (int64_t tag);
-
-/* Check whether given relocation is a copy relocation.  */
-extern bool ppc_copy_reloc_p (int reloc);
-
-/* Check whether given symbol's st_value and st_size are OK despite normal
-   checks.  */
-extern bool ppc_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr,
-				      const GElf_Sym *sym, const char *name,
-				      const GElf_Shdr *destshdr);
-
-/* Check if backend uses a bss PLT in this file.  */
-extern bool ppc_bss_plt_p (Elf *elf, GElf_Ehdr *ehdr);
-
-
-#endif	/* libebl_ppc.h */
diff --git a/libebl/libebl_ppc.map b/libebl/libebl_ppc.map
deleted file mode 100644
index de0c432..0000000
--- a/libebl/libebl_ppc.map
+++ /dev/null
@@ -1,7 +0,0 @@
-ELFUTILS_1.0 {
-  global:
-    ppc_init;
-
-  local:
-    *;
-};
diff --git a/libebl/libebl_ppc64.h b/libebl/libebl_ppc64.h
deleted file mode 100644
index e03a1a7..0000000
--- a/libebl/libebl_ppc64.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Interface for libebl_PPC64 module.
-   Copyright (C) 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.   */
-
-#ifndef _LIBEBL_PPC64_H
-#define _LIBEBL_PPC64_H 1
-
-#include <libeblP.h>
-
-
-/* Constructor.  */
-extern const char *ppc64_init (Elf *elf, GElf_Half machine, Ebl *eh,
-			       size_t ehlen);
-
-/* Destructor.  */
-extern void ppc64_destr (Ebl *bh);
-
-
-/* Function to get relocation type name.  */
-extern const char *ppc64_reloc_type_name (int type, char *buf, size_t len);
-
-/* Check relocation type.  */
-extern bool ppc64_reloc_type_check (int type);
-
-/* Check relocation type use.  */
-extern bool ppc64_reloc_valid_use (Elf *elf, int type);
-
-/* Check for the simple reloc types.  */
-extern Elf_Type ppc64_reloc_simple_type (Elf *elf, int type);
-
-/* Code note handling.  */
-extern bool ppc64_core_note (const char *name, uint32_t type, uint32_t descsz,
-			      const char *desc);
-
-/* Name of dynamic tag.  */
-extern const char *ppc64_dynamic_tag_name (int64_t tag, char *buf, size_t len);
-
-/* Check dynamic tag.  */
-extern bool ppc64_dynamic_tag_check (int64_t tag);
-
-/* Check whether given relocation is a copy relocation.  */
-extern bool ppc64_copy_reloc_p (int reloc);
-
-/* Check whether given symbol's st_value and st_size are OK despite normal
-   checks.  */
-extern bool ppc64_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr,
-					const GElf_Sym *sym, const char *name,
-					const GElf_Shdr *destshdr);
-
-/* Check if backend uses a bss PLT in this file.  */
-extern bool ppc64_bss_plt_p (Elf *elf, GElf_Ehdr *ehdr);
-
-
-#endif	/* libebl_ppc.h */
diff --git a/libebl/libebl_ppc64.map b/libebl/libebl_ppc64.map
deleted file mode 100644
index 0c3842c..0000000
--- a/libebl/libebl_ppc64.map
+++ /dev/null
@@ -1,7 +0,0 @@
-ELFUTILS_1.0 {
-  global:
-    ppc64_init;
-
-  local:
-    *;
-};
diff --git a/libebl/libebl_sh.h b/libebl/libebl_sh.h
deleted file mode 100644
index 32b029a..0000000
--- a/libebl/libebl_sh.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Interface for libebl_sh module.
-   Copyright (C) 2000, 2001, 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.   */
-
-#ifndef _LIBEBL_SH_H
-#define _LIBEBL_SH_H 1
-
-#include <libeblP.h>
-
-
-/* Constructor.  */
-extern const char *sh_init (Elf *elf, GElf_Half machine, Ebl *eh,
-			    size_t ehlen);
-
-/* Destructor.  */
-extern void sh_destr (Ebl *bh);
-
-
-/* Function to get relocation type name.  */
-extern const char *sh_reloc_type_name (int type, char *buf, size_t len);
-
-/* Check whether given relocation is a copy relocation.  */
-extern bool sh_copy_reloc_p (int reloc);
-
-#endif	/* libebl_sh.h */
diff --git a/libebl/libebl_sh.map b/libebl/libebl_sh.map
deleted file mode 100644
index a5130c1..0000000
--- a/libebl/libebl_sh.map
+++ /dev/null
@@ -1,7 +0,0 @@
-ELFUTILS_1.0 {
-  global:
-    sh_init;
-
-  local:
-    *;
-};
diff --git a/libebl/libebl_sparc.h b/libebl/libebl_sparc.h
deleted file mode 100644
index 077db17..0000000
--- a/libebl/libebl_sparc.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Interface for libebl_sparc module.
-   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.   */
-
-#ifndef _LIBEBL_SPARC_H
-#define _LIBEBL_SPARC_H 1
-
-#include <libeblP.h>
-
-
-/* Constructor.  */
-extern const char *sparc_init (Elf *elf, GElf_Half machine, Ebl *eh,
-			       size_t ehlen);
-
-/* Destructor.  */
-extern void sparc_destr (Ebl *bh);
-
-
-/* Function to get relocation type name.  */
-extern const char *sparc_reloc_type_name (int type, char *buf, size_t len);
-
-/* Check relocation type.  */
-extern bool sparc_reloc_type_check (int type);
-
-/* Code note handling.  */
-extern bool sparc_core_note (const char *name, uint32_t type, uint32_t descsz,
-			     const char *desc);
-
-/* Check whether given relocation is a copy relocation.  */
-extern bool sparc_copy_reloc_p (int reloc);
-
-#endif	/* libebl_sparc.h */
diff --git a/libebl/libebl_sparc.map b/libebl/libebl_sparc.map
deleted file mode 100644
index c7c9f1b..0000000
--- a/libebl/libebl_sparc.map
+++ /dev/null
@@ -1,7 +0,0 @@
-ELFUTILS_1.0 {
-  global:
-    sparc_init;
-
-  local:
-    *;
-};
diff --git a/libebl/libebl_x86_64.h b/libebl/libebl_x86_64.h
deleted file mode 100644
index 025edb6..0000000
--- a/libebl/libebl_x86_64.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Interface for libebl_x86_64 module.
-   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.   */
-
-#ifndef _LIBEBL_X86_64_H
-#define _LIBEBL_X86_64_H 1
-
-#include <libeblP.h>
-
-
-/* Constructor.  */
-extern const char *x86_64_init (Elf *elf, GElf_Half machine, Ebl *eh,
-				size_t ehlen);
-
-/* Destructor.  */
-extern void x86_64_destr (Ebl *bh);
-
-
-/* Function to get relocation type name.  */
-extern const char *x86_64_reloc_type_name (int type, char *buf, size_t len);
-
-/* Check relocation type.  */
-extern bool x86_64_reloc_type_check (int type);
-
-/* Check relocation type use.  */
-extern bool x86_64_reloc_valid_use (Elf *elf, int type);
-
-/* Check for the simple reloc types.  */
-extern Elf_Type x86_64_reloc_simple_type (Elf *elf, int type);
-
-/* Code note handling.  */
-extern bool x86_64_core_note (const char *name, uint32_t type, uint32_t descsz,
-			      const char *desc);
-
-/* Check whether given relocation is a copy relocation.  */
-extern bool x86_64_copy_reloc_p (int reloc);
-
-#endif	/* libebl_x86_64.h */
diff --git a/libebl/libebl_x86_64.map b/libebl/libebl_x86_64.map
deleted file mode 100644
index 528a790..0000000
--- a/libebl/libebl_x86_64.map
+++ /dev/null
@@ -1,7 +0,0 @@
-ELFUTILS_1.0 {
-  global:
-    x86_64_init;
-
-  local:
-    *;
-};
diff --git a/libebl/ppc64_destr.c b/libebl/ppc64_destr.c
deleted file mode 100644
index 8da6a8f..0000000
--- a/libebl/ppc64_destr.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Destructor for PPC64 specific backend library.
-   Copyright (C) 2004, 2005 Red Hat, Inc.
-   Written by Ulrich Drepper <drepper@redhat.com>, 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 <libebl_ppc64.h>
-
-
-void
-ppc64_destr (bh)
-     Ebl *bh __attribute__ ((unused));
-{
-  /* Nothing to do so far.  */
-}
diff --git a/libebl/ppc64_init.c b/libebl/ppc64_init.c
index c8235bb..c8a9354 100644
--- a/libebl/ppc64_init.c
+++ b/libebl/ppc64_init.c
@@ -16,7 +16,12 @@
 # include <config.h>
 #endif
 
-#include <libebl_ppc64.h>
+#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 *
@@ -32,16 +37,13 @@
 
   /* We handle it.  */
   eh->name = "PowerPC 64-bit";
-  eh->reloc_type_name = ppc64_reloc_type_name;
-  eh->reloc_type_check = ppc64_reloc_type_check;
-  eh->reloc_valid_use = ppc64_reloc_valid_use;
+  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->destr = ppc64_destr;
 
   return MODVERSION;
 }
diff --git a/libebl/ppc64_reloc.def b/libebl/ppc64_reloc.def
new file mode 100644
index 0000000..d0cb2f9
--- /dev/null
+++ b/libebl/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/libebl/ppc64_symbol.c b/libebl/ppc64_symbol.c
index 7222ae4..db48617 100644
--- a/libebl/ppc64_symbol.c
+++ b/libebl/ppc64_symbol.c
@@ -21,178 +21,13 @@
 #include <stddef.h>
 #include <string.h>
 
-#include <libebl_ppc64.h>
-
-
-/* Return of the backend.  */
-const char *
-ppc64_backend_name (void)
-{
-  return "ppc64";
-}
-
-
-/* Relocation mapping table.  */
-static struct
-{
-  const char *name;
-  enum { both = 0, rel = 1, exec = 2 } appear;
-} reloc_map_table[] =
-  {
-    // XXX Check all the appear values.
-    [R_PPC64_NONE] = { "R_PPC64_NONE", both },
-    [R_PPC64_ADDR32] = { "R_PPC64_ADDR32", both },
-    [R_PPC64_ADDR24] = { "R_PPC64_ADDR24", both },
-    [R_PPC64_ADDR16] = { "R_PPC64_ADDR16", both },
-    [R_PPC64_ADDR16_LO] = { "R_PPC64_ADDR16_LO", both },
-    [R_PPC64_ADDR16_HI] = { "R_PPC64_ADDR16_HI", both },
-    [R_PPC64_ADDR16_HA] = { "R_PPC64_ADDR16_HA", both },
-    [R_PPC64_ADDR14] = { "R_PPC64_ADDR14", both },
-    [R_PPC64_ADDR14_BRTAKEN] = { "R_PPC64_ADDR14_BRTAKEN", exec },
-    [R_PPC64_ADDR14_BRNTAKEN] = { "R_PPC64_ADDR14_BRNTAKEN", exec },
-    [R_PPC64_REL24] = { "R_PPC64_REL24", both },
-    [R_PPC64_REL14] = { "R_PPC64_REL14", both },
-    [R_PPC64_REL14_BRTAKEN] = { "R_PPC64_REL14_BRTAKEN", exec },
-    [R_PPC64_REL14_BRNTAKEN] = { "R_PPC64_REL14_BRNTAKEN", exec },
-    [R_PPC64_GOT16] = { "R_PPC64_GOT16", rel },
-    [R_PPC64_GOT16_LO] = { "R_PPC64_GOT16_LO", rel },
-    [R_PPC64_GOT16_HI] = { "R_PPC64_GOT16_HI", rel },
-    [R_PPC64_GOT16_HA] = { "R_PPC64_GOT16_HA", rel },
-    [R_PPC64_COPY] = { "R_PPC64_COPY", exec },
-    [R_PPC64_GLOB_DAT] = { "R_PPC64_GLOB_DAT", exec },
-    [R_PPC64_JMP_SLOT] = { "R_PPC64_JMP_SLOT", exec },
-    [R_PPC64_RELATIVE] = { "R_PPC64_RELATIVE", exec },
-    [R_PPC64_UADDR32] = { "R_PPC64_UADDR32", exec },
-    [R_PPC64_UADDR16] = { "R_PPC64_UADDR16", exec },
-    [R_PPC64_REL32] = { "R_PPC64_REL32", exec },
-    [R_PPC64_PLT32] = { "R_PPC64_PLT32", exec },
-    [R_PPC64_PLTREL32] = { "R_PPC64_PLTREL32", both },
-    [R_PPC64_PLT16_LO] = { "R_PPC64_PLT16_LO", both },
-    [R_PPC64_PLT16_HI] = { "R_PPC64_PLT16_HI", both },
-    [R_PPC64_PLT16_HA] = { "R_PPC64_PLT16_HA", both },
-    [R_PPC64_SECTOFF] = { "R_PPC64_SECTOFF", both },
-    [R_PPC64_SECTOFF_LO] = { "R_PPC64_SECTOFF_LO", both },
-    [R_PPC64_SECTOFF_HI] = { "R_PPC64_SECTOFF_HI", both },
-    [R_PPC64_SECTOFF_HA] = { "R_PPC64_SECTOFF_HA", both },
-    [R_PPC64_ADDR30] = { "R_PPC64_ADDR30", both },
-    [R_PPC64_ADDR64] = { "R_PPC64_ADDR64", both },
-    [R_PPC64_ADDR16_HIGHER] = { "R_PPC64_ADDR16_HIGHER", both },
-    [R_PPC64_ADDR16_HIGHERA] = { "R_PPC64_ADDR16_HIGHERA", both },
-    [R_PPC64_ADDR16_HIGHEST] = { "R_PPC64_ADDR16_HIGHEST", both },
-    [R_PPC64_ADDR16_HIGHESTA] = { "R_PPC64_ADDR16_HIGHESTA", both },
-    [R_PPC64_UADDR64] = { "R_PPC64_UADDR64", both },
-    [R_PPC64_REL64] = { "R_PPC64_REL64", both },
-    [R_PPC64_PLT64] = { "R_PPC64_PLT64", both },
-    [R_PPC64_PLTREL64] = { "R_PPC64_PLTREL64", both },
-    [R_PPC64_TOC16] = { "R_PPC64_TOC16", both },
-    [R_PPC64_TOC16_LO] = { "R_PPC64_TOC16_LO", both },
-    [R_PPC64_TOC16_HI] = { "R_PPC64_TOC16_HI", both },
-    [R_PPC64_TOC16_HA] = { "R_PPC64_TOC16_HA", both },
-    [R_PPC64_TOC] = { "R_PPC64_TOC", both },
-    [R_PPC64_PLTGOT16] = { "R_PPC64_PLTGOT16", both },
-    [R_PPC64_PLTGOT16_LO] = { "R_PPC64_PLTGOT16_LO", both },
-    [R_PPC64_PLTGOT16_HI] = { "R_PPC64_PLTGOT16_HI", both },
-    [R_PPC64_PLTGOT16_HA] = { "R_PPC64_PLTGOT16_HA", both },
-    [R_PPC64_ADDR16_DS] = { "R_PPC64_ADDR16_DS", both },
-    [R_PPC64_ADDR16_LO_DS] = { "R_PPC64_ADDR16_LO_DS", both },
-    [R_PPC64_GOT16_DS] = { "R_PPC64_GOT16_DS", both },
-    [R_PPC64_GOT16_LO_DS] = { "R_PPC64_GOT16_LO_DS", both },
-    [R_PPC64_PLT16_LO_DS] = { "R_PPC64_PLT16_LO_DS", both },
-    [R_PPC64_SECTOFF_DS] = { "R_PPC64_SECTOFF_DS", both },
-    [R_PPC64_SECTOFF_LO_DS] = { "R_PPC64_SECTOFF_LO_DS", both },
-    [R_PPC64_TOC16_DS] = { "R_PPC64_TOC16_DS", both },
-    [R_PPC64_TOC16_LO_DS] = { "R_PPC64_TOC16_LO_DS", both },
-    [R_PPC64_PLTGOT16_DS] = { "R_PPC64_PLTGOT16_DS", both },
-    [R_PPC64_PLTGOT16_LO_DS] = { "R_PPC64_PLTGOT16_LO_DS", both },
-    [R_PPC64_TLS] = { "R_PPC64_TLS", both },
-    [R_PPC64_DTPMOD64] = { "R_PPC64_DTPMOD64", both },
-    [R_PPC64_TPREL16] = { "R_PPC64_TPREL16", both },
-    [R_PPC64_TPREL16_LO] = { "R_PPC64_TPREL16_LO", both },
-    [R_PPC64_TPREL16_HI] = { "R_PPC64_TPREL16_HI", both },
-    [R_PPC64_TPREL16_HA] = { "R_PPC64_TPREL16_HA", both },
-    [R_PPC64_TPREL64] = { "R_PPC64_TPREL64", both },
-    [R_PPC64_DTPREL16] = { "R_PPC64_DTPREL16", both },
-    [R_PPC64_DTPREL16_LO] = { "R_PPC64_DTPREL16_LO", both },
-    [R_PPC64_DTPREL16_HI] = { "R_PPC64_DTPREL16_HI", both },
-    [R_PPC64_DTPREL16_HA] = { "R_PPC64_DTPREL16_HA", both },
-    [R_PPC64_DTPREL64] = { "R_PPC64_DTPREL64", both },
-    [R_PPC64_GOT_TLSGD16] = { "R_PPC64_GOT_TLSGD16", both },
-    [R_PPC64_GOT_TLSGD16_LO] = { "R_PPC64_GOT_TLSGD16_LO", both },
-    [R_PPC64_GOT_TLSGD16_HI] = { "R_PPC64_GOT_TLSGD16_HI", both },
-    [R_PPC64_GOT_TLSGD16_HA] = { "R_PPC64_GOT_TLSGD16_HA", both },
-    [R_PPC64_GOT_TLSLD16] = { "R_PPC64_GOT_TLSLD16", both },
-    [R_PPC64_GOT_TLSLD16_LO] = { "R_PPC64_GOT_TLSLD16_LO", both },
-    [R_PPC64_GOT_TLSLD16_HI] = { "R_PPC64_GOT_TLSLD16_HI", both },
-    [R_PPC64_GOT_TLSLD16_HA] = { "R_PPC64_GOT_TLSLD16_HA", both },
-    [R_PPC64_GOT_TPREL16_DS] = { "R_PPC64_GOT_TPREL16_DS", both },
-    [R_PPC64_GOT_TPREL16_LO_DS] = { "R_PPC64_GOT_TPREL16_LO_DS", both },
-    [R_PPC64_GOT_TPREL16_HI] = { "R_PPC64_GOT_TPREL16_HI", both },
-    [R_PPC64_GOT_TPREL16_HA] = { "R_PPC64_GOT_TPREL16_HA", both },
-    [R_PPC64_GOT_DTPREL16_DS] = { "R_PPC64_GOT_DTPREL16_DS", both },
-    [R_PPC64_GOT_DTPREL16_LO_DS] = { "R_PPC64_GOT_DTPREL16_LO_DS", both },
-    [R_PPC64_GOT_DTPREL16_HI] = { "R_PPC64_GOT_DTPREL16_HI", both },
-    [R_PPC64_GOT_DTPREL16_HA] = { "R_PPC64_GOT_DTPREL16_HA", both },
-    [R_PPC64_TPREL16_DS] = { "R_PPC64_TPREL16_DS", both },
-    [R_PPC64_TPREL16_LO_DS] = { "R_PPC64_TPREL16_LO_DS", both },
-    [R_PPC64_TPREL16_HIGHER] = { "R_PPC64_TPREL16_HIGHER", both },
-    [R_PPC64_TPREL16_HIGHERA] = { "R_PPC64_TPREL16_HIGHERA", both },
-    [R_PPC64_TPREL16_HIGHEST] = { "R_PPC64_TPREL16_HIGHEST", both },
-    [R_PPC64_TPREL16_HIGHESTA] = { "R_PPC64_TPREL16_HIGHESTA", both },
-    [R_PPC64_DTPREL16_DS] = { "R_PPC64_DTPREL16_DS", both },
-    [R_PPC64_DTPREL16_LO_DS] = { "R_PPC64_DTPREL16_LO_DS", both },
-    [R_PPC64_DTPREL16_HIGHER] = { "R_PPC64_DTPREL16_HIGHER", both },
-    [R_PPC64_DTPREL16_HIGHERA] = { "R_PPC64_DTPREL16_HIGHERA", both },
-    [R_PPC64_DTPREL16_HIGHEST] = { "R_PPC64_DTPREL16_HIGHEST", both },
-    [R_PPC64_DTPREL16_HIGHESTA] = { "R_PPC64_DTPREL16_HIGHESTA", both }
- };
-
-
-/* Determine relocation type string for PPC.  */
-const char *
-ppc64_reloc_type_name (int type, char *buf __attribute__ ((unused)),
-		       size_t len __attribute__ ((unused)))
-{
-  if (type < R_PPC64_NONE || type >= R_PPC64_NUM)
-    return NULL;
-
-  return reloc_map_table[type].name;
-}
-
-
-/* Check for correct relocation type.  */
-bool
-ppc64_reloc_type_check (int type)
-{
-  return (type >= R_PPC64_NONE && type < R_PPC64_NUM
-	  && reloc_map_table[type].name != NULL) ? true : false;
-}
-
-
-/* Check for correct relocation type use.  */
-bool
-ppc64_reloc_valid_use (Elf *elf, int type)
-{
-  if (type < R_PPC64_NONE || type >= R_PPC64_NUM
-      || reloc_map_table[type].name == NULL)
-    return false;
-
-  Elf64_Ehdr *ehdr = elf64_getehdr (elf);
-  assert (ehdr != NULL);
-
-  if (reloc_map_table[type].appear == rel)
-    return ehdr->e_type == ET_REL;
-
-  if (reloc_map_table[type].appear == exec)
-    return ehdr->e_type != ET_REL;
-
-  assert (reloc_map_table[type].appear == both);
-  return true;
-}
+#define BACKEND		ppc64_
+#include "libebl_CPU.h"
 
 
 /* Check for the simple reloc types.  */
 Elf_Type
-ppc64_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type)
+ppc64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
 {
   switch (type)
     {
@@ -238,14 +73,6 @@
 }
 
 
-/* Check whether given relocation is a copy relocation.  */
-bool
-ppc64_copy_reloc_p (int reloc)
-{
-  return reloc == R_PPC64_COPY;
-}
-
-
 /* Check whether given symbol's st_value and st_size are OK despite failing
    normal checks.  */
 bool
diff --git a/libebl/ppc_destr.c b/libebl/ppc_destr.c
deleted file mode 100644
index 65bb81c..0000000
--- a/libebl/ppc_destr.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Destructor for PPC specific backend library.
-   Copyright (C) 2004, 2005 Red Hat, Inc.
-   Written by Ulrich Drepper <drepper@redhat.com>, 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 <libebl_ppc.h>
-
-
-void
-ppc_destr (bh)
-     Ebl *bh __attribute__ ((unused));
-{
-  /* Nothing to do so far.  */
-}
diff --git a/libebl/ppc_init.c b/libebl/ppc_init.c
index d76b1b1..375b79e 100644
--- a/libebl/ppc_init.c
+++ b/libebl/ppc_init.c
@@ -16,7 +16,12 @@
 # include <config.h>
 #endif
 
-#include <libebl_ppc.h>
+#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 *
@@ -32,16 +37,12 @@
 
   /* We handle it.  */
   eh->name = "PowerPC";
-  eh->reloc_type_name = ppc_reloc_type_name;
-  eh->reloc_type_check = ppc_reloc_type_check;
-  eh->reloc_valid_use = ppc_reloc_valid_use;
+  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->copy_reloc_p = ppc_copy_reloc_p;
   eh->check_special_symbol = ppc_check_special_symbol;
   eh->bss_plt_p = ppc_bss_plt_p;
-  eh->destr = ppc_destr;
 
   return MODVERSION;
 }
diff --git a/libebl/ppc_reloc.def b/libebl/ppc_reloc.def
new file mode 100644
index 0000000..9718738
--- /dev/null
+++ b/libebl/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/libebl/ppc_symbol.c b/libebl/ppc_symbol.c
index d83da9e..f161d70 100644
--- a/libebl/ppc_symbol.c
+++ b/libebl/ppc_symbol.c
@@ -21,145 +21,13 @@
 #include <stddef.h>
 #include <string.h>
 
-#include <libebl_ppc.h>
-
-
-/* Return of the backend.  */
-const char *
-ppc_backend_name (void)
-{
-  return "ppc";
-}
-
-
-/* Relocation mapping table.  */
-static struct
-{
-  const char *name;
-  enum { both = 0, rel = 1, exec = 2 } appear;
-} reloc_map_table[] =
-  {
-    // XXX Check all the appear values.
-    [R_PPC_NONE] = { "R_PPC_NONE", both },
-    [R_PPC_ADDR32] = { "R_PPC_ADDR32", both },
-    [R_PPC_ADDR24] = { "R_PPC_ADDR24", both },
-    [R_PPC_ADDR16] = { "R_PPC_ADDR16", both },
-    [R_PPC_ADDR16_LO] = { "R_PPC_ADDR16_LO", both },
-    [R_PPC_ADDR16_HI] = { "R_PPC_ADDR16_HI", both },
-    [R_PPC_ADDR16_HA] = { "R_PPC_ADDR16_HA", both },
-    [R_PPC_ADDR14] = { "R_PPC_ADDR14", exec },
-    [R_PPC_ADDR14_BRTAKEN] = { "R_PPC_ADDR14_BRTAKEN", exec },
-    [R_PPC_ADDR14_BRNTAKEN] = { "R_PPC_ADDR14_BRNTAKEN", exec },
-    [R_PPC_REL24] = { "R_PPC_REL24", both },
-    [R_PPC_REL14] = { "R_PPC_REL14", both },
-    [R_PPC_REL14_BRTAKEN] = { "R_PPC_REL14_BRTAKEN", exec },
-    [R_PPC_REL14_BRNTAKEN] = { "R_PPC_REL14_BRNTAKEN", exec },
-    [R_PPC_GOT16] = { "R_PPC_GOT16", rel },
-    [R_PPC_GOT16_LO] = { "R_PPC_GOT16_LO", rel },
-    [R_PPC_GOT16_HI] = { "R_PPC_GOT16_HI", rel },
-    [R_PPC_GOT16_HA] = { "R_PPC_GOT16_HA", rel },
-    [R_PPC_PLTREL24] = { "R_PPC_PLTREL24", rel },
-    [R_PPC_COPY] = { "R_PPC_COPY", exec },
-    [R_PPC_GLOB_DAT] = { "R_PPC_GLOB_DAT", exec },
-    [R_PPC_JMP_SLOT] = { "R_PPC_JMP_SLOT", exec },
-    [R_PPC_RELATIVE] = { "R_PPC_RELATIVE", exec },
-    [R_PPC_LOCAL24PC] = { "R_PPC_LOCAL24PC", rel },
-    [R_PPC_UADDR32] = { "R_PPC_UADDR32", exec },
-    [R_PPC_UADDR16] = { "R_PPC_UADDR16", exec },
-    [R_PPC_REL32] = { "R_PPC_REL32", exec },
-    [R_PPC_PLT32] = { "R_PPC_PLT32", exec },
-    [R_PPC_PLTREL32] = { "R_PPC_PLTREL32", both },
-    [R_PPC_PLT16_LO] = { "R_PPC_PLT16_LO", both },
-    [R_PPC_PLT16_HI] = { "R_PPC_PLT16_HI", both },
-    [R_PPC_PLT16_HA] = { "R_PPC_PLT16_HA", both },
-    [R_PPC_SDAREL16] = { "R_PPC_SDAREL16", both },
-    [R_PPC_SECTOFF] = { "R_PPC_SECTOFF", both },
-    [R_PPC_SECTOFF_LO] = { "R_PPC_SECTOFF_LO", both },
-    [R_PPC_SECTOFF_HI] = { "R_PPC_SECTOFF_HI", both },
-    [R_PPC_SECTOFF_HA] = { "R_PPC_SECTOFF_HA", both },
-    [R_PPC_TLS] = { "R_PPC_TLS", both },
-    [R_PPC_DTPMOD32] = { "R_PPC_DTPMOD32", exec },
-    [R_PPC_TPREL16] = { "R_PPC_TPREL16", rel },
-    [R_PPC_TPREL16_LO] = { "R_PPC_TPREL16_LO", rel },
-    [R_PPC_TPREL16_HI] = { "R_PPC_TPREL16_HI", rel },
-    [R_PPC_TPREL16_HA] = { "R_PPC_TPREL16_HA", rel },
-    [R_PPC_TPREL32] = { "R_PPC_TPREL32", exec },
-    [R_PPC_DTPREL16] = { "R_PPC_DTPREL16", rel },
-    [R_PPC_DTPREL16_LO] = { "R_PPC_DTPREL16_LO", rel },
-    [R_PPC_DTPREL16_HI] = { "R_PPC_DTPREL16_HI", rel },
-    [R_PPC_DTPREL16_HA] = { "R_PPC_DTPREL16_HA", rel },
-    [R_PPC_DTPREL32] = { "R_PPC_DTPREL32", exec },
-    [R_PPC_GOT_TLSGD16] = { "R_PPC_GOT_TLSGD16", exec },
-    [R_PPC_GOT_TLSGD16_LO] = { "R_PPC_GOT_TLSGD16_LO", exec },
-    [R_PPC_GOT_TLSGD16_HI] = { "R_PPC_GOT_TLSGD16_HI", exec },
-    [R_PPC_GOT_TLSGD16_HA] = { "R_PPC_GOT_TLSGD16_HA", exec },
-    [R_PPC_GOT_TLSLD16] = { "R_PPC_GOT_TLSLD16", exec },
-    [R_PPC_GOT_TLSLD16_LO] = { "R_PPC_GOT_TLSLD16_LO", exec },
-    [R_PPC_GOT_TLSLD16_HI] = { "R_PPC_GOT_TLSLD16_HI", exec },
-    [R_PPC_GOT_TLSLD16_HA] = { "R_PPC_GOT_TLSLD16_HA", exec },
-    [R_PPC_GOT_TPREL16] = { "R_PPC_GOT_TPREL16", exec },
-    [R_PPC_GOT_TPREL16_LO] = { "R_PPC_GOT_TPREL16_LO", exec },
-    [R_PPC_GOT_TPREL16_HI] = { "R_PPC_GOT_TPREL16_HI", exec },
-    [R_PPC_GOT_TPREL16_HA] = { "R_PPC_GOT_TPREL16_HA", exec },
-    [R_PPC_GOT_DTPREL16] = { "R_PPC_GOT_DTPREL16", exec },
-    [R_PPC_GOT_DTPREL16_LO] = { "R_PPC_GOT_DTPREL16_LO", exec },
-    [R_PPC_GOT_DTPREL16_HI] = { "R_PPC_GOT_DTPREL16_HI", exec },
-    [R_PPC_GOT_DTPREL16_HA] = { "R_PPC_GOT_DTPREL16_HA", exec },
-    [R_PPC_REL16] = { "R_PPC_REL16", rel },
-    [R_PPC_REL16_LO] = { "R_PPC_REL16_LO", rel },
-    [R_PPC_REL16_HI] = { "R_PPC_REL16_HI", rel },
-    [R_PPC_REL16_HA] = { "R_PPC_REL16_HA", rel },
-  };
-#define nreloc_map_table \
-     (sizeof (reloc_map_table) / sizeof (reloc_map_table[0]))
-
-
-/* Determine relocation type string for PPC.  */
-const char *
-ppc_reloc_type_name (int type, char *buf __attribute__ ((unused)),
-		     size_t len __attribute__ ((unused)))
-{
-  if (type < 0 || (size_t) type >= nreloc_map_table)
-    return NULL;
-
-  return reloc_map_table[type].name;
-}
-
-
-/* Check for correct relocation type.  */
-bool
-ppc_reloc_type_check (int type)
-{
-  return (type >= R_PPC_NONE && (size_t) type < nreloc_map_table
-	  && reloc_map_table[type].name != NULL) ? true : false;
-}
-
-
-/* Check for correct relocation type use.  */
-bool
-ppc_reloc_valid_use (Elf *elf, int type)
-{
-  if (type < R_PPC_NONE || type >= R_PPC_NUM
-      || reloc_map_table[type].name == NULL)
-    return false;
-
-  Elf32_Ehdr *ehdr = elf32_getehdr (elf);
-  assert (ehdr != NULL);
-
-  if (reloc_map_table[type].appear == rel)
-    return ehdr->e_type == ET_REL;
-
-  if (reloc_map_table[type].appear == exec)
-    return ehdr->e_type != ET_REL;
-
-  assert (reloc_map_table[type].appear == both);
-  return true;
-}
+#define BACKEND		ppc_
+#include "libebl_CPU.h"
 
 
 /* Check for the simple reloc types.  */
 Elf_Type
-ppc_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type)
+ppc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
 {
   switch (type)
     {
@@ -196,14 +64,6 @@
 }
 
 
-/* Check whether given relocation is a copy relocation.  */
-bool
-ppc_copy_reloc_p (int reloc)
-{
-  return reloc == R_PPC_COPY;
-}
-
-
 /* Look for DT_PPC_GOT.  */
 static bool
 find_dyn_got (Elf *elf, GElf_Ehdr *ehdr, GElf_Addr *addr)
diff --git a/libebl/s390_init.c b/libebl/s390_init.c
new file mode 100644
index 0000000..1457866
--- /dev/null
+++ b/libebl/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/libebl/s390_reloc.def b/libebl/s390_reloc.def
new file mode 100644
index 0000000..bee67b3
--- /dev/null
+++ b/libebl/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/libebl/s390_symbol.c b/libebl/s390_symbol.c
new file mode 100644
index 0000000..ddfefbb
--- /dev/null
+++ b/libebl/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/libebl/sh_destr.c b/libebl/sh_destr.c
deleted file mode 100644
index 4f06534..0000000
--- a/libebl/sh_destr.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Destructor for SH specific backend library.
-   Copyright (C) 2000. 2002, 2005 Red Hat, Inc.
-   Written by Ulrich Drepper <drepper@redhat.com>, 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 <libebl_sh.h>
-
-
-void
-sh_destr (bh)
-     Ebl *bh __attribute__ ((unused));
-{
-  /* Nothing to do so far.  */
-}
diff --git a/libebl/sh_init.c b/libebl/sh_init.c
index bb6c904..4fadd9b 100644
--- a/libebl/sh_init.c
+++ b/libebl/sh_init.c
@@ -16,7 +16,12 @@
 # include <config.h>
 #endif
 
-#include <libebl_sh.h>
+#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 *
@@ -32,9 +37,8 @@
 
   /* We handle it.  */
   eh->name = "Hitachi SH";
-  eh->reloc_type_name = sh_reloc_type_name;
-  eh->copy_reloc_p = sh_copy_reloc_p;
-  eh->destr = sh_destr;
+  sh_init_reloc (eh);
+  eh->reloc_simple_type = sh_reloc_simple_type;
 
   return MODVERSION;
 }
diff --git a/libebl/sh_reloc.def b/libebl/sh_reloc.def
new file mode 100644
index 0000000..56db107
--- /dev/null
+++ b/libebl/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/libebl/sh_symbol.c b/libebl/sh_symbol.c
index e24fff1..3209d34 100644
--- a/libebl/sh_symbol.c
+++ b/libebl/sh_symbol.c
@@ -19,81 +19,26 @@
 #include <elf.h>
 #include <stddef.h>
 
-#include <libebl_sh.h>
+#define BACKEND sh_
+#include "libebl_CPU.h"
 
 
-/* Return of the backend.  */
-const char *
-sh_backend_name (void)
-{
-  return "sh";
-}
-
-
-/* Determine relocation type string for SH.  */
-const char *
-sh_reloc_type_name (int type, char *buf __attribute__ ((unused)),
-		    size_t len __attribute__ ((unused)))
-{
-  static const char *map_table1[] =
-  {
-    [R_SH_NONE] = "R_SH_NONE",
-    [R_SH_DIR32] = "R_SH_DIR32",
-    [R_SH_REL32] = "R_SH_REL32",
-    [R_SH_DIR8WPN] = "R_SH_DIR8WPN",
-    [R_SH_IND12W] = "R_SH_IND12W",
-    [R_SH_DIR8WPL] = "R_SH_DIR8WPL",
-    [R_SH_DIR8WPZ] = "R_SH_DIR8WPZ",
-    [R_SH_DIR8BP] = "R_SH_DIR8BP",
-    [R_SH_DIR8W] = "R_SH_DIR8W",
-    [R_SH_DIR8L] = "R_SH_DIR8L",
-    [R_SH_SWITCH16] = "R_SH_SWITCH16",
-    [R_SH_SWITCH32] = "R_SH_SWITCH32",
-    [R_SH_USES] = "R_SH_USES",
-    [R_SH_COUNT] = "R_SH_COUNT",
-    [R_SH_ALIGN] = "R_SH_ALIGN",
-    [R_SH_CODE] = "R_SH_CODE",
-    [R_SH_DATA] = "R_SH_DATA",
-    [R_SH_LABEL] = "R_SH_LABEL",
-    [R_SH_SWITCH8] = "R_SH_SWITCH8",
-    [R_SH_GNU_VTINHERIT] ="R_SH_GNU_VTINHERIT",
-    [R_SH_GNU_VTENTRY] = "R_SH_GNU_VTENTRY"
-  };
-  static const char *map_table2[] =
-  {
-    [R_SH_TLS_GD_32] = "R_SH_TLS_GD_32",
-    [R_SH_TLS_LD_32] = "R_SH_TLS_LD_32",
-    [R_SH_TLS_LDO_32] = "R_SH_TLS_LDO_32",
-    [R_SH_TLS_IE_32] = "R_SH_TLS_IE_32",
-    [R_SH_TLS_LE_32] = "R_SH_TLS_LE_32",
-    [R_SH_TLS_DTPMOD32] = "R_SH_TLS_DTPMOD32",
-    [R_SH_TLS_DTPOFF32] = "R_SH_TLS_DTPOFF32",
-    [R_SH_TLS_TPOFF32] = "R_SH_TLS_TPOFF32",
-    [R_SH_GOT32 - R_SH_GOT32] = "R_SH_GOT32",
-    [R_SH_PLT32 - R_SH_GOT32] = "R_SH_PLT32",
-    [R_SH_COPY - R_SH_GOT32] = "R_SH_COPY",
-    [R_SH_GLOB_DAT - R_SH_GOT32] = "R_SH_GLOB_DAT",
-    [R_SH_JMP_SLOT - R_SH_GOT32] = "R_SH_JMP_SLOT",
-    [R_SH_RELATIVE - R_SH_GOT32] = "R_SH_RELATIVE",
-    [R_SH_GOTOFF - R_SH_GOT32] = "R_SH_GOTOFF",
-    [R_SH_GOTPC - R_SH_GOT32] = "R_SH_GOTPC"
-  };
-
-  if (type >= 0
-      && (size_t) type < sizeof (map_table1) / sizeof (map_table1[0]))
-    return map_table1[type];
-
-  if ((type - R_SH_TLS_GD_32) >= 0
-      && ((size_t) (type - R_SH_TLS_GD_32)
-	  < sizeof (map_table2) / sizeof (map_table2[0])))
-    return map_table2[type - R_SH_TLS_GD_32];
-
-  return NULL;
-}
-
-/* Check whether given relocation is a copy relocation.  */
+/* Return true if the symbol type is that referencing the GOT.  */
 bool
-sh_copy_reloc_p (int reloc)
+sh_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), int type)
 {
-  return reloc == R_SH_COPY;
+  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/libebl/sparc_destr.c b/libebl/sparc_destr.c
deleted file mode 100644
index 819f361..0000000
--- a/libebl/sparc_destr.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Destructor for 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
-
-#include <libebl_sparc.h>
-
-
-void
-sparc_destr (bh)
-     Ebl *bh __attribute__ ((unused));
-{
-  /* Nothing to do so far.  */
-}
diff --git a/libebl/sparc_init.c b/libebl/sparc_init.c
index ac461a1..541df84 100644
--- a/libebl/sparc_init.c
+++ b/libebl/sparc_init.c
@@ -15,7 +15,12 @@
 # include <config.h>
 #endif
 
-#include <libebl_sparc.h>
+#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 *
@@ -36,11 +41,9 @@
     eh->name = "SPARC v8+";
   else
     eh->name = "SPARC";
-  eh->reloc_type_name = sparc_reloc_type_name;
-  eh->reloc_type_check = sparc_reloc_type_check;
+  sparc_init_reloc (eh);
+  eh->reloc_simple_type = sparc_reloc_simple_type;
   //eh->core_note = sparc_core_note;
-  eh->copy_reloc_p = sparc_copy_reloc_p;
-  eh->destr = sparc_destr;
 
   return MODVERSION;
 }
diff --git a/libebl/sparc_reloc.def b/libebl/sparc_reloc.def
new file mode 100644
index 0000000..91fcad7
--- /dev/null
+++ b/libebl/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/libebl/sparc_symbol.c b/libebl/sparc_symbol.c
index f33ed53..c83e5d3 100644
--- a/libebl/sparc_symbol.c
+++ b/libebl/sparc_symbol.c
@@ -19,131 +19,27 @@
 #include <elf.h>
 #include <stddef.h>
 
-#include <libebl_sparc.h>
+#define BACKEND		sparc_
+#include "libebl_CPU.h"
 
-
-/* Return of the backend.  */
-const char *
-sparc_backend_name (void)
+/* Check for the simple reloc types.  */
+Elf_Type
+sparc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
 {
-  return "sparc";
-}
-
-
-/* Relocation mapping table.  */
-static const char *reloc_map_table[] =
-  {
-    [R_SPARC_NONE] = "R_SPARC_NONE",
-    [R_SPARC_8] = "R_SPARC_8",
-    [R_SPARC_16] = "R_SPARC_16",
-    [R_SPARC_32] = "R_SPARC_32",
-    [R_SPARC_DISP8] = "R_SPARC_DISP8",
-    [R_SPARC_DISP16] = "R_SPARC_DISP16",
-    [R_SPARC_DISP32] = "R_SPARC_DISP32",
-    [R_SPARC_WDISP30] = "R_SPARC_WDISP30",
-    [R_SPARC_WDISP22] = "R_SPARC_WDISP22",
-    [R_SPARC_HI22] = "R_SPARC_HI22",
-    [R_SPARC_22] = "R_SPARC_22",
-    [R_SPARC_13] = "R_SPARC_13",
-    [R_SPARC_LO10] = "R_SPARC_LO10",
-    [R_SPARC_GOT10] = "R_SPARC_GOT10",
-    [R_SPARC_GOT13] = "R_SPARC_GOT13",
-    [R_SPARC_GOT22] = "R_SPARC_GOT22",
-    [R_SPARC_PC10] = "R_SPARC_PC10",
-    [R_SPARC_PC22] = "R_SPARC_PC22",
-    [R_SPARC_WPLT30] = "R_SPARC_WPLT30",
-    [R_SPARC_COPY] = "R_SPARC_COPY",
-    [R_SPARC_GLOB_DAT] = "R_SPARC_GLOB_DAT",
-    [R_SPARC_JMP_SLOT] = "R_SPARC_JMP_SLOT",
-    [R_SPARC_RELATIVE] = "R_SPARC_RELATIVE",
-    [R_SPARC_UA32] = "R_SPARC_UA32",
-    [R_SPARC_PLT32] = "R_SPARC_PLT32",
-    [R_SPARC_HIPLT22] = "R_SPARC_HIPLT22",
-    [R_SPARC_LOPLT10] = "R_SPARC_LOPLT10",
-    [R_SPARC_PCPLT32] = "R_SPARC_PCPLT32",
-    [R_SPARC_PCPLT22] = "R_SPARC_PCPLT22",
-    [R_SPARC_PCPLT10] = "R_SPARC_PCPLT10",
-    [R_SPARC_10] = "R_SPARC_10",
-    [R_SPARC_11] = "R_SPARC_11",
-    [R_SPARC_64] = "R_SPARC_64",
-    [R_SPARC_OLO10] = "R_SPARC_OLO10",
-    [R_SPARC_HH22] = "R_SPARC_HH22",
-    [R_SPARC_HM10] = "R_SPARC_HM10",
-    [R_SPARC_LM22] = "R_SPARC_LM22",
-    [R_SPARC_PC_HH22] = "R_SPARC_PC_HH22",
-    [R_SPARC_PC_HM10] = "R_SPARC_PC_HM10",
-    [R_SPARC_PC_LM22] = "R_SPARC_PC_LM22",
-    [R_SPARC_WDISP16] = "R_SPARC_WDISP16",
-    [R_SPARC_WDISP19] = "R_SPARC_WDISP19",
-    [R_SPARC_7] = "R_SPARC_7",
-    [R_SPARC_5] = "R_SPARC_5",
-    [R_SPARC_6] = "R_SPARC_6",
-    [R_SPARC_DISP64] = "R_SPARC_DISP64",
-    [R_SPARC_PLT64] = "R_SPARC_PLT64",
-    [R_SPARC_HIX22] = "R_SPARC_HIX22",
-    [R_SPARC_LOX10] = "R_SPARC_LOX10",
-    [R_SPARC_H44] = "R_SPARC_H44",
-    [R_SPARC_M44] = "R_SPARC_M44",
-    [R_SPARC_L44] = "R_SPARC_L44",
-    [R_SPARC_REGISTER] = "R_SPARC_REGISTER",
-    [R_SPARC_UA64] = "R_SPARC_UA64",
-    [R_SPARC_UA16] = "R_SPARC_UA16",
-    [R_SPARC_TLS_GD_HI22] = "R_SPARC_TLS_GD_HI22",
-    [R_SPARC_TLS_GD_LO10] = "R_SPARC_TLS_GD_LO10",
-    [R_SPARC_TLS_GD_ADD] = "R_SPARC_TLS_GD_ADD",
-    [R_SPARC_TLS_GD_CALL] = "R_SPARC_TLS_GD_CALL",
-    [R_SPARC_TLS_LDM_HI22] = "R_SPARC_TLS_LDM_HI22",
-    [R_SPARC_TLS_LDM_LO10] = "R_SPARC_TLS_LDM_LO10",
-    [R_SPARC_TLS_LDM_ADD] = "R_SPARC_TLS_LDM_ADD",
-    [R_SPARC_TLS_LDM_CALL] = "R_SPARC_TLS_LDM_CALL",
-    [R_SPARC_TLS_LDO_HIX22] = "R_SPARC_TLS_LDO_HIX22",
-    [R_SPARC_TLS_LDO_LOX10] = "R_SPARC_TLS_LDO_LOX10",
-    [R_SPARC_TLS_LDO_ADD] = "R_SPARC_TLS_LDO_ADD",
-    [R_SPARC_TLS_IE_HI22] = "R_SPARC_TLS_IE_HI22",
-    [R_SPARC_TLS_IE_LO10] = "R_SPARC_TLS_IE_LO10",
-    [R_SPARC_TLS_IE_LD] = "R_SPARC_TLS_IE_LD",
-    [R_SPARC_TLS_IE_LDX] = "R_SPARC_TLS_IE_LDX",
-    [R_SPARC_TLS_IE_ADD] = "R_SPARC_TLS_IE_ADD",
-    [R_SPARC_TLS_LE_HIX22] = "R_SPARC_TLS_LE_HIX22",
-    [R_SPARC_TLS_LE_LOX10] = "R_SPARC_TLS_LE_LOX10",
-    [R_SPARC_TLS_DTPMOD32] = "R_SPARC_TLS_DTPMOD32",
-    [R_SPARC_TLS_DTPMOD64] = "R_SPARC_TLS_DTPMOD64",
-    [R_SPARC_TLS_DTPOFF32] = "R_SPARC_TLS_DTPOFF32",
-    [R_SPARC_TLS_DTPOFF64] = "R_SPARC_TLS_DTPOFF64",
-    [R_SPARC_TLS_TPOFF32] = "R_SPARC_TLS_TPOFF32",
-    [R_SPARC_TLS_TPOFF64] = "R_SPARC_TLS_TPOFF64"
-  };
-
-
-/* Determine relocation type string for sparc.  */
-const char *
-sparc_reloc_type_name (int type, char *buf __attribute__ ((unused)),
-		       size_t len __attribute__ ((unused)))
-{
-  /* High 24 bits of r_type are used for second addend in R_SPARC_OLO10.  */
-  if ((type & 0xff) == R_SPARC_OLO10)
-    return reloc_map_table[type & 0xff];
-
-  if (type < 0 || type >= R_SPARC_NUM)
-    return NULL;
-
-  return reloc_map_table[type];
-}
-
-
-/* Check for correct relocation type.  */
-bool
-sparc_reloc_type_check (int type)
-{
-  if ((type & 0xff) == R_SPARC_OLO10)
-    return true;
-  return (type >= R_SPARC_NONE && type < R_SPARC_NUM
-	  && reloc_map_table[type] != NULL) ? true : false;
-}
-
-/* Check whether given relocation is a copy relocation.  */
-bool
-sparc_copy_reloc_p (int reloc)
-{
-  return reloc == R_SPARC_COPY;
+  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/libebl/x86_64_corenote.c b/libebl/x86_64_corenote.c
index 0ee7cea..2fd775b 100644
--- a/libebl/x86_64_corenote.c
+++ b/libebl/x86_64_corenote.c
@@ -22,7 +22,8 @@
 #include <stdio.h>
 #include <sys/time.h>
 
-#include <libebl_x86_64.h>
+#define BACKEND		x86_64_
+#include "libebl_CPU.h"
 
 
 /* We cannot include <sys/procfs.h> since the definition would be for
diff --git a/libebl/x86_64_destr.c b/libebl/x86_64_destr.c
deleted file mode 100644
index 3805829..0000000
--- a/libebl/x86_64_destr.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Destructor for x86_64 specific backend library.
-   Copyright (C) 2002, 2005 Red Hat, Inc.
-   Written by Ulrich Drepper <drepper@redhat.com>, 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 <libebl_x86_64.h>
-
-
-void
-x86_64_destr (bh)
-     Ebl *bh __attribute__ ((unused));
-{
-  /* Nothing to do so far.  */
-}
diff --git a/libebl/x86_64_init.c b/libebl/x86_64_init.c
index 655a67f..e479972 100644
--- a/libebl/x86_64_init.c
+++ b/libebl/x86_64_init.c
@@ -16,7 +16,13 @@
 # include <config.h>
 #endif
 
-#include <libebl_x86_64.h>
+#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 *
@@ -32,13 +38,9 @@
 
   /* We handle it.  */
   eh->name = "AMD x86-64";
-  eh->reloc_type_name = x86_64_reloc_type_name;
-  eh->reloc_type_check = x86_64_reloc_type_check;
-  eh->reloc_valid_use = x86_64_reloc_valid_use;
+  x86_64_init_reloc (eh);
   eh->reloc_simple_type = x86_64_reloc_simple_type;
   eh->core_note = x86_64_core_note;
-  eh->copy_reloc_p = x86_64_copy_reloc_p;
-  eh->destr = x86_64_destr;
 
   return MODVERSION;
 }
diff --git a/libebl/x86_64_reloc.def b/libebl/x86_64_reloc.def
new file mode 100644
index 0000000..83a1828
--- /dev/null
+++ b/libebl/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/libebl/x86_64_symbol.c b/libebl/x86_64_symbol.c
index 38d357c..c48af10 100644
--- a/libebl/x86_64_symbol.c
+++ b/libebl/x86_64_symbol.c
@@ -20,96 +20,12 @@
 #include <elf.h>
 #include <stddef.h>
 
-#include <libebl_x86_64.h>
-
-
-/* Return of the backend.  */
-const char *
-x86_64_backend_name (void)
-{
-  return "x86-64";
-}
-
-
-/* Relocation mapping table.  */
-static struct
-{
-  const char *name;
-  enum { both = 0, rel = 1, exec = 2 } appear;
-} reloc_map_table[] =
-  {
-    [R_X86_64_NONE] = { "R_X86_64_NONE", both },
-    [R_X86_64_64] = { "R_X86_64_64", both },
-    [R_X86_64_PC32] = { "R_X86_64_PC32", rel },
-    [R_X86_64_GOT32] = { "R_X86_64_GOT32", rel },
-    [R_X86_64_PLT32] = { "R_X86_64_PLT32", rel },
-    [R_X86_64_COPY] = { "R_X86_64_COPY", exec },
-    [R_X86_64_GLOB_DAT] = { "R_X86_64_GLOB_DAT", exec },
-    [R_X86_64_JUMP_SLOT] = { "R_X86_64_JUMP_SLOT", exec },
-    [R_X86_64_RELATIVE] = { "R_X86_64_RELATIVE", exec },
-    [R_X86_64_GOTPCREL] = { "R_X86_64_GOTPCREL", exec },
-    [R_X86_64_32] = { "R_X86_64_32", both },
-    [R_X86_64_32S] = { "R_X86_64_32S", rel },
-    [R_X86_64_16] = { "R_X86_64_16", rel },
-    [R_X86_64_PC16] = { "R_X86_64_PC16", rel },
-    [R_X86_64_8] = { "R_X86_64_8", rel },
-    [R_X86_64_PC8] = { "R_X86_64_PC8", rel },
-    [R_X86_64_DTPMOD64] = { "R_X86_64_DTPMOD64", rel },
-    [R_X86_64_DTPOFF64] = { "R_X86_64_DTPOFF64", rel },
-    [R_X86_64_TPOFF64] = { "R_X86_64_TPOFF64", rel },
-    [R_X86_64_TLSGD] = { "R_X86_64_TLSGD", rel },
-    [R_X86_64_TLSLD] = { "R_X86_64_TLSLD", rel },
-    [R_X86_64_DTPOFF32] = { "R_X86_64_DTPOFF32", rel },
-    [R_X86_64_GOTTPOFF] = { "R_X86_64_GOTTPOFF", rel },
-    [R_X86_64_TPOFF32] = { "R_X86_64_TPOFF32", rel }
-  };
-
-
-/* Determine relocation type string for x86-64.  */
-const char *
-x86_64_reloc_type_name (int type, char *buf __attribute__ ((unused)),
-			size_t len __attribute__ ((unused)))
-{
-  if (type < 0 || type >= R_X86_64_NUM)
-    return NULL;
-
-  return reloc_map_table[type].name;
-}
-
-
-/* Check for correct relocation type.  */
-bool
-x86_64_reloc_type_check (int type)
-{
-  return (type >= R_X86_64_NONE && type < R_X86_64_NUM
-	  && reloc_map_table[type].name != NULL) ? true : false;
-}
-
-
-/* Check for correct relocation type use.  */
-bool
-x86_64_reloc_valid_use (Elf *elf, int type)
-{
-  if (type < R_X86_64_NONE || type >= R_X86_64_NUM
-      || reloc_map_table[type].name == NULL)
-    return false;
-
-  Elf64_Ehdr *ehdr = elf64_getehdr (elf);
-  assert (ehdr != NULL);
-
-  if (reloc_map_table[type].appear == rel)
-    return ehdr->e_type == ET_REL;
-
-  if (reloc_map_table[type].appear == exec)
-    return ehdr->e_type != ET_REL;
-
-  assert (reloc_map_table[type].appear == both);
-  return true;
-}
+#define BACKEND		x86_64_
+#include "libebl_CPU.h"
 
 /* Check for the simple reloc types.  */
 Elf_Type
-x86_64_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type)
+x86_64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
 {
   switch (type)
     {
@@ -127,10 +43,3 @@
       return ELF_T_NUM;
     }
 }
-
-/* Check whether given relocation is a copy relocation.  */
-bool
-x86_64_copy_reloc_p (int reloc)
-{
-  return reloc == R_X86_64_COPY;
-}