Adjust for monotone.
diff --git a/libebl/.cvsignore b/libebl/.cvsignore
new file mode 100644
index 0000000..70845e0
--- /dev/null
+++ b/libebl/.cvsignore
@@ -0,0 +1 @@
+Makefile.in
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
new file mode 100644
index 0000000..a14572c
--- /dev/null
+++ b/libebl/ChangeLog
@@ -0,0 +1,281 @@
+2005-07-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblsectionstripp.c: New file.
+	* Makefile.am (gen_SOURCES): Add eblsectionstripp.c.
+	* i386_init.c (i386_init): Install specific debugscn_p callback.
+	* i386_symbol.c (i386_debugscn_p): New function.
+	* libebl.h: Declare ebl_section_strip_p.
+	* libebl_i386.h: Declare i386_debugscn_p.
+
+	* libebl.h: Move Ebl definition to...
+	* libeblP.h: ...here.
+
+2005-07-21  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (install-ebl-modules): New target, commands from ...
+	(install): ... here.  Make this depend on it.
+	(LIBEBL_SUBDIR): New variable, substituted by configure.
+	(install-ebl-modules): Install in $(libdir)/$(LIBEBL_SUBDIR).
+	* eblopenbackend.c (openbackend): Use LIBEBL_SUBDIR in module name.
+
+2005-07-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblcopyrelocp.c: New file.
+	* Makefile.am (gen_SOURCES): Add eblcopyrelocp.c.
+	* libebl.h: Declare ebl_copy_reloc_p.
+	* eblopenbackend.c (fill_defaults): Fill in copy_reloc_p.
+	(default_copy_reloc_p): New function.
+	* alpha_init.c: Define and use arch-specific copy_reloc_p function.
+	* alpha_symbol.c: Likewise.
+	* arm_init.c: Likewise.
+	* arm_symbol.c: Likewise.
+	* i386_init.c: Likewise.
+	* i386_symbol.c: Likewise.
+	* ia64_init.c: Likewise.
+	* ia64_symbol.c: Likewise.
+	* ppc64_init.c: Likewise.
+	* ppc64_symbol.c: Likewise.
+	* ppc_init.c: Likewise.
+	* ppc_symbol.c: Likewise.
+	* sh_init.c: Likewise.
+	* sh_symbol.c: Likewise.
+	* sparc_init.c: Likewise.
+	* sparc_symbol.c: Likewise.
+	* x86_64_init.c: Likewise.
+	* x86_64_symbol.c: Likewise.
+	* libebl_alpha.h: Declare the copy_reloc_p function.
+	* libebl_arm.h: Likewise.
+	* libebl_i386.h: Likewise.
+	* libebl_ia64.h: Likewise.
+	* libebl_ppc.h: Likewise.
+	* libebl_ppc64.h: Likewise.
+	* libebl_sh.h: Likewise.
+	* libebl_sparc.h: Likewise.
+	* libebl_x86_64.h: Likewise.
+
+2005-05-31  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (libebl_*_so_SOURCES): Set to $(*_SRCS) so dependency
+	tracking works right.
+
+2005-05-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* libebl_x86_64.map: Add x86_64_core_note.
+
+2005-05-19  Roland McGrath  <roland@redhat.com>
+
+	* libebl_i386.map: Add i386_reloc_valid_use, i386_reloc_simple_type.
+	* libebl_ppc.map: Add ppc_reloc_simple_type.
+	* libebl_ppc64.map: Add ppc64_reloc_simple_type.
+	* libebl_x86_64.map: Add x86_64_reloc_simple_type.
+
+2005-05-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblcorenote.c: Handle new AT_* values and files with different
+	endianess.
+	* Makefile.am (x86_64_SRCS): Add x86_64_corenote.c.
+	* x86-64_corenote.c: New file.
+	* x86_64_init.c: Hook in x86_64_corenote.
+	* i386_corenote.c: Make file usable on 64-bit platforms.
+
+	* eblopenbackend.c: If modules version comparison fails, reinitialize
+	hooks.
+
+2005-05-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblopenbackend.c: Require the init function to return a string.
+	Compare it with MODVERSION from config.h.
+	* alpha_init.c: Change return type.  Return MODVERSION or NULL.
+	* arm_init.c: Likewise.
+	* eblopenbackend.c: Likewise.
+	* i386_init.c: Likewise.
+	* ia64_init.c: Likewise.
+	* ppc64_init.c: Likewise.
+	* ppc_init.c: Likewise.
+	* sh_init.c: Likewise.
+	* sparc_init.c: Likewise.
+	* x86_64_init.c: Likewise.
+	* libeblP.h: Adjust ebl_bhinit_t.
+	* libebl_alpha.h: Adjust init function prototype.
+	* libebl_arm.h: Likewise.
+	* libebl_i386.h: Likewise.
+	* libebl_ia64.h: Likewise.
+	* libebl_ppc.h: Likewise.
+	* libebl_ppc64.h: Likewise.
+	* libebl_sh.h: Likewise.
+	* libebl_sparc.h: Likewise.
+	* libebl_x86_64.h: Likewise.
+
+	* mips_destr.c: Removed.
+	* mips_init.c: Removed.
+	* mips_symbol.c: Removed.
+	* libebl_mips.h: Removed.
+	* libebl_mips.map: Removed.
+
+2005-05-03  Roland McGrath  <roland@redhat.com>
+
+	* libebl.h (Ebl): Add `reloc_simple_type' member.
+	* eblopenbackend.c (default_reloc_simple_type): New function.
+	(openbackend): Use that as default reloc_simple_type callback.
+	* eblrelocsimpletype.c: New file.
+	* Makefile.am (gen_SOURCES): Add it.
+	* i386_symbol.c (i386_reloc_simple_type): New function.
+	* libebl_i386.h: Declare it.
+	* i386_init.c (i386_init): Use it.
+	* x86_64_symbol.c (x86_64_reloc_simple_type): New function.
+	* libebl_x86_64.h: Declare it.
+	* x86_64_init.c (x86_64_init): Use it.
+	* ppc_symbol.c (ppc_reloc_simple_type): New function.
+	* libebl_ppc.h: Declare it.
+	* ppc_init.c (ppc_init): Use it.
+	* ppc64_symbol.c (ppc64_reloc_simple_type): New function.
+	* libebl_ppc64.h: Declare it.
+	* ppc64_init.c (ppc64_init): Use it.
+
+2005-03-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblcorenote.c (ebl_core_note): Add support for AT_SECURE.
+
+2005-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (AM_CFLAGS): Add -Wformat=2.
+
+2005-02-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* alpha_destr.c: Add __attribute__((unused)) where needed.
+	* alpha_init.c: Likewise.
+	* alpha_symbol.c: Likewise.
+	* arm_destr.c: Likewise.
+	* arm_init.c: Likewise.
+	* arm_symbol.c: Likewise.
+	* i386_corenote.c: Likewise.
+	* i386_destr.c: Likewise.
+	* i386_init.c: Likewise.
+	* i386_symbol.c: Likewise.
+	* ia64_destr.c: Likewise.
+	* ia64_init.c: Likewise.
+	* ia64_symbol.c: Likewise.
+	* mips_destr.c: Likewise.
+	* mips_init.c: Likewise.
+	* mips_symbol.c: Likewise.
+	* ppc64_destr.c: Likewise.
+	* ppc64_init.c: Likewise.
+	* ppc64_symbol.c: Likewise.
+	* ppc_destr.c: Likewise.
+	* ppc_init.c: Likewise.
+	* ppc_symbol.c: Likewise.
+	* sh_destr.c: Likewise.
+	* sh_init.c: Likewise.
+	* sh_symbol.c: Likewise.
+	* sparc_destr.c: Likewise.
+	* sparc_init.c: Likewise.
+	* sparc_symbol.c: Likewise.
+	* x86_64_destr.c: Likewise.
+	* x86_64_init.c: Likewise.
+	* x86_64_symbol.c: Likewise.
+
+	* x86_64_symbol.c (reloc_map_table): Fix entries for R_X86_64_64
+	and R_X86_64_32..
+
+2005-02-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblstrtab.c: A few cleanups.
+
+	* eblopenbackend.c: Mark unused parameters.
+
+	* eblgstrtab.c: Cleanups a few printf format strings.
+
+	* Makefile.am: Cleanup AM_CFLAGS handling.  Add -Wunused -Wextra.
+
+2005-02-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Check for text relocations in constructed DSOs.
+
+	* eblstrtab.c: Minor cleanups.
+
+	* Makefile.am (AM_CFLAGS): Add -std=gnu99 and -fmudflap for MUDFLAP.
+
+2004-08-16  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (AM_CFLAGS): Add LIBSTR definition with base name of
+	the lib directory.
+	* eblopenbackend.c (openbackend): Use LIBSTR instead of hardcoded
+	lib in path to ebl modules.
+
+2004-04-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Add rules for ppc and ppc64 ebl module.
+	* ppc_init..c: New file.
+	* ppc_destr.c: New file.
+	* ppc_symbol.c: New file.
+	* libebl_ppc.h: New file.
+	* libebl_ppc.map: New file.
+	* ppc64_init..c: New file.
+	* ppc64_destr.c: New file.
+	* ppc64_symbol.c: New file.
+	* libebl_ppc64.h: New file.
+	* libebl_ppc64.map: New file.
+
+2004-01-20  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Support building with mudflap.
+
+2004-01-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* libeblP.h (_): Use elfutils domain.
+
+2004-01-16  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblsectionname.c: Add support for SHN_BEFORE and SHN_AFTER.
+
+2004-01-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblsegmenttypename.c ((ebl_segment_type_name): Add support for
+	PT_GNU_RELRO.
+
+2004-01-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* libebl.h: Remove last traces of libtool.
+
+2004-01-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf-knowledge.h: Move to libelf subdir.
+
+	* Makefile.am (EXTRA_DIST): Remove libebl.map.
+	* libebl.map: Removed.
+
+2003-12-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblsectiontypename.c (ebl_section_type_name): Add support for
+	SHT_SUNW_move, SHT_CHECKSUM, and SHT_GNU_LIBLIST.
+
+2003-11-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* ia64_symbol.c (ia64_dynamic_tag_name): New function.
+	* libebl_ia64.h (ia64_dynamic_tag_name): Declare.
+	* ia64_init.c (ia64_init): Register i164_dynamic_tag_name.
+
+2003-09-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* ia64_init.c (ia64_init): Initialize segment_type_name callback.
+	* ia64_symbol.c (ia64_segment_type_name): Define.
+	* libebl_ia64.h (ia64_segment_type_name): Declare.
+
+2003-09-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (AM_CFLAGS): Add -fpic.
+
+2003-08-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (install): Remove dependency on libebl.so.
+
+2003-08-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblopenbackend.c: Adjust relative path to arch-specific DSOs
+	assuming the code ends up in the application.  Add second dlopen()
+	try without any path, just the filename.
+	* Makefile.in: Remove rules to build and install libebl.so.
+
+2003-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+        * Moved to CVS archive.
diff --git a/libebl/Makefile.am b/libebl/Makefile.am
new file mode 100644
index 0000000..5f7be50
--- /dev/null
+++ b/libebl/Makefile.am
@@ -0,0 +1,201 @@
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
+##
+## This program is Open Source software; you can redistribute it and/or
+## modify it under the terms of the Open Software License version 1.0 as
+## published by the Open Source Initiative.
+##
+## You should have received a copy of the Open Software License along
+## with this program; if not, you may obtain a copy of the Open Software
+## License version 1.0 from http://www.opensource.org/licenses/osl.php or
+## by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+## 3001 King Ranch Road, Ukiah, CA 95482.
+##
+DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DOBJDIR=\"$(shell pwd)\"
+if MUDFLAP
+AM_CFLAGS = -fmudflap
+else
+AM_CFLAGS =
+endif
+AM_CFLAGS += -fpic -Wall -Wshadow -Werror -Wunused -Wextra -Wformat=2 \
+	     -std=gnu99
+
+INCLUDES = -I$(srcdir) -I$(top_srcdir)/libelf -I$(top_srcdir)/lib -I..
+VERSION = 1
+PACKAGE_VERSION = @PACKAGE_VERSION@
+LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
+
+lib_LIBRARIES = libebl.a
+modules = i386 sh x86_64 ia64 alpha arm sparc ppc ppc64
+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)
+
+euincludedir = $(includedir)/elfutils
+euinclude_HEADERS = libebl.h
+
+gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \
+	      eblreloctypename.c eblsegmenttypename.c \
+	      eblsectiontypename.c eblmachineflagname.c \
+	      eblsymboltypename.c ebldynamictagname.c eblsectionname.c \
+	      eblobjecttypename.c eblsymbolbindingname.c \
+	      eblbackendname.c eblshflagscombine.c eblwstrtab.c \
+	      eblgstrtab.c eblosabiname.c eblmachineflagcheck.c \
+	      eblreloctypecheck.c eblrelocvaliduse.c eblrelocsimpletype.c \
+	      ebldynamictagcheck.c eblcorenotetypename.c eblobjnotetypename.c \
+	      eblcorenote.c eblobjnote.c ebldebugscnp.c \
+	      eblgotpcreloccheck.c eblcopyrelocp.c eblsectionstripp.c
+
+libebl_a_SOURCES = $(gen_SOURCES)
+
+i386_SRCS = i386_init.c i386_destr.c i386_symbol.c i386_corenote.c
+libebl_i386_pic_a_SOURCES = $(i386_SRCS)
+am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os)
+
+if MUDFLAP
+libelf = ../libelf/libelf.a
+libmudflap = -lmudflap
+else
+libelf = ../libelf/libelf.so
+libmudflap =
+endif
+
+textrel_check = if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi
+
+libebl_i386_so_SOURCES =
+libebl_i386.so: libebl_i386_pic.a libebl_i386.map
+	$(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
+	      -Wl,--version-script,$(srcdir)/libebl_i386.map \
+	      -Wl,-z,defs $(libelf) $(libmudflap)
+	$(textrel_check)
+
+
+sh_SRCS = sh_init.c sh_destr.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
+	$(CC) -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
+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
+	$(CC) -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
+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
+	$(CC) -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
+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
+	$(CC) -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
+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
+	$(CC) -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
+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
+	$(CC) -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
+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
+	$(CC) -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
+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
+	$(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
+	      -Wl,--version-script,$(srcdir)/libebl_ppc64.map \
+	      -Wl,-z,defs $(libelf) $(libmudflap)
+	$(textrel_check)
+
+
+%.os: %.c %.o
+	if $(COMPILE) -c -o $@ -fpic -DPIC -DSHARED -MT $@ -MD -MP \
+	  -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \
+	then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \
+	     rm -f "$(DEPDIR)/$*.Tpo"; \
+	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+	fi
+
+install: install-am install-ebl-modules
+install-ebl-modules:
+	$(mkinstalldirs) $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)
+	for m in $(modules); do \
+	  $(INSTALL_PROGRAM) libebl_$${m}.so $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}-$(PACKAGE_VERSION).so; \
+	  ln -fs libebl_$${m}-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}.so; \
+	done
+
+uninstall: uninstall-am
+	for m in $(modules); do \
+	  rm -f $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}-$(PACKAGE_VERSION).so; \
+	  rm -f $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}.so; \
+	done
+	rmdir --ignore-fail-on-non-empty $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)
+	rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils
+
+noinst_HEADERS = libeblP.h $(noinst_LIBRARIES:%_pic.a=%.h)
+EXTRA_DIST = $(noinst_LIBRARIES:%_pic.a=%.map) \
+	     $(foreach m,$(modules),$($(m)_SRCS))
+
+CLEANFILES = $(am_libebl_pic_a_OBJECTS) \
+	     $(foreach m,$(modules),$(am_libebl_$(m)_pic_a_OBJECTS))
diff --git a/libebl/alpha_destr.c b/libebl/alpha_destr.c
new file mode 100644
index 0000000..4fc5cf8
--- /dev/null
+++ b/libebl/alpha_destr.c
@@ -0,0 +1,27 @@
+/* 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
new file mode 100644
index 0000000..17eff37
--- /dev/null
+++ b/libebl/alpha_init.c
@@ -0,0 +1,41 @@
+/* Initialization of 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>
+
+
+const char *
+alpha_init (elf, machine, eh, ehlen)
+     Elf *elf __attribute__ ((unused));
+     GElf_Half machine __attribute__ ((unused));
+     Ebl *eh;
+     size_t ehlen;
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "Alpha";
+  eh->reloc_type_name = alpha_reloc_type_name;
+  eh->reloc_type_check = alpha_reloc_type_check;
+  eh->copy_reloc_p = alpha_copy_reloc_p;
+  eh->destr = alpha_destr;
+
+  return MODVERSION;
+}
diff --git a/libebl/alpha_symbol.c b/libebl/alpha_symbol.c
new file mode 100644
index 0000000..49e7c72
--- /dev/null
+++ b/libebl/alpha_symbol.c
@@ -0,0 +1,101 @@
+/* Alpha specific symbolic name handling.
+   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 <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;
+}
+
+/* Check whether given relocation is a copy relocation.  */
+bool
+alpha_copy_reloc_p (int reloc)
+{
+  return reloc == R_ALPHA_COPY;
+}
diff --git a/libebl/arm_destr.c b/libebl/arm_destr.c
new file mode 100644
index 0000000..2675720
--- /dev/null
+++ b/libebl/arm_destr.c
@@ -0,0 +1,27 @@
+/* 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
new file mode 100644
index 0000000..a0a65f8
--- /dev/null
+++ b/libebl/arm_init.c
@@ -0,0 +1,41 @@
+/* Initialization of 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>
+
+
+const char *
+arm_init (elf, machine, eh, ehlen)
+     Elf *elf __attribute__ ((unused));
+     GElf_Half machine __attribute__ ((unused));
+     Ebl *eh;
+     size_t ehlen;
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "Arm";
+  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;
+
+  return MODVERSION;
+}
diff --git a/libebl/arm_symbol.c b/libebl/arm_symbol.c
new file mode 100644
index 0000000..f4de8be
--- /dev/null
+++ b/libebl/arm_symbol.c
@@ -0,0 +1,121 @@
+/* Arm specific symbolic name handling.
+   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 <elf.h>
+#include <stddef.h>
+
+#include <libebl_arm.h>
+
+
+/* Return of the backend.  */
+const char *
+arm_backend_name (void)
+{
+  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;
+}
diff --git a/libebl/eblbackendname.c b/libebl/eblbackendname.c
new file mode 100644
index 0000000..03830eb
--- /dev/null
+++ b/libebl/eblbackendname.c
@@ -0,0 +1,28 @@
+/* Return backend name.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   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 <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_backend_name (ebl)
+     Ebl *ebl;
+{
+  return ebl != NULL ? ebl->emulation : gettext ("No backend");
+}
diff --git a/libebl/eblclosebackend.c b/libebl/eblclosebackend.c
new file mode 100644
index 0000000..c557961
--- /dev/null
+++ b/libebl/eblclosebackend.c
@@ -0,0 +1,39 @@
+/* Free ELF backend handle.
+   Copyright (C) 2000, 2001, 2002 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 <dlfcn.h>
+#include <stdlib.h>
+
+#include <libeblP.h>
+
+
+void
+ebl_closebackend (Ebl *ebl)
+{
+  if (ebl != NULL)
+    {
+      /* Run the destructor.  */
+      ebl->destr (ebl);
+
+      /* Close the dynamically loaded object.  */
+      if (ebl->dlhandle != NULL)
+	(void) dlclose (ebl->dlhandle);
+
+      /* Free the resources.  */
+      free (ebl);
+    }
+}
diff --git a/libebl/eblcopyrelocp.c b/libebl/eblcopyrelocp.c
new file mode 100644
index 0000000..2d3362a
--- /dev/null
+++ b/libebl/eblcopyrelocp.c
@@ -0,0 +1,28 @@
+/* Check whether given relocation is a copy relocation.
+   Copyright (C) 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This program is Open Source software; you can redistribute it and/or
+   modify it under the terms of the Open Software License version 1.0 as
+   published by the Open Source Initiative.
+
+   You should have received a copy of the Open Software License along
+   with this program; if not, you may obtain a copy of the Open Software
+   License version 1.0 from http://www.opensource.org/licenses/osl.php or
+   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+   3001 King Ranch Road, Ukiah, CA 95482.   */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_copy_reloc_p (ebl, reloc)
+     Ebl *ebl;
+     int reloc;
+{
+  return ebl->copy_reloc_p (reloc);
+}
diff --git a/libebl/eblcorenote.c b/libebl/eblcorenote.c
new file mode 100644
index 0000000..725d3a1
--- /dev/null
+++ b/libebl/eblcorenote.c
@@ -0,0 +1,191 @@
+/* Print contents of core note.
+   Copyright (C) 2002, 2004, 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 <assert.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <libeblP.h>
+
+
+void
+ebl_core_note (ebl, name, type, descsz, desc)
+     Ebl *ebl;
+     const char *name;
+     uint32_t type;
+     uint32_t descsz;
+     const char *desc;
+{
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (ebl->elf, &ehdr_mem);
+  assert (ehdr != NULL);
+  int class = ehdr->e_ident[EI_CLASS];
+  int endian = ehdr->e_ident[EI_DATA];
+
+  if (! ebl->core_note (name, type, descsz, desc))
+    /* The machine specific function did not know this type.  */
+    switch (type)
+      {
+      case NT_PLATFORM:
+	printf (gettext ("    Platform: %.*s\n"), (int) descsz, desc);
+	break;
+
+      case NT_AUXV:
+	;
+	size_t elsize = (class == ELFCLASS32
+			 ? sizeof (Elf32_auxv_t) : sizeof (Elf64_auxv_t));
+
+	for (size_t cnt = 0; (cnt + 1) * elsize <= descsz; ++cnt)
+	  {
+	    uintmax_t atype;
+	    uintmax_t val;
+
+	    if (class == ELFCLASS32)
+	      {
+		Elf32_auxv_t *auxv = &((Elf32_auxv_t *) desc)[cnt];
+
+		if ((endian == ELFDATA2LSB && __BYTE_ORDER == __LITTLE_ENDIAN)
+		    || (endian == ELFDATA2MSB && __BYTE_ORDER == __BIG_ENDIAN))
+		  {
+		    atype = auxv->a_type;
+		    val = auxv->a_un.a_val;
+		  }
+		else
+		  {
+		    atype = bswap_32 (auxv->a_type);
+		    val = bswap_32 (auxv->a_un.a_val);
+		  }
+	      }
+	    else
+	      {
+		Elf64_auxv_t *auxv = &((Elf64_auxv_t *) desc)[cnt];
+
+		if ((endian == ELFDATA2LSB && __BYTE_ORDER == __LITTLE_ENDIAN)
+		    || (endian == ELFDATA2MSB && __BYTE_ORDER == __BIG_ENDIAN))
+		  {
+		    atype = auxv->a_type;
+		    val = auxv->a_un.a_val;
+		  }
+		else
+		  {
+		    atype = bswap_64 (auxv->a_type);
+		    val = bswap_64 (auxv->a_un.a_val);
+		  }
+	      }
+
+	    /* XXX Do we need the auxiliary vector info anywhere
+	       else?  If yes, move code into a separate function.  */
+	    const char *at;
+
+	    switch (atype)
+	      {
+#define NEW_AT(name) case AT_##name: at = #name; break
+		NEW_AT (NULL);
+		NEW_AT (IGNORE);
+		NEW_AT (EXECFD);
+		NEW_AT (PHDR);
+		NEW_AT (PHENT);
+		NEW_AT (PHNUM);
+		NEW_AT (PAGESZ);
+		NEW_AT (BASE);
+		NEW_AT (FLAGS);
+		NEW_AT (ENTRY);
+		NEW_AT (NOTELF);
+		NEW_AT (UID);
+		NEW_AT (EUID);
+		NEW_AT (GID);
+		NEW_AT (EGID);
+		NEW_AT (CLKTCK);
+		NEW_AT (PLATFORM);
+		NEW_AT (HWCAP);
+		NEW_AT (FPUCW);
+		NEW_AT (DCACHEBSIZE);
+		NEW_AT (ICACHEBSIZE);
+		NEW_AT (UCACHEBSIZE);
+		NEW_AT (IGNOREPPC);
+		NEW_AT (SECURE);
+		NEW_AT (SYSINFO);
+		NEW_AT (SYSINFO_EHDR);
+		NEW_AT (L1I_CACHESHAPE);
+		NEW_AT (L1D_CACHESHAPE);
+		NEW_AT (L2_CACHESHAPE);
+		NEW_AT (L3_CACHESHAPE);
+
+	      default:;
+		static char buf[30];
+		sprintf (buf, "%ju (AT_?""?""?)", atype);
+		at = buf;
+		break;
+	      }
+
+	    switch (atype)
+	      {
+	      case AT_NULL:
+	      case AT_IGNORE:
+	      case AT_IGNOREPPC:
+	      case AT_NOTELF:
+	      default:
+		printf ("    %s\n", at);
+		break;
+
+	      case AT_EXECFD:
+	      case AT_PHENT:
+	      case AT_PHNUM:
+	      case AT_PAGESZ:
+	      case AT_UID:
+	      case AT_EUID:
+	      case AT_GID:
+	      case AT_EGID:
+	      case AT_CLKTCK:
+	      case AT_FPUCW:
+	      case AT_DCACHEBSIZE:
+	      case AT_ICACHEBSIZE:
+	      case AT_UCACHEBSIZE:
+	      case AT_SECURE:
+	      case AT_L1I_CACHESHAPE:
+	      case AT_L1D_CACHESHAPE:
+	      case AT_L2_CACHESHAPE:
+	      case AT_L3_CACHESHAPE:
+		printf ("    %s: %jd\n", at, val);
+		break;
+
+	      case AT_PHDR:
+	      case AT_BASE:
+	      case AT_FLAGS:	/* XXX Print flags?  */
+	      case AT_ENTRY:
+	      case AT_PLATFORM:	/* XXX Get string?  */
+	      case AT_HWCAP:	/* XXX Print flags?  */
+	      case AT_SYSINFO:
+	      case AT_SYSINFO_EHDR:
+		printf ("    %s: %#jx\n", at, val);
+		break;
+	      }
+
+	    if (atype == AT_NULL)
+	      /* Reached the end.  */
+	      break;
+	  }
+	break;
+
+      default:
+	/* Unknown type.  */
+	break;
+      }
+}
diff --git a/libebl/eblcorenotetypename.c b/libebl/eblcorenotetypename.c
new file mode 100644
index 0000000..4a94d2b
--- /dev/null
+++ b/libebl/eblcorenotetypename.c
@@ -0,0 +1,68 @@
+/* Return note type name.
+   Copyright (C) 2002 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 <inttypes.h>
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_core_note_type_name (ebl, type, buf, len)
+     Ebl *ebl;
+     uint32_t type;
+     char *buf;
+     size_t len;
+{
+  const char *res = ebl->core_note_type_name (type, buf, len);
+
+  if (res == NULL)
+    {
+      static const char *knowntypes[] =
+	{
+#define KNOWNSTYPE(name) [NT_##name] = #name
+	  KNOWNSTYPE (PRSTATUS),
+	  KNOWNSTYPE (FPREGSET),
+	  KNOWNSTYPE (PRPSINFO),
+	  KNOWNSTYPE (TASKSTRUCT),
+	  KNOWNSTYPE (PLATFORM),
+	  KNOWNSTYPE (AUXV),
+	  KNOWNSTYPE (GWINDOWS),
+	  KNOWNSTYPE (ASRS),
+	  KNOWNSTYPE (PSTATUS),
+	  KNOWNSTYPE (PSINFO),
+	  KNOWNSTYPE (PRCRED),
+	  KNOWNSTYPE (UTSNAME),
+	  KNOWNSTYPE (LWPSTATUS),
+	  KNOWNSTYPE (LWPSINFO),
+	  KNOWNSTYPE (PRFPXREG)
+	};
+
+      /* Handle standard names.  */
+      if (type < sizeof (knowntypes) / sizeof (knowntypes[0])
+	  && knowntypes[type] != NULL)
+	res = knowntypes[type];
+      else
+	{
+	  snprintf (buf, len, "%s: %" PRIu32, gettext ("<unknown>"), type);
+
+	  res = buf;
+	}
+    }
+
+  return res;
+}
diff --git a/libebl/ebldebugscnp.c b/libebl/ebldebugscnp.c
new file mode 100644
index 0000000..59310b5
--- /dev/null
+++ b/libebl/ebldebugscnp.c
@@ -0,0 +1,29 @@
+/* Check section name for being that of a debug informatino section.
+   Copyright (C) 2002 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 <stdint.h>
+#include <libeblP.h>
+
+
+bool
+ebl_debugscn_p (ebl, name)
+     Ebl *ebl;
+     const char *name;
+{
+  return ebl->debugscn_p (name);
+}
diff --git a/libebl/ebldynamictagcheck.c b/libebl/ebldynamictagcheck.c
new file mode 100644
index 0000000..68b4169
--- /dev/null
+++ b/libebl/ebldynamictagcheck.c
@@ -0,0 +1,41 @@
+/* Check dynamic tag.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This program is Open Source software; you can redistribute it and/or
+   modify it under the terms of the Open Software License version 1.0 as
+   published by the Open Source Initiative.
+
+   You should have received a copy of the Open Software License along
+   with this program; if not, you may obtain a copy of the Open Software
+   License version 1.0 from http://www.opensource.org/licenses/osl.php or
+   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+   3001 King Ranch Road, Ukiah, CA 95482.   */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <libeblP.h>
+
+
+bool
+ebl_dynamic_tag_check (ebl, tag)
+     Ebl *ebl;
+     int64_t tag;
+{
+  bool res = ebl != NULL ? ebl->dynamic_tag_check (tag) : false;
+
+  if (!res
+      && ((tag >= 0 && tag < DT_NUM)
+	  || (tag >= DT_GNU_PRELINKED && tag <= DT_SYMINENT)
+	  || (tag >= DT_GNU_CONFLICT && tag <= DT_SYMINFO)
+	  || tag == DT_VERSYM
+	  || (tag >= DT_RELACOUNT && tag <= DT_VERNEEDNUM)
+	  || tag == DT_AUXILIARY
+	  || tag == DT_FILTER))
+    res = true;
+
+  return res;
+}
diff --git a/libebl/ebldynamictagname.c b/libebl/ebldynamictagname.c
new file mode 100644
index 0000000..464c1e2
--- /dev/null
+++ b/libebl/ebldynamictagname.c
@@ -0,0 +1,97 @@
+/* Return dynamic tag name.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This program is Open Source software; you can redistribute it and/or
+   modify it under the terms of the Open Software License version 1.0 as
+   published by the Open Source Initiative.
+
+   You should have received a copy of the Open Software License along
+   with this program; if not, you may obtain a copy of the Open Software
+   License version 1.0 from http://www.opensource.org/licenses/osl.php or
+   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+   3001 King Ranch Road, Ukiah, CA 95482.   */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_dynamic_tag_name (ebl, tag, buf, len)
+     Ebl *ebl;
+     int64_t tag;
+     char *buf;
+     size_t len;
+{
+  const char *res = ebl != NULL ? ebl->dynamic_tag_name (tag, buf, len) : NULL;
+
+  if (res == NULL)
+    {
+      if (tag >= 0 && tag < DT_NUM)
+	{
+	  static const char *stdtags[] =
+	    {
+	      "NULL", "NEEDED", "PLTRELSZ", "PLTGOT", "HASH", "STRTAB",
+	      "SYMTAB", "RELA", "RELASZ", "RELAENT", "STRSZ", "SYMENT",
+	      "INIT", "FINI", "SONAME", "RPATH", "SYMBOLIC", "REL", "RELSZ",
+	      "RELENT", "PLTREL", "DEBUG", "TEXTREL", "JMPREL", "BIND_NOW",
+	      "INIT_ARRAY", "FINI_ARRAY", "INIT_ARRAYSZ", "FINI_ARRAYSZ",
+	      "RUNPATH", "FLAGS", "ENCODING", "PREINIT_ARRAY",
+	      "PREINIT_ARRAYSZ"
+	    };
+
+	  res = stdtags[tag];
+	}
+      else if (tag == DT_VERSYM)
+	res = "VERSYM";
+      else if (tag >= DT_GNU_PRELINKED && tag <= DT_SYMINENT)
+	{
+	  static const char *valrntags[] =
+	    {
+	      "GNU_PRELINKED", "GNU_CONFLICTSZ", "GNU_LIBLISTSZ",
+	      "CHECKSUM", "PLTPADSZ", "MOVEENT", "MOVESZ", "FEATURE_1",
+	      "POSFLAG_1", "SYMINSZ", "SYMINENT"
+	    };
+
+	  res = valrntags[tag - DT_GNU_PRELINKED];
+	}
+      else if (tag >= DT_GNU_CONFLICT && tag <= DT_SYMINFO)
+	{
+	  static const char *addrrntags[] =
+	    {
+	      "GNU_CONFLICT", "GNU_LIBLIST", "CONFIG", "DEPAUDIT", "AUDIT",
+	      "PLTPAD", "MOVETAB", "SYMINFO"
+	    };
+
+	  res = addrrntags[tag - DT_GNU_CONFLICT];
+	}
+      else if (tag >= DT_RELACOUNT && tag <= DT_VERNEEDNUM)
+	{
+	  static const char *suntags[] =
+	    {
+	      "RELACOUNT", "RELCOUNT", "FLAGS_1", "VERDEF", "VERDEFNUM",
+	      "VERNEED", "VERNEEDNUM"
+	    };
+
+	  res = suntags[tag - DT_RELACOUNT];
+	}
+      else if (tag == DT_AUXILIARY)
+	res = "AUXILIARY";
+      else if (tag == DT_FILTER)
+	res = "FILTER";
+      else
+	{
+	  snprintf (buf, len, gettext ("<unknown>: %" PRId64), tag);
+
+	  res = buf;
+
+	}
+    }
+
+  return res;
+}
diff --git a/libebl/eblgotpcreloccheck.c b/libebl/eblgotpcreloccheck.c
new file mode 100644
index 0000000..8ae8b7b
--- /dev/null
+++ b/libebl/eblgotpcreloccheck.c
@@ -0,0 +1,29 @@
+/* Return true if the symbol type is that referencing the GOT.  E.g.,
+   R_386_GOTPC.
+   Copyright (C) 2003 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   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 <libeblP.h>
+
+
+bool
+ebl_gotpc_reloc_check (ebl, reloc)
+     Ebl *ebl;
+     int reloc;
+{
+  return ebl != NULL ? ebl->gotpc_reloc_check (ebl->elf, reloc) : false;
+}
diff --git a/libebl/eblgstrtab.c b/libebl/eblgstrtab.c
new file mode 100644
index 0000000..57cb2d8
--- /dev/null
+++ b/libebl/eblgstrtab.c
@@ -0,0 +1,350 @@
+/* Generic string table handling.
+   Copyright (C) 2000, 2001, 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 <assert.h>
+#include <inttypes.h>
+#include <libelf.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+#include "libebl.h"
+
+#ifndef MIN
+# define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+
+struct Ebl_GStrent
+{
+  const char *string;
+  size_t len;
+  struct Ebl_GStrent *next;
+  struct Ebl_GStrent *left;
+  struct Ebl_GStrent *right;
+  size_t offset;
+  unsigned int width;
+  char reverse[0];
+};
+
+
+struct memoryblock
+{
+  struct memoryblock *next;
+  char memory[0];
+};
+
+
+struct Ebl_GStrtab
+{
+  struct Ebl_GStrent *root;
+  struct memoryblock *memory;
+  char *backp;
+  size_t left;
+  size_t total;
+  unsigned int width;
+  bool nullstr;
+
+  struct Ebl_GStrent null;
+};
+
+
+/* Cache for the pagesize.  We correct this value a bit so that `malloc'
+   is not allocating more than a page.  */
+static size_t ps;
+
+
+struct Ebl_GStrtab *
+ebl_gstrtabinit (unsigned int width, bool nullstr)
+{
+  struct Ebl_GStrtab *ret;
+
+  if (ps == 0)
+    {
+      ps = sysconf (_SC_PAGESIZE) - 2 * sizeof (void *);
+      assert (sizeof (struct memoryblock) < ps);
+    }
+
+  ret = (struct Ebl_GStrtab *) calloc (1, sizeof (struct Ebl_GStrtab));
+  if (ret != NULL)
+    {
+      ret->width = width;
+      ret->nullstr = nullstr;
+
+      if (nullstr)
+	{
+	  ret->null.len = 1;
+	  ret->null.string = (char *) calloc (1, width);
+	}
+    }
+
+  return ret;
+}
+
+
+static void
+morememory (struct Ebl_GStrtab *st, size_t len)
+{
+  struct memoryblock *newmem;
+
+  if (len < ps)
+    len = ps;
+  newmem = (struct memoryblock *) malloc (len);
+  if (newmem == NULL)
+    abort ();
+
+  newmem->next = st->memory;
+  st->memory = newmem;
+  st->backp = newmem->memory;
+  st->left = len - offsetof (struct memoryblock, memory);
+}
+
+
+void
+ebl_gstrtabfree (struct Ebl_GStrtab *st)
+{
+  struct memoryblock *mb = st->memory;
+
+  while (mb != NULL)
+    {
+      void *old = mb;
+      mb = mb->next;
+      free (old);
+    }
+
+  if (st->null.string != NULL)
+    free ((char *) st->null.string);
+
+  free (st);
+}
+
+
+static struct Ebl_GStrent *
+newstring (struct Ebl_GStrtab *st, const char *str, size_t len)
+{
+  /* Compute the amount of padding needed to make the structure aligned.  */
+  size_t align = ((__alignof__ (struct Ebl_GStrent)
+		   - (((uintptr_t) st->backp)
+		      & (__alignof__ (struct Ebl_GStrent) - 1)))
+		  & (__alignof__ (struct Ebl_GStrent) - 1));
+
+  /* Make sure there is enough room in the memory block.  */
+  if (st->left < align + sizeof (struct Ebl_GStrent) + len * st->width)
+    {
+      morememory (st, sizeof (struct Ebl_GStrent) + len * st->width);
+      align = 0;
+    }
+
+  /* Create the reserved string.  */
+  struct Ebl_GStrent *newstr = (struct Ebl_GStrent *) (st->backp + align);
+  newstr->string = str;
+  newstr->len = len;
+  newstr->width = st->width;
+  newstr->next = NULL;
+  newstr->left = NULL;
+  newstr->right = NULL;
+  newstr->offset = 0;
+  for (int i = len - 2; i >= 0; --i)
+    for (int j = st->width - 1; j >= 0; --j)
+      newstr->reverse[i * st->width + j] = str[(len - 2 - i) * st->width + j];
+  for (size_t j = 0; j < st->width; ++j)
+    newstr->reverse[(len - 1) * st->width + j] = '\0';
+  st->backp += align + sizeof (struct Ebl_GStrent) + len * st->width;
+  st->left -= align + sizeof (struct Ebl_GStrent) + len * st->width;
+
+  return newstr;
+}
+
+
+/* XXX This function should definitely be rewritten to use a balancing
+   tree algorith (AVL, red-black trees).  For now a simple, correct
+   implementation is enough.  */
+static struct Ebl_GStrent **
+searchstring (struct Ebl_GStrent **sep, struct Ebl_GStrent *newstr)
+{
+  int cmpres;
+
+  /* More strings?  */
+  if (*sep == NULL)
+    {
+      *sep = newstr;
+      return sep;
+    }
+
+  /* Compare the strings.  */
+  cmpres = memcmp ((*sep)->reverse, newstr->reverse,
+		   (MIN ((*sep)->len, newstr->len) - 1) * (*sep)->width);
+  if (cmpres == 0)
+    /* We found a matching string.  */
+    return sep;
+  else if (cmpres > 0)
+    return searchstring (&(*sep)->left, newstr);
+  else
+    return searchstring (&(*sep)->right, newstr);
+}
+
+
+/* Add new string.  The actual string is assumed to be permanent.  */
+struct Ebl_GStrent *
+ebl_gstrtabadd (struct Ebl_GStrtab *st, const char *str, size_t len)
+{
+  struct Ebl_GStrent *newstr;
+  struct Ebl_GStrent **sep;
+
+  /* Compute the string length if the caller doesn't know it.  */
+  if (len == 0)
+    {
+      size_t j;
+
+      do
+	for (j = 0; j < st->width; ++j)
+	  if (str[len * st->width + j] != '\0')
+	    break;
+      while (j == st->width && ++len);
+    }
+
+  /* Make sure all "" strings get offset 0 but only if the table was
+     created with a special null entry in mind.  */
+  if (len == 1 && st->null.string != NULL)
+    return &st->null;
+
+  /* Allocate memory for the new string and its associated information.  */
+  newstr = newstring (st, str, len);
+
+  /* Search in the array for the place to insert the string.  If there
+     is no string with matching prefix and no string with matching
+     leading substring, create a new entry.  */
+  sep = searchstring (&st->root, newstr);
+  if (*sep != newstr)
+    {
+      /* This is not the same entry.  This means we have a prefix match.  */
+      if ((*sep)->len > newstr->len)
+	{
+	  struct Ebl_GStrent *subs;
+
+	  /* Check whether we already know this string.  */
+	  for (subs = (*sep)->next; subs != NULL; subs = subs->next)
+	    if (subs->len == newstr->len)
+	      {
+		/* We have an exact match with a substring.  Free the memory
+		   we allocated.  */
+		st->left += (st->backp - (char *) newstr) * st->width;
+		st->backp = (char *) newstr;
+
+		return subs;
+	      }
+
+	  /* We have a new substring.  This means we don't need the reverse
+	     string of this entry anymore.  */
+	  st->backp -= newstr->len;
+	  st->left += newstr->len;
+
+	  newstr->next = (*sep)->next;
+	  (*sep)->next = newstr;
+	}
+      else if ((*sep)->len != newstr->len)
+	{
+	  /* When we get here it means that the string we are about to
+	     add has a common prefix with a string we already have but
+	     it is longer.  In this case we have to put it first.  */
+	  st->total += newstr->len - (*sep)->len;
+	  newstr->next = *sep;
+	  newstr->left = (*sep)->left;
+	  newstr->right = (*sep)->right;
+	  *sep = newstr;
+	}
+      else
+	{
+	  /* We have an exact match.  Free the memory we allocated.  */
+	  st->left += (st->backp - (char *) newstr) * st->width;
+	  st->backp = (char *) newstr;
+
+	  newstr = *sep;
+	}
+    }
+  else
+    st->total += newstr->len;
+
+  return newstr;
+}
+
+
+static void
+copystrings (struct Ebl_GStrent *nodep, char **freep, size_t *offsetp)
+{
+  struct Ebl_GStrent *subs;
+
+  if (nodep->left != NULL)
+    copystrings (nodep->left, freep, offsetp);
+
+  /* Process the current node.  */
+  nodep->offset = *offsetp;
+  *freep = (char *) mempcpy (*freep, nodep->string, nodep->len * nodep->width);
+  *offsetp += nodep->len * nodep->width;
+
+  for (subs = nodep->next; subs != NULL; subs = subs->next)
+    {
+      assert (subs->len < nodep->len);
+      subs->offset = nodep->offset + (nodep->len - subs->len) * nodep->width;
+      assert (subs->offset != 0 || subs->string[0] == '\0');
+    }
+
+  if (nodep->right != NULL)
+    copystrings (nodep->right, freep, offsetp);
+}
+
+
+void
+ebl_gstrtabfinalize (struct Ebl_GStrtab *st, Elf_Data *data)
+{
+  size_t copylen;
+  char *endp;
+  size_t nulllen = st->nullstr ? st->width : 0;
+
+  /* Fill in the information.  */
+  data->d_buf = malloc (st->total + nulllen);
+  if (data->d_buf == NULL)
+    abort ();
+
+  /* The first byte must always be zero if we created the table with a
+     null string.  */
+  if (st->nullstr)
+    memset (data->d_buf, '\0', st->width);
+
+  data->d_type = ELF_T_BYTE;
+  data->d_size = st->total + nulllen;
+  data->d_off = 0;
+  data->d_align = 1;
+  data->d_version = EV_CURRENT;
+
+  /* Now run through the tree and add all the string while also updating
+     the offset members of the elfstrent records.  */
+  endp = (char *) data->d_buf + nulllen;
+  copylen = nulllen;
+  copystrings (st->root, &endp, &copylen);
+  assert (copylen == st->total * st->width + nulllen);
+}
+
+
+size_t
+ebl_gstrtaboffset (struct Ebl_GStrent *se)
+{
+  return se->offset;
+}
diff --git a/libebl/eblmachineflagcheck.c b/libebl/eblmachineflagcheck.c
new file mode 100644
index 0000000..abc8d30
--- /dev/null
+++ b/libebl/eblmachineflagcheck.c
@@ -0,0 +1,28 @@
+/* Check machine flag.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   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 <libeblP.h>
+
+
+bool
+ebl_machine_flag_check (ebl, flags)
+     Ebl *ebl;
+     Elf64_Word flags;
+{
+  return ebl != NULL ? ebl->machine_flag_check (flags) : (flags == 0);
+}
diff --git a/libebl/eblmachineflagname.c b/libebl/eblmachineflagname.c
new file mode 100644
index 0000000..228a994
--- /dev/null
+++ b/libebl/eblmachineflagname.c
@@ -0,0 +1,76 @@
+/* Return machine flag names.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   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 <stdio.h>
+#include <string.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_machine_flag_name (ebl, flags, buf, len)
+     Ebl *ebl;
+     Elf64_Word flags;
+     char *buf;
+     size_t len;
+{
+  const char *res;
+
+  if (flags == 0)
+    res = "";
+  else
+    {
+      char *cp = buf;
+      int first = 1;
+      const char *machstr;
+      size_t machstrlen;
+
+      do
+	{
+	  if (! first)
+	    {
+	      if (cp + 1 >= buf + len)
+		break;
+	      *cp++ = ',';
+	    }
+
+	  machstr = ebl != NULL ? ebl->machine_flag_name (&flags) : NULL;
+	  if (machstr == NULL)
+	    {
+	      /* No more known flag.  */
+	      snprintf (cp, buf + len - cp, "%#x", flags);
+	      break;
+	    }
+
+	  machstrlen = strlen (machstr) + 1;
+	  if ((size_t) (buf + len - cp) < machstrlen)
+	    {
+	      *((char *) mempcpy (cp, machstr, buf + len - cp - 1)) = '\0';
+	      break;
+	    }
+
+	  cp = mempcpy (cp, machstr, machstrlen);
+
+	  first = 0;
+	}
+      while (flags != 0);
+
+      res = buf;
+    }
+
+  return res;
+}
diff --git a/libebl/eblobjecttypename.c b/libebl/eblobjecttypename.c
new file mode 100644
index 0000000..c099c71
--- /dev/null
+++ b/libebl/eblobjecttypename.c
@@ -0,0 +1,48 @@
+/* Return object file type name.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   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 <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_object_type_name (ebl, object, buf, len)
+     Ebl *ebl;
+     int object;
+     char *buf;
+     size_t len;
+{
+  const char *res;
+
+  res = ebl != NULL ? ebl->object_type_name (object, buf, len) : NULL;
+  if (res == NULL)
+    {
+      /* Handle OS-specific section names.  */
+      if (object >= ET_LOOS && object <= ET_HIOS)
+	snprintf (buf, len, "LOOS+%x", object - ET_LOOS);
+      /* Handle processor-specific section names.  */
+      else if (object >= ET_LOPROC && object <= ET_HIPROC)
+	snprintf (buf, len, "LOPROC+%x", object - ET_LOPROC);
+      else
+	snprintf (buf, len, "%s: %d", gettext ("<unknown>"), object);
+
+      res = buf;
+    }
+
+  return res;
+}
diff --git a/libebl/eblobjnote.c b/libebl/eblobjnote.c
new file mode 100644
index 0000000..5adff18
--- /dev/null
+++ b/libebl/eblobjnote.c
@@ -0,0 +1,87 @@
+/* Print contents of object file note.
+   Copyright (C) 2002 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 <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <libeblP.h>
+
+
+void
+ebl_object_note (ebl, name, type, descsz, desc)
+     Ebl *ebl;
+     const char *name;
+     uint32_t type;
+     uint32_t descsz;
+     const char *desc;
+{
+  if (! ebl->object_note (name, type, descsz, desc))
+    /* The machine specific function did not know this type.  */
+    switch (type)
+      {
+      case NT_VERSION:
+	if (strcmp (name, "GNU") == 0 && descsz >= 8)
+	  {
+	    struct
+	    {
+	      uint32_t os;
+	      uint32_t version[descsz / 4 - 1];
+	    } *tag = (__typeof (tag)) desc;
+
+	    const char *os;
+	    switch (tag->os)
+	      {
+	      case ELF_NOTE_OS_LINUX:
+		os = "Linux";
+		break;
+
+	      case ELF_NOTE_OS_GNU:
+		os = "GNU";
+		break;
+
+	      case ELF_NOTE_OS_SOLARIS2:
+		os = "Solaris";
+		break;
+
+	      case ELF_NOTE_OS_FREEBSD:
+		os = "FreeBSD";
+		break;
+
+	      default:
+		os = "???";
+		break;
+	      }
+
+	    printf (gettext ("    OS: %s, ABI: "), os);
+	    size_t cnt;
+	    for (cnt = 0; cnt < descsz / 4 - 1; ++cnt)
+	      {
+		if (cnt != 0)
+		  putchar_unlocked ('.');
+		printf ("%" PRIu32, tag->version[cnt]);
+	      }
+	    putchar_unlocked ('\n');
+	    break;
+	  }
+	/* FALLTHROUGH */
+
+      default:
+	/* Unknown type.  */
+	break;
+      }
+}
diff --git a/libebl/eblobjnotetypename.c b/libebl/eblobjnotetypename.c
new file mode 100644
index 0000000..a963cef
--- /dev/null
+++ b/libebl/eblobjnotetypename.c
@@ -0,0 +1,54 @@
+/* Return note type name.
+   Copyright (C) 2002 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 <inttypes.h>
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_object_note_type_name (ebl, type, buf, len)
+     Ebl *ebl;
+     uint32_t type;
+     char *buf;
+     size_t len;
+{
+  const char *res = ebl->object_note_type_name (type, buf, len);
+
+  if (res == NULL)
+    {
+      static const char *knowntypes[] =
+	{
+#define KNOWNSTYPE(name) [NT_##name] = #name
+	  KNOWNSTYPE (VERSION),
+	};
+
+      /* Handle standard names.  */
+      if (type < sizeof (knowntypes) / sizeof (knowntypes[0])
+	  && knowntypes[type] != NULL)
+	res = knowntypes[type];
+      else
+	{
+	  snprintf (buf, len, "%s: %" PRIu32, gettext ("<unknown>"), type);
+
+	  res = buf;
+	}
+    }
+
+  return res;
+}
diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c
new file mode 100644
index 0000000..dc2f7c3
--- /dev/null
+++ b/libebl/eblopenbackend.c
@@ -0,0 +1,551 @@
+/* Generate ELF backend handle.
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
+
+   This program is Open Source software; you can redistribute it and/or
+   modify it under the terms of the Open Software License version 1.0 as
+   published by the Open Source Initiative.
+
+   You should have received a copy of the Open Software License along
+   with this program; if not, you may obtain a copy of the Open Software
+   License version 1.0 from http://www.opensource.org/licenses/osl.php or
+   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+   3001 King Ranch Road, Ukiah, CA 95482.   */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <error.h>
+#include <gelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libeblP.h>
+
+
+/* This table should contain the complete list of architectures as far
+   as the ELF specification is concerned.  */
+/* XXX When things are stable replace the string pointers with char
+   arrays to avoid relocations.  */
+static const struct
+{
+  const char *dsoname;
+  const char *emulation;
+  const char *prefix;
+  int prefix_len;
+  int em;
+} machines[] =
+{
+  { "i386", "elf_i386", "i386", 4, EM_386 },
+  { "ia64", "elf_ia64", "ia64", 4, EM_IA_64 },
+  { "alpha", "elf_alpha", "alpha", 5, EM_ALPHA },
+  { "x86_64", "elf_x86_64", "x86_64", 6, EM_X86_64 },
+  { "sh", "elf_sh", "sh", 2, EM_SH },
+  { "arm", "ebl_arm", "arm", 3, EM_ARM },
+  { "sparc", "elf_sparcv9", "sparc", 5, EM_SPARCV9 },
+  { "sparc", "elf_sparc", "sparc", 5, EM_SPARC },
+  { "sparc", "elf_sparcv8plus", "sparc", 5, EM_SPARC32PLUS },
+
+  { "m32", "elf_m32", "m32", 3, EM_M32 },
+  { "m68k", "elf_m68k", "m68k", 4, EM_68K },
+  { "m88k", "elf_m88k", "m88k", 4, EM_88K },
+  { "i860", "elf_i860", "i860", 4, EM_860 },
+  { "mips", "elf_mips", "mips", 4, EM_MIPS },
+  { "s370", "ebl_s370", "s370", 4, EM_S370 },
+  { "mips", "elf_mipsel", "mips", 4, EM_MIPS_RS3_LE },
+  { "parisc", "elf_parisc", "parisc", 6, EM_PARISC },
+  { "vpp500", "elf_vpp500", "vpp500", 5, EM_VPP500 },
+  { "sparc", "elf_v8plus", "v8plus", 6, EM_SPARC32PLUS },
+  { "i960", "elf_i960", "i960", 4, EM_960 },
+  { "ppc", "elf_ppc", "ppc", 3, EM_PPC },
+  { "ppc64", "elf_ppc64", "ppc64", 5, EM_PPC64 },
+  { "s390", "ebl_s390", "s390", 4, EM_S390 },
+  { "v800", "ebl_v800", "v800", 4, EM_V800 },
+  { "fr20", "ebl_fr20", "fr20", 4, EM_FR20 },
+  { "rh32", "ebl_rh32", "rh32", 4, EM_RH32 },
+  { "rce", "ebl_rce", "rce", 3, EM_RCE },
+  { "tricore", "elf_tricore", "tricore", 7, EM_TRICORE },
+  { "arc", "elf_arc", "arc", 3, EM_ARC },
+  { "h8", "elf_h8_300", "h8_300", 6, EM_H8_300 },
+  { "h8", "elf_h8_300h", "h8_300h", 6, EM_H8_300H },
+  { "h8", "elf_h8s", "h8s", 6, EM_H8S },
+  { "h8", "elf_h8_500", "h8_500", 6, EM_H8_500 },
+  { "mips_x", "elf_mips_x", "mips_x", 6, EM_MIPS_X },
+  { "coldfire", "elf_coldfire", "coldfire", 8, EM_COLDFIRE },
+  { "m68k", "elf_68hc12", "68hc12", 6, EM_68HC12 },
+  { "mma", "elf_mma", "mma", 3, EM_MMA },
+  { "pcp", "elf_pcp", "pcp", 3, EM_PCP },
+  { "ncpu", "elf_ncpu", "ncpu", 4, EM_NCPU },
+  { "ndr1", "elf_ndr1", "ndr1", 4, EM_NDR1 },
+  { "starcore", "elf_starcore", "starcore", 8, EM_STARCORE },
+  { "me16", "elf_me16", "em16", 4, EM_ME16 },
+  { "st100", "elf_st100", "st100", 5, EM_ST100 },
+  { "tinyj", "elf_tinyj", "tinyj", 5, EM_TINYJ },
+  { "pdsp", "elf_pdsp", "pdsp", 4, EM_PDSP },
+  { "fx66", "elf_fx66", "fx66", 4, EM_FX66 },
+  { "st9plus", "elf_st9plus", "st9plus", 7, EM_ST9PLUS },
+  { "st7", "elf_st7", "st7", 3, EM_ST7 },
+  { "m68k", "elf_68hc16", "68hc16", 6, EM_68HC16 },
+  { "m68k", "elf_68hc11", "68hc11", 6, EM_68HC11 },
+  { "m68k", "elf_68hc08", "68hc08", 6, EM_68HC08 },
+  { "m68k", "elf_68hc05", "68hc05", 6, EM_68HC05 },
+  { "svx", "elf_svx", "svx", 3, EM_SVX },
+  { "st19", "elf_st19", "st19", 4, EM_ST19 },
+  { "vax", "elf_vax", "vax", 3, EM_VAX },
+  { "cris", "elf_cris", "cris", 4, EM_CRIS },
+  { "javelin", "elf_javelin", "javelin", 7, EM_JAVELIN },
+  { "firepath", "elf_firepath", "firepath", 8, EM_FIREPATH },
+  { "zsp", "elf_zsp", "zsp", 3, EM_ZSP},
+  { "mmix", "elf_mmix", "mmix", 4, EM_MMIX },
+  { "hunay", "elf_huany", "huany", 5, EM_HUANY },
+  { "prism", "elf_prism", "prism", 5, EM_PRISM },
+  { "avr", "elf_avr", "avr", 3, EM_AVR },
+  { "fr30", "elf_fr30", "fr30", 4, EM_FR30 },
+  { "dv10", "elf_dv10", "dv10", 4, EM_D10V },
+  { "dv30", "elf_dv30", "dv30", 4, EM_D30V },
+  { "v850", "elf_v850", "v850", 4, EM_V850 },
+  { "m32r", "elf_m32r", "m32r", 4, EM_M32R },
+  { "mn10300", "elf_mn10300", "mn10300", 7, EM_MN10300 },
+  { "mn10200", "elf_mn10200", "mn10200", 7, EM_MN10200 },
+  { "pj", "elf_pj", "pj", 2, EM_PJ },
+  { "openrisc", "elf_openrisc", "openrisc", 8, EM_OPENRISC },
+  { "arc", "elf_arc_a5", "arc_a5", 6, EM_ARC_A5 },
+  { "xtensa", "elf_xtensa", "xtensa", 6, EM_XTENSA },
+};
+#define nmachines (sizeof (machines) / sizeof (machines[0]))
+
+
+/* Default callbacks.  Mostly they just return the error value.  */
+static const char *default_object_type_name (int ignore, char *buf,
+					     size_t len);
+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 bool default_gotpc_reloc_check (Elf *elf, int ignore);
+static const char *default_segment_type_name (int ignore, char *buf,
+					      size_t len);
+static const char *default_section_type_name (int ignore, char *buf,
+					      size_t len);
+static const char *default_section_name (int ignore, int ignore2, char *buf,
+					 size_t len);
+static const char *default_machine_flag_name (Elf64_Word *ignore);
+static bool default_machine_flag_check (Elf64_Word flags);
+static const char *default_symbol_type_name (int ignore, char *buf,
+					     size_t len);
+static const char *default_symbol_binding_name (int ignore, char *buf,
+						size_t len);
+static const char *default_dynamic_tag_name (int64_t ignore, char *buf,
+					     size_t len);
+static bool default_dynamic_tag_check (int64_t ignore);
+static GElf_Word default_sh_flags_combine (GElf_Word flags1, GElf_Word flags2);
+static const char *default_osabi_name (int ignore, char *buf, size_t len);
+static void default_destr (struct ebl *ignore);
+static const char *default_core_note_type_name (uint32_t, char *buf,
+						size_t len);
+static const char *default_object_note_type_name (uint32_t, char *buf,
+						  size_t len);
+static bool default_core_note (const char *name, uint32_t type,
+			       uint32_t descsz, const char *desc);
+static bool default_object_note (const char *name, uint32_t type,
+				 uint32_t descsz, const char *desc);
+static bool default_debugscn_p (const char *name);
+static bool default_copy_reloc_p (int reloc);
+
+
+static void
+fill_defaults (Ebl *result)
+{
+  result->object_type_name = default_object_type_name;
+  result->reloc_type_name = default_reloc_type_name;
+  result->reloc_type_check = default_reloc_type_check;
+  result->reloc_valid_use = default_reloc_valid_use;
+  result->reloc_simple_type = default_reloc_simple_type;
+  result->gotpc_reloc_check = default_gotpc_reloc_check;
+  result->segment_type_name = default_segment_type_name;
+  result->section_type_name = default_section_type_name;
+  result->section_name = default_section_name;
+  result->machine_flag_name = default_machine_flag_name;
+  result->machine_flag_check = default_machine_flag_check;
+  result->symbol_type_name = default_symbol_type_name;
+  result->symbol_binding_name = default_symbol_binding_name;
+  result->dynamic_tag_name = default_dynamic_tag_name;
+  result->dynamic_tag_check = default_dynamic_tag_check;
+  result->sh_flags_combine = default_sh_flags_combine;
+  result->osabi_name = default_osabi_name;
+  result->core_note_type_name = default_core_note_type_name;
+  result->object_note_type_name = default_object_note_type_name;
+  result->core_note = default_core_note;
+  result->object_note = default_object_note;
+  result->debugscn_p = default_debugscn_p;
+  result->copy_reloc_p = default_copy_reloc_p;
+  result->destr = default_destr;
+}
+
+
+/* Find an appropriate backend for the file associated with ELF.  */
+static Ebl *
+openbackend (elf, emulation, machine)
+     Elf *elf;
+     const char *emulation;
+     GElf_Half machine;
+{
+  Ebl *result;
+  size_t cnt;
+
+  /* First allocate the data structure for the result.  We do this
+     here since this assures that the structure is always large
+     enough.  */
+  result = (Ebl *) calloc (1, sizeof (Ebl));
+  if (result == NULL)
+    {
+      // XXX uncomment
+      // __libebl_seterror (ELF_E_NOMEM);
+      return NULL;
+    }
+
+  /* Fill in the default callbacks.  The initializer for the machine
+     specific module can overwrite the values.  */
+  fill_defaults (result);
+
+  /* XXX Currently all we do is to look at 'e_machine' value in the
+     ELF header.  With an internal mapping table from EM_* value to
+     DSO name we try to load the appropriate module to handle this
+     binary type.
+
+     Multiple modules for the same machine type are possible and they
+     will be tried in sequence.  The lookup process will only stop
+     when a module which can handle the machine type is found or all
+     available matching modules are tried.  */
+  for (cnt = 0; cnt < nmachines; ++cnt)
+    if ((emulation != NULL && strcmp (emulation, machines[cnt].emulation) == 0)
+	|| (emulation == NULL && machines[cnt].em == machine))
+      {
+	/* Well, we know the emulation name now.  */
+	result->emulation = machines[cnt].emulation;
+
+#ifndef LIBEBL_SUBDIR
+# define LIBEBL_SUBDIR PACKAGE
+#endif
+#define ORIGINDIR "$ORIGIN/../$LIB/" LIBEBL_SUBDIR "/"
+
+	/* Give it a try.  At least the machine type matches.  First
+           try to load the module.  */
+	char dsoname[100];
+	strcpy (stpcpy (stpcpy (dsoname, ORIGINDIR "libebl_"),
+			machines[cnt].dsoname),
+		".so");
+
+	void *h = dlopen (dsoname, RTLD_LAZY);
+	if (h == NULL)
+	  {
+	    strcpy (stpcpy (stpcpy (dsoname, "libebl_"),
+			    machines[cnt].dsoname),
+		    ".so");
+	    h = dlopen (dsoname, RTLD_LAZY);
+	  }
+
+	  /* Try without an explicit path.  */
+	if (h != NULL)
+	  {
+	    /* We managed to load the object.  Now see whether the
+	       initialization function likes our file.  */
+	    static const char version[] = MODVERSION;
+	    const char *modversion;
+	    ebl_bhinit_t initp;
+	    char symname[machines[cnt].prefix_len + sizeof "_init"];
+
+	    strcpy (mempcpy (symname, machines[cnt].prefix,
+			     machines[cnt].prefix_len), "_init");
+
+	    initp = (ebl_bhinit_t) dlsym (h, symname);
+	    if (initp != NULL
+		&& (modversion = initp (elf, machine, result, sizeof (Ebl)))
+		&& strcmp (version, modversion) == 0)
+	      {
+		/* We found a module to handle our file.  */
+		result->dlhandle = h;
+		result->elf = elf;
+
+		/* A few entries are mandatory.  */
+		assert (result->name != NULL);
+		assert (result->destr != NULL);
+
+		return result;
+	      }
+
+	    /* Not the module we need.  */
+	    (void) dlclose (h);
+	  }
+
+	/* We cannot find a DSO but the emulation/machine ID matches.
+	   Return that information.  */
+	result->dlhandle = NULL;
+	result->elf = elf;
+	result->name = machines[cnt].prefix;
+	fill_defaults (result);
+
+	return result;
+      }
+
+  /* Nothing matched.  We use only the default callbacks.   */
+  result->dlhandle = NULL;
+  result->elf = elf;
+  result->emulation = "<unknown>";
+  result->name = "<unknown>";
+  fill_defaults (result);
+
+  return result;
+}
+
+
+/* Find an appropriate backend for the file associated with ELF.  */
+Ebl *
+ebl_openbackend (elf)
+     Elf *elf;
+{
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr;
+
+  /* Get the ELF header of the object.  */
+  ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+      // XXX uncomment
+      // __libebl_seterror (elf_errno ());
+      return NULL;
+    }
+
+  return openbackend (elf, NULL, ehdr->e_machine);
+}
+
+
+/* Find backend without underlying ELF file.  */
+Ebl *
+ebl_openbackend_machine (machine)
+     GElf_Half machine;
+{
+  return openbackend (NULL, NULL, machine);
+}
+
+
+/* Find backend with given emulation name.  */
+Ebl *
+ebl_openbackend_emulation (const char *emulation)
+{
+  return openbackend (NULL, emulation, EM_NONE);
+}
+
+
+/* Default callbacks.  Mostly they just return the error value.  */
+static const char *
+default_object_type_name (int ignore __attribute__ ((unused)),
+			  char *buf __attribute__ ((unused)),
+			  size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static const char *
+default_reloc_type_name (int ignore __attribute__ ((unused)),
+			 char *buf __attribute__ ((unused)),
+			 size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static bool
+default_reloc_type_check (int ignore __attribute__ ((unused)))
+{
+  return false;
+}
+
+static bool
+default_reloc_valid_use (Elf *elf __attribute__ ((unused)),
+			 int ignore __attribute__ ((unused)))
+{
+  return false;
+}
+
+static Elf_Type
+default_reloc_simple_type (Elf *elf __attribute__ ((unused)),
+			   int ignore __attribute__ ((unused)))
+{
+  return ELF_T_NUM;
+}
+
+static bool
+default_gotpc_reloc_check (Elf *elf __attribute__ ((unused)),
+			   int ignore __attribute__ ((unused)))
+{
+  return false;
+}
+
+static const char *
+default_segment_type_name (int ignore __attribute__ ((unused)),
+			   char *buf __attribute__ ((unused)),
+			   size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static const char *
+default_section_type_name (int ignore __attribute__ ((unused)),
+			   char *buf __attribute__ ((unused)),
+			   size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static const char *
+default_section_name (int ignore __attribute__ ((unused)),
+		      int ignore2 __attribute__ ((unused)),
+		      char *buf __attribute__ ((unused)),
+		      size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static const char *
+default_machine_flag_name (Elf64_Word *ignore __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static bool
+default_machine_flag_check (Elf64_Word flags __attribute__ ((unused)))
+{
+  return flags == 0;
+}
+
+static const char *
+default_symbol_type_name (int ignore __attribute__ ((unused)),
+			  char *buf __attribute__ ((unused)),
+			  size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static const char *
+default_symbol_binding_name (int ignore __attribute__ ((unused)),
+			     char *buf __attribute__ ((unused)),
+			     size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static const char *
+default_dynamic_tag_name (int64_t ignore __attribute__ ((unused)),
+			  char *buf __attribute__ ((unused)),
+			  size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static bool
+default_dynamic_tag_check (int64_t ignore __attribute__ ((unused)))
+{
+  return false;
+}
+
+static GElf_Word
+default_sh_flags_combine (GElf_Word flags1, GElf_Word flags2)
+{
+  return SH_FLAGS_COMBINE (flags1, flags2);
+}
+
+static void
+default_destr (struct ebl *ignore __attribute__ ((unused)))
+{
+}
+
+static const char *
+default_osabi_name (int ignore __attribute__ ((unused)),
+		    char *buf __attribute__ ((unused)),
+		    size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static const char *
+default_core_note_type_name (uint32_t ignore __attribute__ ((unused)),
+			     char *buf __attribute__ ((unused)),
+			     size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static const char *
+default_object_note_type_name (uint32_t ignore __attribute__ ((unused)),
+			       char *buf __attribute__ ((unused)),
+			       size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static bool
+default_core_note (const char *name __attribute__ ((unused)),
+		   uint32_t type __attribute__ ((unused)),
+		   uint32_t descsz __attribute__ ((unused)),
+		   const char *desc __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static bool
+default_object_note (const char *name __attribute__ ((unused)),
+		     uint32_t type __attribute__ ((unused)),
+		     uint32_t descsz __attribute__ ((unused)),
+		     const char *desc __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static bool
+default_debugscn_p (const char *name)
+{
+  /* We know by default only about the DWARF debug sections which have
+     fixed names.  */
+  static const char *dwarf_scn_names[] =
+    {
+      /* DWARF 1 */
+      ".debug",
+      ".line",
+      /* GNU DWARF 1 extensions */
+      ".debug_srcinfo",
+      ".debug_sfnames",
+      /* DWARF 1.1 and DWARF 2 */
+      ".debug_aranges",
+      ".debug_pubnames",
+      /* DWARF 2 */
+      ".debug_info",
+      ".debug_abbrev",
+      ".debug_line",
+      ".debug_frame",
+      ".debug_str",
+      ".debug_loc",
+      ".debug_macinfo",
+      /* DWARF 3 */
+      ".debug_ranges",
+      /* SGI/MIPS DWARF 2 extensions */
+      ".debug_weaknames",
+      ".debug_funcnames",
+      ".debug_typenames",
+      ".debug_varnames"
+    };
+  const size_t ndwarf_scn_names = (sizeof (dwarf_scn_names)
+				   / sizeof (dwarf_scn_names[0]));
+  for (size_t cnt = 0; cnt < ndwarf_scn_names; ++cnt)
+    if (strcmp (name, dwarf_scn_names[cnt]) == 0)
+      return true;
+
+  return false;
+}
+
+static bool
+default_copy_reloc_p (int reloc __attribute__ ((unused)))
+{
+  return false;
+}
diff --git a/libebl/eblosabiname.c b/libebl/eblosabiname.c
new file mode 100644
index 0000000..9a1e653
--- /dev/null
+++ b/libebl/eblosabiname.c
@@ -0,0 +1,69 @@
+/* Return OS ABI name
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   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 <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_osabi_name (ebl, osabi, buf, len)
+     Ebl *ebl;
+     int osabi;
+     char *buf;
+     size_t len;
+{
+  const char *res = ebl != NULL ? ebl->osabi_name (osabi, buf, len) : NULL;
+
+  if (res == NULL)
+    {
+      if (osabi == ELFOSABI_NONE)
+	res = "UNIX - System V";
+      else if (osabi == ELFOSABI_HPUX)
+	res = "HP/UX";
+      else if (osabi == ELFOSABI_NETBSD)
+	res = "NetBSD";
+      else if (osabi == ELFOSABI_LINUX)
+	res = "Linux";
+      else if (osabi == ELFOSABI_SOLARIS)
+	res = "Solaris";
+      else if (osabi == ELFOSABI_AIX)
+	res = "AIX";
+      else if (osabi == ELFOSABI_IRIX)
+	res = "Irix";
+      else if (osabi == ELFOSABI_FREEBSD)
+	res = "FreeBSD";
+      else if (osabi == ELFOSABI_TRU64)
+	res = "TRU64";
+      else if (osabi == ELFOSABI_MODESTO)
+	res = "Modesto";
+      else if (osabi == ELFOSABI_OPENBSD)
+	res = "OpenBSD";
+      else if (osabi == ELFOSABI_ARM)
+	res = "Arm";
+      else if (osabi == ELFOSABI_STANDALONE)
+	res = gettext ("Stand alone");
+      else
+	{
+	  snprintf (buf, len, "%s: %d", gettext ("<unknown>"), osabi);
+
+	  res = buf;
+	}
+    }
+
+  return res;
+}
diff --git a/libebl/eblrelocsimpletype.c b/libebl/eblrelocsimpletype.c
new file mode 100644
index 0000000..3e048d1
--- /dev/null
+++ b/libebl/eblrelocsimpletype.c
@@ -0,0 +1,27 @@
+/* Check relocation type for simple types.
+   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 <libeblP.h>
+
+
+Elf_Type
+ebl_reloc_simple_type (ebl, reloc)
+     Ebl *ebl;
+     int reloc;
+{
+  return ebl != NULL ? ebl->reloc_simple_type (ebl->elf, reloc) : ELF_T_NUM;
+}
diff --git a/libebl/eblreloctypecheck.c b/libebl/eblreloctypecheck.c
new file mode 100644
index 0000000..cafbc61
--- /dev/null
+++ b/libebl/eblreloctypecheck.c
@@ -0,0 +1,28 @@
+/* Check relocation type.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   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 <libeblP.h>
+
+
+bool
+ebl_reloc_type_check (ebl, reloc)
+     Ebl *ebl;
+     int reloc;
+{
+  return ebl != NULL ? ebl->reloc_type_check (reloc) : false;
+}
diff --git a/libebl/eblreloctypename.c b/libebl/eblreloctypename.c
new file mode 100644
index 0000000..5fa9560
--- /dev/null
+++ b/libebl/eblreloctypename.c
@@ -0,0 +1,38 @@
+/* Return relocation type name.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   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 <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_reloc_type_name (ebl, reloc, buf, len)
+     Ebl *ebl;
+     int reloc;
+     char *buf;
+     size_t len;
+{
+  const char *res;
+
+  res = ebl != NULL ? ebl->reloc_type_name (reloc, buf, len) : NULL;
+  if (res == NULL)
+    /* There are no generic relocation type names.  */
+    res = "???";
+
+  return res;
+}
diff --git a/libebl/eblrelocvaliduse.c b/libebl/eblrelocvaliduse.c
new file mode 100644
index 0000000..7488986
--- /dev/null
+++ b/libebl/eblrelocvaliduse.c
@@ -0,0 +1,28 @@
+/* Check relocation type use.
+   Copyright (C) 2003 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   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 <libeblP.h>
+
+
+bool
+ebl_reloc_valid_use (ebl, reloc)
+     Ebl *ebl;
+     int reloc;
+{
+  return ebl != NULL ? ebl->reloc_valid_use (ebl->elf, reloc) : false;
+}
diff --git a/libebl/eblsectionname.c b/libebl/eblsectionname.c
new file mode 100644
index 0000000..6c801db
--- /dev/null
+++ b/libebl/eblsectionname.c
@@ -0,0 +1,81 @@
+/* Return section name.
+   Copyright (C) 2001, 2002, 2004 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   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 <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_section_name (ebl, section, xsection, buf, len, scnnames, shnum)
+     Ebl *ebl;
+     int section;
+     int xsection;
+     char *buf;
+     size_t len;
+     const char *scnnames[];
+     size_t shnum;
+{
+  const char *res = ebl != NULL ? ebl->section_name (section, xsection,
+						     buf, len) : NULL;
+
+  if (res == NULL)
+    {
+      if (section == SHN_UNDEF)
+	res = "UNDEF";
+      else if (section == SHN_ABS)
+	res = "ABS";
+      else if (section == SHN_COMMON)
+	res = "COMMON";
+      else if (section == SHN_BEFORE)
+	res = "BEFORE";
+      else if (section == SHN_AFTER)
+	res = "AFTER";
+      else if ((section < SHN_LORESERVE || section == SHN_XINDEX)
+	       && (size_t) section < shnum)
+	{
+	  int idx = section != SHN_XINDEX ? section : xsection;
+
+	  if (scnnames != NULL)
+	    res = scnnames[idx];
+	  else
+	    {
+	      snprintf (buf, len, "%d", idx);
+	      res = buf;
+	    }
+	}
+      else
+	{
+	  /* Handle OS-specific section names.  */
+	  if (section == SHN_XINDEX)
+	    snprintf (buf, len, "%s: %d", "XINDEX", xsection);
+	  else if (section >= SHN_LOOS && section <= SHN_HIOS)
+	    snprintf (buf, len, "LOOS+%x", section - SHN_LOOS);
+	  /* Handle processor-specific section names.  */
+	  else if (section >= SHN_LOPROC && section <= SHN_HIPROC)
+	    snprintf (buf, len, "LOPROC+%x", section - SHN_LOPROC);
+	  else if (section >= SHN_LORESERVE && section <= SHN_HIRESERVE)
+	    snprintf (buf, len, "LORESERVE+%x", section - SHN_LORESERVE);
+	  else
+	    snprintf (buf, len, "%s: %d", gettext ("<unknown>"), section);
+
+	  res = buf;
+	}
+    }
+
+  return res;
+}
diff --git a/libebl/eblsectionstripp.c b/libebl/eblsectionstripp.c
new file mode 100644
index 0000000..77a22ca
--- /dev/null
+++ b/libebl/eblsectionstripp.c
@@ -0,0 +1,52 @@
+/* Check whether section can be stripped.
+   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 <string.h>
+#include "libeblP.h"
+
+
+bool
+ebl_section_strip_p (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr,
+		     const char *name, bool remove_comment,
+		     bool only_remove_debug)
+{
+  /* If only debug information should be removed check the name.  There
+     is unfortunately no other way.  */
+  if (unlikely (only_remove_debug))
+    {
+      if (ebl_debugscn_p (ebl, name))
+	return true;
+
+      if (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL)
+	{
+	  Elf_Scn *scn_l = elf_getscn (ebl->elf, (shdr)->sh_info);
+	  GElf_Shdr shdr_mem_l;
+	  GElf_Shdr *shdr_l = gelf_getshdr (scn_l, &shdr_mem_l);
+	  if (shdr_l == NULL)
+	    {
+	      const char *s_l = elf_strptr (ebl->elf, ehdr->e_shstrndx,
+					    shdr_l->sh_name);
+	      if (s_l != NULL && ebl_debugscn_p (ebl, s_l))
+		return true;
+	    }
+	}
+
+      return false;
+    }
+
+  return SECTION_STRIP_P (shdr, name, remove_comment);
+}
diff --git a/libebl/eblsectiontypename.c b/libebl/eblsectiontypename.c
new file mode 100644
index 0000000..e6857ac
--- /dev/null
+++ b/libebl/eblsectiontypename.c
@@ -0,0 +1,103 @@
+/* Return section type name.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   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 <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_section_type_name (ebl, section, buf, len)
+     Ebl *ebl;
+     int section;
+     char *buf;
+     size_t len;
+{
+  const char *res = ebl->section_type_name (section, buf, len);
+
+  if (res == NULL)
+    {
+      static const char *knowntypes[] =
+	{
+#define KNOWNSTYPE(name) [SHT_##name] = #name
+	  KNOWNSTYPE (NULL),
+	  KNOWNSTYPE (PROGBITS),
+	  KNOWNSTYPE (SYMTAB),
+	  KNOWNSTYPE (STRTAB),
+	  KNOWNSTYPE (RELA),
+	  KNOWNSTYPE (HASH),
+	  KNOWNSTYPE (DYNAMIC),
+	  KNOWNSTYPE (NOTE),
+	  KNOWNSTYPE (NOBITS),
+	  KNOWNSTYPE (REL),
+	  KNOWNSTYPE (SHLIB),
+	  KNOWNSTYPE (DYNSYM),
+	  KNOWNSTYPE (INIT_ARRAY),
+	  KNOWNSTYPE (FINI_ARRAY),
+	  KNOWNSTYPE (PREINIT_ARRAY),
+	  KNOWNSTYPE (GROUP),
+	  KNOWNSTYPE (SYMTAB_SHNDX)
+	};
+
+      /* Handle standard names.  */
+      if ((size_t) section < sizeof (knowntypes) / sizeof (knowntypes[0])
+	  && knowntypes[section] != NULL)
+	res = knowntypes[section];
+      /* The symbol versioning/Sun extensions.  */
+      else if (section >= SHT_LOSUNW && section <= SHT_HISUNW)
+	{
+	  static const char *sunwtypes[] =
+	    {
+#undef KNOWNSTYPE
+#define KNOWNSTYPE(name) [SHT_##name - SHT_LOSUNW] = #name
+	      KNOWNSTYPE (SUNW_move),
+	      KNOWNSTYPE (SUNW_COMDAT),
+	      KNOWNSTYPE (SUNW_syminfo),
+	      KNOWNSTYPE (GNU_verdef),
+	      KNOWNSTYPE (GNU_verneed),
+	      KNOWNSTYPE (GNU_versym)
+	    };
+	  res = sunwtypes[section - SHT_LOSUNW];
+	}
+      else
+	{
+	  /* A few GNU additions.  */
+	  if (section == SHT_CHECKSUM)
+	    res = "CHECKSUM";
+	  else if (section == SHT_GNU_LIBLIST)
+	    res = "GNU_LIBLIST";
+	  /* Handle OS-specific section names.  */
+	  else
+	    {
+	      if (section >= SHT_LOOS && section <= SHT_HIOS)
+		snprintf (buf, len, "SHT_LOOS+%x", section - SHT_LOOS);
+	      /* Handle processor-specific section names.  */
+	      else if (section >= SHT_LOPROC && section <= SHT_HIPROC)
+		snprintf (buf, len, "SHT_LOPROC+%x", section - SHT_LOPROC);
+	      else if ((unsigned int) section >= SHT_LOUSER
+		       && (unsigned int) section <= SHT_HIUSER)
+		snprintf (buf, len, "SHT_LOUSER+%x", section - SHT_LOUSER);
+	      else
+		snprintf (buf, len, "%s: %d", gettext ("<unknown>"), section);
+
+	      res = buf;
+	    }
+	}
+    }
+
+  return res;
+}
diff --git a/libebl/eblsegmenttypename.c b/libebl/eblsegmenttypename.c
new file mode 100644
index 0000000..c59f037
--- /dev/null
+++ b/libebl/eblsegmenttypename.c
@@ -0,0 +1,75 @@
+/* Return segment type name.
+   Copyright (C) 2001, 2002, 2004 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   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 <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_segment_type_name (ebl, segment, buf, len)
+     Ebl *ebl;
+     int segment;
+     char *buf;
+     size_t len;
+{
+  const char *res;
+
+  res = ebl != NULL ? ebl->segment_type_name (segment, buf, len) : NULL;
+  if (res == NULL)
+    {
+      static const char *ptypes[PT_NUM] =
+	{
+#define PTYPE(name) [PT_##name] = #name
+	  PTYPE (NULL),
+	  PTYPE (LOAD),
+	  PTYPE (DYNAMIC),
+	  PTYPE (INTERP),
+	  PTYPE (NOTE),
+	  PTYPE (SHLIB),
+	  PTYPE (PHDR),
+	  PTYPE (TLS)
+	};
+
+      /* Is it one of the standard segment types?  */
+      if (segment >= PT_NULL && segment < PT_NUM)
+	res = ptypes[segment];
+      else if (segment == PT_GNU_EH_FRAME)
+	res = "GNU_EH_FRAME";
+      else if (segment == PT_GNU_STACK)
+	res = "GNU_STACK";
+      else if (segment == PT_GNU_RELRO)
+	res = "GNU_RELRO";
+      else if (segment == PT_SUNWBSS)
+	res = "SUNWBSS";
+      else if (segment == PT_SUNWSTACK)
+	res = "SUNWSTACK";
+      else
+	{
+	  if (segment >= PT_LOOS && segment <= PT_HIOS)
+	    snprintf (buf, len, "LOOS+%d", segment - PT_LOOS);
+	  else if (segment >= PT_LOPROC && segment <= PT_HIPROC)
+	    snprintf (buf, len, "LOPROC+%d", segment - PT_LOPROC);
+	  else
+	    snprintf (buf, len, "%s: %d", gettext ("<unknown>"), segment);
+
+	  res = buf;
+	}
+    }
+
+  return res;
+}
diff --git a/libebl/eblshflagscombine.c b/libebl/eblshflagscombine.c
new file mode 100644
index 0000000..7edcf4e
--- /dev/null
+++ b/libebl/eblshflagscombine.c
@@ -0,0 +1,29 @@
+/* Return combines section header flags value.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   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 <libeblP.h>
+
+
+GElf_Word
+ebl_sh_flags_combine (ebl, flags1, flags2)
+     Ebl *ebl;
+     GElf_Word flags1;
+     GElf_Word flags2;
+{
+  return ebl->sh_flags_combine (flags1, flags2);
+}
diff --git a/libebl/eblstrtab.c b/libebl/eblstrtab.c
new file mode 100644
index 0000000..165909f
--- /dev/null
+++ b/libebl/eblstrtab.c
@@ -0,0 +1,337 @@
+/* ELF string table handling.
+   Copyright (C) 2000, 2001, 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 <assert.h>
+#include <inttypes.h>
+#include <libelf.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+#include "libebl.h"
+#include <system.h>
+
+#ifndef MIN
+# define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+
+struct Ebl_Strent
+{
+  const char *string;
+  size_t len;
+  struct Ebl_Strent *next;
+  struct Ebl_Strent *left;
+  struct Ebl_Strent *right;
+  size_t offset;
+  char reverse[0];
+};
+
+
+struct memoryblock
+{
+  struct memoryblock *next;
+  char memory[0];
+};
+
+
+struct Ebl_Strtab
+{
+  struct Ebl_Strent *root;
+  struct memoryblock *memory;
+  char *backp;
+  size_t left;
+  size_t total;
+  bool nullstr;
+
+  struct Ebl_Strent null;
+};
+
+
+/* Cache for the pagesize.  We correct this value a bit so that `malloc'
+   is not allocating more than a page.  */
+static size_t ps;
+
+
+struct Ebl_Strtab *
+ebl_strtabinit (bool nullstr)
+{
+  if (ps == 0)
+    {
+      ps = sysconf (_SC_PAGESIZE) - 2 * sizeof (void *);
+      assert (sizeof (struct memoryblock) < ps);
+    }
+
+  struct Ebl_Strtab *ret
+    = (struct Ebl_Strtab *) calloc (1, sizeof (struct Ebl_Strtab));
+  if (ret != NULL)
+    {
+      ret->nullstr = nullstr;
+
+      if (nullstr)
+	{
+	  ret->null.len = 1;
+	  ret->null.string = "";
+	}
+    }
+
+  return ret;
+}
+
+
+static int
+morememory (struct Ebl_Strtab *st, size_t len)
+{
+  if (len < ps)
+    len = ps;
+
+  struct memoryblock *newmem = (struct memoryblock *) malloc (len);
+  if (newmem == NULL)
+    return 1;
+
+  newmem->next = st->memory;
+  st->memory = newmem;
+  st->backp = newmem->memory;
+  st->left = len - offsetof (struct memoryblock, memory);
+
+  return 0;
+}
+
+
+void
+ebl_strtabfree (struct Ebl_Strtab *st)
+{
+  struct memoryblock *mb = st->memory;
+
+  while (mb != NULL)
+    {
+      void *old = mb;
+      mb = mb->next;
+      free (old);
+    }
+
+  free (st);
+}
+
+
+static struct Ebl_Strent *
+newstring (struct Ebl_Strtab *st, const char *str, size_t len)
+{
+  /* Compute the amount of padding needed to make the structure aligned.  */
+  size_t align = ((__alignof__ (struct Ebl_Strent)
+		   - (((uintptr_t) st->backp)
+		      & (__alignof__ (struct Ebl_Strent) - 1)))
+		  & (__alignof__ (struct Ebl_Strent) - 1));
+
+  /* Make sure there is enough room in the memory block.  */
+  if (st->left < align + sizeof (struct Ebl_Strent) + len)
+    {
+      if (morememory (st, sizeof (struct Ebl_Strent) + len))
+	return NULL;
+
+      align = 0;
+    }
+
+  /* Create the reserved string.  */
+  struct Ebl_Strent *newstr = (struct Ebl_Strent *) (st->backp + align);
+  newstr->string = str;
+  newstr->len = len;
+  newstr->next = NULL;
+  newstr->left = NULL;
+  newstr->right = NULL;
+  newstr->offset = 0;
+  for (int i = len - 2; i >= 0; --i)
+    newstr->reverse[i] = str[len - 2 - i];
+  newstr->reverse[len - 1] = '\0';
+  st->backp += align + sizeof (struct Ebl_Strent) + len;
+  st->left -= align + sizeof (struct Ebl_Strent) + len;
+
+  return newstr;
+}
+
+
+/* XXX This function should definitely be rewritten to use a balancing
+   tree algorith (AVL, red-black trees).  For now a simple, correct
+   implementation is enough.  */
+static struct Ebl_Strent **
+searchstring (struct Ebl_Strent **sep, struct Ebl_Strent *newstr)
+{
+  /* More strings?  */
+  if (*sep == NULL)
+    {
+      *sep = newstr;
+      return sep;
+    }
+
+  /* Compare the strings.  */
+  int cmpres = memcmp ((*sep)->reverse, newstr->reverse,
+		       MIN ((*sep)->len, newstr->len) - 1);
+  if (cmpres == 0)
+    /* We found a matching string.  */
+    return sep;
+  else if (cmpres > 0)
+    return searchstring (&(*sep)->left, newstr);
+  else
+    return searchstring (&(*sep)->right, newstr);
+}
+
+
+/* Add new string.  The actual string is assumed to be permanent.  */
+struct Ebl_Strent *
+ebl_strtabadd (struct Ebl_Strtab *st, const char *str, size_t len)
+{
+  /* Compute the string length if the caller doesn't know it.  */
+  if (len == 0)
+    len = strlen (str) + 1;
+
+  /* Make sure all "" strings get offset 0 but only if the table was
+     created with a special null entry in mind.  */
+  if (len == 1 && st->null.string != NULL)
+    return &st->null;
+
+  /* Allocate memory for the new string and its associated information.  */
+  struct Ebl_Strent *newstr = newstring (st, str, len);
+  if (newstr == NULL)
+    return NULL;
+
+  /* Search in the array for the place to insert the string.  If there
+     is no string with matching prefix and no string with matching
+     leading substring, create a new entry.  */
+  struct Ebl_Strent **sep = searchstring (&st->root, newstr);
+  if (*sep != newstr)
+    {
+      /* This is not the same entry.  This means we have a prefix match.  */
+      if ((*sep)->len > newstr->len)
+	{
+	  /* Check whether we already know this string.  */
+	  for (struct Ebl_Strent *subs = (*sep)->next; subs != NULL;
+	       subs = subs->next)
+	    if (subs->len == newstr->len)
+	      {
+		/* We have an exact match with a substring.  Free the memory
+		   we allocated.  */
+		st->left += st->backp - (char *) newstr;
+		st->backp = (char *) newstr;
+
+		return subs;
+	      }
+
+	  /* We have a new substring.  This means we don't need the reverse
+	     string of this entry anymore.  */
+	  st->backp -= newstr->len;
+	  st->left += newstr->len;
+
+	  newstr->next = (*sep)->next;
+	  (*sep)->next = newstr;
+	}
+      else if ((*sep)->len != newstr->len)
+	{
+	  /* When we get here it means that the string we are about to
+	     add has a common prefix with a string we already have but
+	     it is longer.  In this case we have to put it first.  */
+	  st->total += newstr->len - (*sep)->len;
+	  newstr->next = *sep;
+	  newstr->left = (*sep)->left;
+	  newstr->right = (*sep)->right;
+	  *sep = newstr;
+	}
+      else
+	{
+	  /* We have an exact match.  Free the memory we allocated.  */
+	  st->left += st->backp - (char *) newstr;
+	  st->backp = (char *) newstr;
+
+	  newstr = *sep;
+	}
+    }
+  else
+    st->total += newstr->len;
+
+  return newstr;
+}
+
+
+static void
+copystrings (struct Ebl_Strent *nodep, char **freep, size_t *offsetp)
+{
+  if (nodep->left != NULL)
+    copystrings (nodep->left, freep, offsetp);
+
+  /* Process the current node.  */
+  nodep->offset = *offsetp;
+  *freep = (char *) mempcpy (*freep, nodep->string, nodep->len);
+  *offsetp += nodep->len;
+
+  for (struct Ebl_Strent *subs = nodep->next; subs != NULL; subs = subs->next)
+    {
+      assert (subs->len < nodep->len);
+      subs->offset = nodep->offset + nodep->len - subs->len;
+      assert (subs->offset != 0 || subs->string[0] == '\0');
+    }
+
+  if (nodep->right != NULL)
+    copystrings (nodep->right, freep, offsetp);
+}
+
+
+void
+ebl_strtabfinalize (struct Ebl_Strtab *st, Elf_Data *data)
+{
+  size_t nulllen = st->nullstr ? 1 : 0;
+
+  /* Fill in the information.  */
+  data->d_buf = malloc (st->total + nulllen);
+  if (data->d_buf == NULL)
+    abort ();
+
+  /* The first byte must always be zero if we created the table with a
+     null string.  */
+  if (st->nullstr)
+    *((char *) data->d_buf) = '\0';
+
+  data->d_type = ELF_T_BYTE;
+  data->d_size = st->total + nulllen;
+  data->d_off = 0;
+  data->d_align = 1;
+  data->d_version = EV_CURRENT;
+
+  /* Now run through the tree and add all the string while also updating
+     the offset members of the elfstrent records.  */
+  char *endp = (char *) data->d_buf + nulllen;
+  size_t copylen = nulllen;
+  copystrings (st->root, &endp, &copylen);
+  assert (copylen == st->total + nulllen);
+}
+
+
+size_t
+ebl_strtaboffset (struct Ebl_Strent *se)
+{
+  return se->offset;
+}
+
+
+const char *
+ebl_string (struct Ebl_Strent *se)
+{
+  assert (se->string != NULL);
+
+  return se->string;
+}
diff --git a/libebl/eblsymbolbindingname.c b/libebl/eblsymbolbindingname.c
new file mode 100644
index 0000000..efcd250
--- /dev/null
+++ b/libebl/eblsymbolbindingname.c
@@ -0,0 +1,57 @@
+/* Return symbol binding name.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   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 <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_symbol_binding_name (ebl, binding, buf, len)
+     Ebl *ebl;
+     int binding;
+     char *buf;
+     size_t len;
+{
+  const char *res;
+
+  res = ebl != NULL ? ebl->symbol_type_name (binding, buf, len) : NULL;
+  if (res == NULL)
+    {
+      static const char *stb_names[STB_NUM] =
+	{
+	  "LOCAL", "GLOBAL", "WEAK"
+	};
+
+      /* Standard binding?  */
+      if (binding < STB_NUM)
+	res = stb_names[binding];
+      else
+	{
+	  if (binding >= STB_LOPROC && binding <= STB_HIPROC)
+	    snprintf (buf, len, "LOPROC+%d", binding - STB_LOPROC);
+	  else if (binding >= STB_LOOS && binding <= STB_HIOS)
+	    snprintf (buf, len, "LOOS+%d", binding - STB_LOOS);
+	  else
+	    snprintf (buf, len, gettext ("<unknown>: %d"), binding);
+
+	  res = buf;
+	}
+    }
+
+  return res;
+}
diff --git a/libebl/eblsymboltypename.c b/libebl/eblsymboltypename.c
new file mode 100644
index 0000000..d11aec1
--- /dev/null
+++ b/libebl/eblsymboltypename.c
@@ -0,0 +1,63 @@
+/* Return symbol type name.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   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 <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_symbol_type_name (ebl, symbol, buf, len)
+     Ebl *ebl;
+     int symbol;
+     char *buf;
+     size_t len;
+{
+  const char *res;
+
+  res = ebl != NULL ? ebl->symbol_type_name (symbol, buf, len) : NULL;
+  if (res == NULL)
+    {
+      static const char *stt_names[STT_NUM] =
+	{
+	  [STT_NOTYPE] = "NOTYPE",
+	  [STT_OBJECT] = "OBJECT",
+	  [STT_FUNC] = "FUNC",
+	  [STT_SECTION] = "SECTION",
+	  [STT_FILE] = "FILE",
+	  [STT_COMMON] = "COMMON",
+	  [STT_TLS] = "TLS"
+	};
+
+      /* Standard type?  */
+      if (symbol < STT_NUM)
+	res = stt_names[symbol];
+      else
+	{
+	  if (symbol >= STT_LOPROC && symbol <= STT_HIPROC)
+	    snprintf (buf, len, "LOPROC+%d", symbol - STT_LOPROC);
+	  else if (symbol >= STT_LOOS && symbol <= STT_HIOS)
+	    snprintf (buf, len, "LOOS+%d", symbol - STT_LOOS);
+	  else
+	    snprintf (buf, len, gettext ("<unknown>: %d"), symbol);
+
+	  res = buf;
+	}
+    }
+
+  return res;
+}
diff --git a/libebl/eblwstrtab.c b/libebl/eblwstrtab.c
new file mode 100644
index 0000000..8320cb5
--- /dev/null
+++ b/libebl/eblwstrtab.c
@@ -0,0 +1,344 @@
+/* ELF string table handling.
+   Copyright (C) 2000, 2001, 2002 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 <assert.h>
+#include <inttypes.h>
+#include <libelf.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <wchar.h>
+#include <sys/param.h>
+
+#include "libebl.h"
+#include <system.h>
+
+#ifndef MIN
+# define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+
+struct Ebl_WStrent
+{
+  const wchar_t *string;
+  size_t len;
+  struct Ebl_WStrent *next;
+  struct Ebl_WStrent *left;
+  struct Ebl_WStrent *right;
+  size_t offset;
+  wchar_t reverse[0];
+};
+
+
+struct memoryblock
+{
+  struct memoryblock *next;
+  char memory[0];
+};
+
+
+struct Ebl_WStrtab
+{
+  struct Ebl_WStrent *root;
+  struct memoryblock *memory;
+  char *backp;
+  size_t left;
+  size_t total;
+  bool nullstr;
+
+  struct Ebl_WStrent null;
+};
+
+
+/* Cache for the pagesize.  We correct this value a bit so that `malloc'
+   is not allocating more than a page.  */
+static size_t ps;
+
+
+struct Ebl_WStrtab *
+ebl_wstrtabinit (bool nullstr)
+{
+  struct Ebl_WStrtab *ret;
+
+  if (ps == 0)
+    {
+      ps = sysconf (_SC_PAGESIZE) - 2 * sizeof (void *);
+      assert (sizeof (struct memoryblock) < ps);
+    }
+
+  ret = (struct Ebl_WStrtab *) calloc (1, sizeof (struct Ebl_WStrtab));
+  if (ret != NULL)
+    {
+      ret->nullstr = nullstr;
+      if (nullstr)
+	{
+	  ret->null.len = 1;
+	  ret->null.string = L"";
+	}
+    }
+  return ret;
+}
+
+
+static int
+morememory (struct Ebl_WStrtab *st, size_t len)
+{
+  struct memoryblock *newmem;
+
+  if (len < ps)
+    len = ps;
+  newmem = (struct memoryblock *) malloc (len);
+  if (newmem == NULL)
+    return 1;
+
+  newmem->next = st->memory;
+  st->memory = newmem;
+  st->backp = newmem->memory;
+  st->left = len - offsetof (struct memoryblock, memory);
+
+  return 0;
+}
+
+
+void
+ebl_wstrtabfree (struct Ebl_WStrtab *st)
+{
+  struct memoryblock *mb = st->memory;
+
+  while (mb != NULL)
+    {
+      void *old = mb;
+      mb = mb->next;
+      free (old);
+    }
+
+  free (st);
+}
+
+
+static struct Ebl_WStrent *
+newstring (struct Ebl_WStrtab *st, const wchar_t *str, size_t len)
+{
+  struct Ebl_WStrent *newstr;
+  size_t align;
+  int i;
+
+  /* Compute the amount of padding needed to make the structure aligned.  */
+  align = ((__alignof__ (struct Ebl_WStrent)
+	    - (((uintptr_t) st->backp)
+	       & (__alignof__ (struct Ebl_WStrent) - 1)))
+	   & (__alignof__ (struct Ebl_WStrent) - 1));
+
+  /* Make sure there is enough room in the memory block.  */
+  if (st->left < align + sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t))
+    {
+      if (morememory (st,
+		      sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t)))
+	return NULL;
+
+      align = 0;
+    }
+
+  /* Create the reserved string.  */
+  newstr = (struct Ebl_WStrent *) (st->backp + align);
+  newstr->string = str;
+  newstr->len = len;
+  newstr->next = NULL;
+  newstr->left = NULL;
+  newstr->right = NULL;
+  newstr->offset = 0;
+  for (i = len - 2; i >= 0; --i)
+    newstr->reverse[i] = str[len - 2 - i];
+  newstr->reverse[len - 1] = L'\0';
+  st->backp += align + sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t);
+  st->left -= align + sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t);
+
+  return newstr;
+}
+
+
+/* XXX This function should definitely be rewritten to use a balancing
+   tree algorith (AVL, red-black trees).  For now a simple, correct
+   implementation is enough.  */
+static struct Ebl_WStrent **
+searchstring (struct Ebl_WStrent **sep, struct Ebl_WStrent *newstr)
+{
+  int cmpres;
+
+  /* More strings?  */
+  if (*sep == NULL)
+    {
+      *sep = newstr;
+      return sep;
+    }
+
+  /* Compare the strings.  */
+  cmpres = wmemcmp ((*sep)->reverse, newstr->reverse,
+		    MIN ((*sep)->len, newstr->len) - 1);
+  if (cmpres == 0)
+    /* We found a matching string.  */
+    return sep;
+  else if (cmpres > 0)
+    return searchstring (&(*sep)->left, newstr);
+  else
+    return searchstring (&(*sep)->right, newstr);
+}
+
+
+/* Add new string.  The actual string is assumed to be permanent.  */
+struct Ebl_WStrent *
+ebl_wstrtabadd (struct Ebl_WStrtab *st, const wchar_t *str, size_t len)
+{
+  struct Ebl_WStrent *newstr;
+  struct Ebl_WStrent **sep;
+
+  /* Compute the string length if the caller doesn't know it.  */
+  if (len == 0)
+    len = wcslen (str) + 1;
+
+  /* Make sure all "" strings get offset 0 but only if the table was
+     created with a special null entry in mind.  */
+  if (len == 1 && st->null.string != NULL)
+    return &st->null;
+
+  /* Allocate memory for the new string and its associated information.  */
+  newstr = newstring (st, str, len);
+  if (newstr == NULL)
+    return NULL;
+
+  /* Search in the array for the place to insert the string.  If there
+     is no string with matching prefix and no string with matching
+     leading substring, create a new entry.  */
+  sep = searchstring (&st->root, newstr);
+  if (*sep != newstr)
+    {
+      /* This is not the same entry.  This means we have a prefix match.  */
+      if ((*sep)->len > newstr->len)
+	{
+	  struct Ebl_WStrent *subs;
+
+	  /* Check whether we already know this string.  */
+	  for (subs = (*sep)->next; subs != NULL; subs = subs->next)
+	    if (subs->len == newstr->len)
+	      {
+		/* We have an exact match with a substring.  Free the memory
+		   we allocated.  */
+		st->left += st->backp - (char *) newstr;
+		st->backp = (char *) newstr;
+
+		return subs;
+	      }
+
+	  /* We have a new substring.  This means we don't need the reverse
+	     string of this entry anymore.  */
+	  st->backp -= newstr->len;
+	  st->left += newstr->len;
+
+	  newstr->next = (*sep)->next;
+	  (*sep)->next = newstr;
+	}
+      else if ((*sep)->len != newstr->len)
+	{
+	  /* When we get here it means that the string we are about to
+	     add has a common prefix with a string we already have but
+	     it is longer.  In this case we have to put it first.  */
+	  st->total += newstr->len - (*sep)->len;
+	  newstr->next = *sep;
+	  newstr->left = (*sep)->left;
+	  newstr->right = (*sep)->right;
+	  *sep = newstr;
+	}
+      else
+	{
+	  /* We have an exact match.  Free the memory we allocated.  */
+	  st->left += st->backp - (char *) newstr;
+	  st->backp = (char *) newstr;
+
+	  newstr = *sep;
+	}
+    }
+  else
+    st->total += newstr->len;
+
+  return newstr;
+}
+
+
+static void
+copystrings (struct Ebl_WStrent *nodep, wchar_t **freep, size_t *offsetp)
+{
+  struct Ebl_WStrent *subs;
+
+  if (nodep->left != NULL)
+    copystrings (nodep->left, freep, offsetp);
+
+  /* Process the current node.  */
+  nodep->offset = *offsetp;
+  *freep = wmempcpy (*freep, nodep->string, nodep->len);
+  *offsetp += nodep->len * sizeof (wchar_t);
+
+  for (subs = nodep->next; subs != NULL; subs = subs->next)
+    {
+      assert (subs->len < nodep->len);
+      subs->offset = nodep->offset + nodep->len - subs->len;
+      assert (subs->offset != 0 || subs->string[0] == '\0');
+    }
+
+  if (nodep->right != NULL)
+    copystrings (nodep->right, freep, offsetp);
+}
+
+
+void
+ebl_wstrtabfinalize (struct Ebl_WStrtab *st, Elf_Data *data)
+{
+  size_t copylen;
+  wchar_t *endp;
+  size_t nulllen = st->nullstr ? 1 : 0;
+
+  /* Fill in the information.  */
+  data->d_buf = malloc ((st->total + nulllen) * sizeof (wchar_t));
+  if (data->d_buf == NULL)
+    abort ();
+
+  /* The first byte must always be zero if we created the table with a
+     null string.  */
+  if (st->nullstr)
+    *((wchar_t *) data->d_buf) = L'\0';
+
+  data->d_type = ELF_T_BYTE;
+  data->d_size = st->total + nulllen;
+  data->d_off = 0;
+  data->d_align = 1;
+  data->d_version = EV_CURRENT;
+
+  /* Now run through the tree and add all the string while also updating
+     the offset members of the elfstrent records.  */
+  endp = (wchar_t *) data->d_buf + nulllen;
+  copylen = sizeof (wchar_t) * nulllen;
+  copystrings (st->root, &endp, &copylen);
+  assert (copylen == (st->total + nulllen) * sizeof (wchar_t));
+}
+
+
+size_t
+ebl_wstrtaboffset (struct Ebl_WStrent *se)
+{
+  return se->offset;
+}
diff --git a/libebl/i386_corenote.c b/libebl/i386_corenote.c
new file mode 100644
index 0000000..3a123e9
--- /dev/null
+++ b/libebl/i386_corenote.c
@@ -0,0 +1,162 @@
+/* i386 specific core note handling.
+   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 <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#include <libebl_i386.h>
+
+
+/* We cannot include <sys/procfs.h> since the definition would be for
+   the host platform and not always x86 as required here.  */
+struct elf_prstatus
+  {
+    struct
+    {
+      int32_t si_signo;			/* Signal number.  */
+      int32_t si_code;			/* Extra code.  */
+      int32_t si_errno;			/* Errno.  */
+    } pr_info;				/* Info associated with signal.  */
+    int16_t pr_cursig;			/* Current signal.  */
+    uint32_t pr_sigpend;		/* Set of pending signals.  */
+    uint32_t pr_sighold;		/* Set of held signals.  */
+    int32_t pr_pid;
+    int32_t pr_ppid;
+    int32_t pr_pgrp;
+    int32_t pr_sid;
+    struct i386_timeval
+    {
+      int32_t tv_sec;
+      int32_t tv_usec;
+    } pr_utime;				/* User time.  */
+    struct i386_timeval pr_stime;	/* System time.  */
+    struct i386_timeval pr_cutime;	/* Cumulative user time.  */
+    struct i386_timeval pr_cstime;	/* Cumulative system time.  */
+    uint32_t pr_reg[17];		/* GP registers.  */
+    int32_t pr_fpvalid;			/* True if math copro being used.  */
+  };
+
+
+struct elf_prpsinfo
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    uint32_t pr_flag;			/* Flags.  */
+    uint16_t pr_uid;
+    uint16_t pr_gid;
+    int32_t pr_pid;
+    int32_t pr_ppid;
+    int32_t pr_pgrp;
+    int32_t pr_sid;
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[80];			/* Initial part of arg list.  */
+  };
+
+
+bool
+i386_core_note (name, type, descsz, desc)
+     const char *name __attribute__ ((unused));
+     uint32_t type;
+     uint32_t descsz;
+     const char *desc;
+{
+  bool result = false;
+
+  switch (type)
+    {
+    case NT_PRSTATUS:
+      if (descsz < sizeof (struct elf_prstatus))
+	/* Not enough data.  */
+	break;
+
+      struct elf_prstatus *stat = (struct elf_prstatus *) desc;
+
+      printf ("    SIGINFO:  signo: %" PRId32 ", code = %" PRId32
+	      ", errno = %" PRId32 "\n"
+	      "    signal: %" PRId16 ", pending: %08" PRIx32
+	      ", holding: %8" PRIx32 "\n"
+	      "    pid: %" PRId32 ", ppid = %" PRId32 ", pgrp = %" PRId32
+	      ", sid = %"  PRId32 "\n"
+	      "     utime: %6" PRId32 ".%06" PRId32
+	      "s,  stime: %6" PRId32 ".%06" PRId32 "s\n"
+	      "    cutime: %6" PRId32 ".%06" PRId32
+	      "s, cstime: %6" PRId32 ".%06" PRId32 "s\n"
+	      "    eax: %08" PRIx32 "  ebx: %08" PRIx32 "  ecx: %08" PRIx32
+	      "  edx: %08" PRIx32 "\n"
+	      "    esi: %08" PRIx32 "  edi: %08" PRIx32 "  ebp: %08" PRIx32
+	      "  esp: %08" PRIx32 "\n"
+	      "    eip: %08" PRIx32 "  eflags: %08" PRIx32
+	      "  original eax: %08" PRIx32 "\n"
+	      "    cs: %04" PRIx32 "  ds: %04" PRIx32 "  es: %04" PRIx32
+	      "  fs: %04" PRIx32 "  gs: %04" PRIx32 "  ss: %04" PRIx32 "\n\n",
+	      stat->pr_info.si_signo,
+	      stat->pr_info.si_code,
+	      stat->pr_info.si_errno,
+	      stat->pr_cursig,
+	      stat->pr_sigpend, stat->pr_sighold,
+	      stat->pr_pid, stat->pr_ppid, stat->pr_pgrp, stat->pr_sid,
+	      stat->pr_utime.tv_sec, stat->pr_utime.tv_usec,
+	      stat->pr_stime.tv_sec, stat->pr_stime.tv_usec,
+	      stat->pr_cutime.tv_sec, stat->pr_cutime.tv_usec,
+	      stat->pr_cstime.tv_sec, stat->pr_cstime.tv_usec,
+	      stat->pr_reg[6], stat->pr_reg[0], stat->pr_reg[1],
+	      stat->pr_reg[2], stat->pr_reg[3], stat->pr_reg[4],
+	      stat->pr_reg[5], stat->pr_reg[15], stat->pr_reg[12],
+	      stat->pr_reg[14], stat->pr_reg[11], stat->pr_reg[13] & 0xffff,
+	      stat->pr_reg[7] & 0xffff, stat->pr_reg[8] & 0xffff,
+	      stat->pr_reg[9] & 0xffff, stat->pr_reg[10] & 0xffff,
+	      stat->pr_reg[16]);
+
+      /* We handled this entry.  */
+      result = true;
+      break;
+
+    case NT_PRPSINFO:
+      if (descsz < sizeof (struct elf_prpsinfo))
+	/* Not enough data.  */
+	break;
+
+      struct elf_prpsinfo *info = (struct elf_prpsinfo *) desc;
+
+      printf ("    state: %c (%hhd),  zombie: %hhd,  nice: %hhd\n"
+	      "    flags: %08" PRIx32 ",  uid: %" PRId16 ",  gid: %" PRId16"\n"
+	      "    pid: %" PRId32 ",  ppid: %" PRId32 ",  pgrp: %" PRId32
+	      ",  sid: %" PRId32 "\n"
+	      "    fname: %.16s\n"
+	      "     args: %.80s\n\n",
+	      info->pr_sname, info->pr_state, info->pr_zomb, info->pr_nice,
+	      info->pr_flag, info->pr_uid, info->pr_gid,
+	      info->pr_pid, info->pr_ppid, info->pr_pgrp, info->pr_sid,
+	      info->pr_fname, info->pr_psargs);
+
+      /* We handled this entry.  */
+      result = true;
+      break;
+
+    default:
+      break;
+    }
+
+  return result;
+}
diff --git a/libebl/i386_destr.c b/libebl/i386_destr.c
new file mode 100644
index 0000000..50c0fd4
--- /dev/null
+++ b/libebl/i386_destr.c
@@ -0,0 +1,27 @@
+/* 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
new file mode 100644
index 0000000..264f3ef
--- /dev/null
+++ b/libebl/i386_init.c
@@ -0,0 +1,47 @@
+/* Initialization of i386 specific backend library.
+   Copyright (C) 2000, 2001, 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>
+
+
+const char *
+i386_init (elf, machine, eh, ehlen)
+     Elf *elf __attribute__ ((unused));
+     GElf_Half machine __attribute__ ((unused));
+     Ebl *eh;
+     size_t ehlen;
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "Intel 80386";
+  eh->reloc_type_name = i386_reloc_type_name;
+  eh->reloc_type_check = i386_reloc_type_check;
+  eh->reloc_valid_use = i386_reloc_valid_use;
+  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_symbol.c b/libebl/i386_symbol.c
new file mode 100644
index 0000000..e9eded2
--- /dev/null
+++ b/libebl/i386_symbol.c
@@ -0,0 +1,163 @@
+/* i386 specific symbolic name handling.
+   Copyright (C) 2000, 2001, 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 <assert.h>
+#include <elf.h>
+#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;
+}
+
+
+/* Return true if the symbol type is that referencing the GOT.  */
+bool
+i386_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), int type)
+{
+  return type == R_386_GOTPC;
+}
+
+/* Check for the simple reloc types.  */
+Elf_Type
+i386_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_386_32:
+      return ELF_T_SWORD;
+    case R_386_16:
+      return ELF_T_HALF;
+    case R_386_8:
+      return ELF_T_BYTE;
+    default:
+      return ELF_T_NUM;
+    }
+}
+
+/* Check section name for being that of a debug informatino section.  */
+bool (*generic_debugscn_p) (const char *);
+bool
+i386_debugscn_p (const char *name)
+{
+  return (generic_debugscn_p (name)
+	  || strcmp (name, ".stab") == 0
+	  || strcmp (name, ".stabstr") == 0);
+}
+
+/* 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
new file mode 100644
index 0000000..cb105f6
--- /dev/null
+++ b/libebl/ia64_destr.c
@@ -0,0 +1,27 @@
+/* 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
new file mode 100644
index 0000000..3cafe5d
--- /dev/null
+++ b/libebl/ia64_init.c
@@ -0,0 +1,43 @@
+/* Initialization of IA-64 specific backend library.
+   Copyright (C) 2002, 2003, 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>
+
+
+const char *
+ia64_init (elf, machine, eh, ehlen)
+     Elf *elf __attribute__ ((unused));
+     GElf_Half machine __attribute__ ((unused));
+     Ebl *eh;
+     size_t ehlen;
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "Intel IA-64";
+  eh->reloc_type_name = ia64_reloc_type_name;
+  eh->reloc_type_check = ia64_reloc_type_check;
+  eh->segment_type_name = ia64_segment_type_name;
+  eh->dynamic_tag_name = ia64_dynamic_tag_name;
+  eh->copy_reloc_p = ia64_copy_reloc_p;
+  eh->destr = ia64_destr;
+
+  return MODVERSION;
+}
diff --git a/libebl/ia64_symbol.c b/libebl/ia64_symbol.c
new file mode 100644
index 0000000..77ced76
--- /dev/null
+++ b/libebl/ia64_symbol.c
@@ -0,0 +1,187 @@
+/* IA-64 specific symbolic name handling.
+   Copyright (C) 2002, 2003, 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 <elf.h>
+#include <stddef.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;
+}
+
+
+const char *
+ia64_segment_type_name (int segment, char *buf __attribute__ ((unused)),
+			size_t len __attribute__ ((unused)))
+{
+  switch (segment)
+    {
+    case PT_IA_64_ARCHEXT:
+      return "IA_64_ARCHEXT";
+    case PT_IA_64_UNWIND:
+      return "IA_64_UNWIND";
+    case PT_IA_64_HP_OPT_ANOT:
+      return "IA_64_HP_OPT_ANOT";
+    case PT_IA_64_HP_HSL_ANOT:
+      return "IA_64_HP_HSL_ANOT";
+    case PT_IA_64_HP_STACK:
+      return "IA_64_HP_STACK";
+    default:
+      break;
+    }
+  return NULL;
+}
+
+
+const char *
+ia64_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
+		       size_t len __attribute__ ((unused)))
+{
+  switch (tag)
+    {
+    case DT_IA_64_PLT_RESERVE:
+      return "IA_64_PLT_RESERVE";
+    default:
+      break;
+    }
+  return NULL;
+}
+
+/* Check whether given relocation is a copy relocation.  */
+bool
+ia64_copy_reloc_p (int reloc)
+{
+  return reloc == R_IA64_COPY;
+}
diff --git a/libebl/libebl.h b/libebl/libebl.h
new file mode 100644
index 0000000..aff9ca5
--- /dev/null
+++ b/libebl/libebl.h
@@ -0,0 +1,208 @@
+/* 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.   */
+
+#ifndef _LIBEBL_H
+#define _LIBEBL_H 1
+
+#include <gelf.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <elf-knowledge.h>
+
+
+/* Opaque type for the handle.  */
+typedef struct ebl Ebl;
+
+
+/* Get backend handle for object associated with ELF handle.  */
+extern Ebl *ebl_openbackend (Elf *elf);
+/* Similar but without underlying ELF file.  */
+extern Ebl *ebl_openbackend_machine (GElf_Half machine);
+/* Similar but with emulation name given.  */
+extern Ebl *ebl_openbackend_emulation (const char *emulation);
+
+/* Free resources allocated for backend handle.  */
+extern void ebl_closebackend (Ebl *bh);
+
+
+/* Function to call the callback functions including default ELF
+   handling.  */
+
+/* Return backend name.  */
+extern const char *ebl_backend_name (Ebl *ebl);
+
+/* Return relocation type name.  */
+extern const char *ebl_object_type_name (Ebl *ebl, int object,
+					 char *buf, size_t len);
+
+/* Return relocation type name.  */
+extern const char *ebl_reloc_type_name (Ebl *ebl, int reloc,
+					char *buf, size_t len);
+
+/* Check relocation type.  */
+extern bool ebl_reloc_type_check (Ebl *ebl, int reloc);
+
+/* Check relocation type use.  */
+extern bool ebl_reloc_valid_use (Ebl *ebl, int reloc);
+
+/* Check if relocation type is for simple absolute relocations.
+   Return ELF_T_{BYTE,HALF,SWORD,SXWORD} for a simple type, else ELF_T_NUM.  */
+extern Elf_Type ebl_reloc_simple_type (Ebl *ebl, int reloc);
+
+/* Return true if the symbol type is that referencing the GOT.  E.g.,
+   R_386_GOTPC.  */
+extern bool ebl_gotpc_reloc_check (Ebl *ebl, int reloc);
+
+/* Return segment type name.  */
+extern const char *ebl_segment_type_name (Ebl *ebl, int segment,
+					  char *buf, size_t len);
+
+/* Return section type name.  */
+extern const char *ebl_section_type_name (Ebl *ebl, int section,
+					  char *buf, size_t len);
+
+/* Return section name.  */
+extern const char *ebl_section_name (Ebl *ebl, int section, int xsection,
+				     char *buf, size_t len,
+				     const char *scnnames[], size_t shnum);
+
+/* Return machine flag names.  */
+extern const char *ebl_machine_flag_name (Ebl *ebl, GElf_Word flags,
+					  char *buf, size_t len);
+
+/* Check whether machine flag is valid.  */
+extern bool ebl_machine_flag_check (Ebl *ebl, GElf_Word flags);
+
+/* Return symbol type name.  */
+extern const char *ebl_symbol_type_name (Ebl *ebl, int symbol,
+					 char *buf, size_t len);
+
+/* Return symbol binding name.  */
+extern const char *ebl_symbol_binding_name (Ebl *ebl, int binding,
+					    char *buf, size_t len);
+
+/* Return dynamic tag name.  */
+extern const char *ebl_dynamic_tag_name (Ebl *ebl, int64_t tag,
+					 char *buf, size_t len);
+
+/* Check dynamic tag.  */
+extern bool ebl_dynamic_tag_check (Ebl *ebl, int64_t tag);
+
+/* Return combined section header flags value.  */
+extern GElf_Word ebl_sh_flags_combine (Ebl *ebl, GElf_Word flags1,
+				       GElf_Word flags2);
+
+/* Return symbolic representation of OS ABI.  */
+extern const char *ebl_osabi_name (Ebl *ebl, int osabi, char *buf, size_t len);
+
+
+/* Return name of the note section type for a core file.  */
+extern const char *ebl_core_note_type_name (Ebl *ebl, uint32_t type, char *buf,
+					    size_t len);
+
+/* Return name of the note section type for an object file.  */
+extern const char *ebl_object_note_type_name (Ebl *ebl, uint32_t type,
+					      char *buf, size_t len);
+
+/* Print information about core note if available.  */
+extern void ebl_core_note (Ebl *ebl, const char *name, uint32_t type,
+			   uint32_t descsz, const char *desc);
+
+/* Print information about object note if available.  */
+extern void ebl_object_note (Ebl *ebl, 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 ebl_debugscn_p (Ebl *ebl, const char *name);
+
+/* Check whether given relocation is a copy relocation.  */
+extern bool ebl_copy_reloc_p (Ebl *ebl, int reloc);
+
+
+/* CHeck whether section should be stripped.  */
+extern bool ebl_section_strip_p (Ebl *ebl, const GElf_Ehdr *ehdr,
+				 const GElf_Shdr *shdr, const char *name,
+				 bool remove_comment, bool only_remove_debug);
+
+
+/* ELF string table handling.  */
+struct Ebl_Strtab;
+struct Ebl_Strent;
+
+/* Create new ELF string table object in memory.  */
+extern struct Ebl_Strtab *ebl_strtabinit (bool nullstr);
+
+/* Free resources allocated for ELF string table ST.  */
+extern void ebl_strtabfree (struct Ebl_Strtab *st);
+
+/* Add string STR (length LEN is != 0) to ELF string table ST.  */
+extern struct Ebl_Strent *ebl_strtabadd (struct Ebl_Strtab *st,
+					 const char *str, size_t len);
+
+/* Finalize string table ST and store size and memory location information
+   in DATA.  */
+extern void ebl_strtabfinalize (struct Ebl_Strtab *st, Elf_Data *data);
+
+/* Get offset in string table for string associated with SE.  */
+extern size_t ebl_strtaboffset (struct Ebl_Strent *se);
+
+/* Return the string associated with SE.  */
+extern const char *ebl_string (struct Ebl_Strent *se);
+
+
+/* ELF wide char string table handling.  */
+struct Ebl_WStrtab;
+struct Ebl_WStrent;
+
+/* Create new ELF wide char string table object in memory.  */
+extern struct Ebl_WStrtab *ebl_wstrtabinit (bool nullstr);
+
+/* Free resources allocated for ELF wide char string table ST.  */
+extern void ebl_wstrtabfree (struct Ebl_WStrtab *st);
+
+/* Add string STR (length LEN is != 0) to ELF string table ST.  */
+extern struct Ebl_WStrent *ebl_wstrtabadd (struct Ebl_WStrtab *st,
+					   const wchar_t *str, size_t len);
+
+/* Finalize string table ST and store size and memory location information
+   in DATA.  */
+extern void ebl_wstrtabfinalize (struct Ebl_WStrtab *st, Elf_Data *data);
+
+/* Get offset in wide char string table for string associated with SE.  */
+extern size_t ebl_wstrtaboffset (struct Ebl_WStrent *se);
+
+
+/* Generic string table handling.  */
+struct Ebl_GStrtab;
+struct Ebl_GStrent;
+
+/* Create new string table object in memory.  */
+extern struct Ebl_GStrtab *ebl_gstrtabinit (unsigned int width, bool nullstr);
+
+/* Free resources allocated for string table ST.  */
+extern void ebl_gstrtabfree (struct Ebl_GStrtab *st);
+
+/* Add string STR (length LEN is != 0) to string table ST.  */
+extern struct Ebl_GStrent *ebl_gstrtabadd (struct Ebl_GStrtab *st,
+					   const char *str, size_t len);
+
+/* Finalize string table ST and store size and memory location information
+   in DATA.  */
+extern void ebl_gstrtabfinalize (struct Ebl_GStrtab *st, Elf_Data *data);
+
+/* Get offset in wide char string table for string associated with SE.  */
+extern size_t ebl_gstrtaboffset (struct Ebl_GStrent *se);
+
+#endif	/* libebl.h */
diff --git a/libebl/libeblP.h b/libebl/libeblP.h
new file mode 100644
index 0000000..21bb8ff
--- /dev/null
+++ b/libebl/libeblP.h
@@ -0,0 +1,118 @@
+/* Internal definitions for 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.   */
+
+#ifndef _LIBEBLP_H
+#define _LIBEBLP_H 1
+
+#include <gelf.h>
+#include <libebl.h>
+#include <libintl.h>
+
+
+/* Backend handle.  */
+struct ebl
+{
+  /* Machine name.  */
+  const char *name;
+
+  /* Emulation name.  */
+  const char *emulation;
+
+  /* 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);
+
+  /* Destructor for ELF backend handle.  */
+  void (*destr) (struct ebl *);
+
+  /* Internal data.  */
+  void *dlhandle;
+};
+
+
+/* Type of the initialization functions in the backend modules.  */
+typedef const char *(*ebl_bhinit_t) (Elf *, GElf_Half, Ebl *, size_t);
+
+
+/* gettext helper macros.  */
+#define _(Str) dgettext ("elfutils", Str)
+
+#endif	/* libeblP.h */
diff --git a/libebl/libebl_alpha.h b/libebl/libebl_alpha.h
new file mode 100644
index 0000000..7990d99
--- /dev/null
+++ b/libebl/libebl_alpha.h
@@ -0,0 +1,37 @@
+/* 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);
+
+/* 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
new file mode 100644
index 0000000..aa66ad7
--- /dev/null
+++ b/libebl/libebl_alpha.map
@@ -0,0 +1,11 @@
+ELFUTILS_1.0 {
+  global:
+    alpha_backend_name;
+    alpha_destr;
+    alpha_init;
+    alpha_reloc_type_check;
+    alpha_reloc_type_name;
+
+  local:
+    *;
+};
diff --git a/libebl/libebl_arm.h b/libebl/libebl_arm.h
new file mode 100644
index 0000000..18bb99c
--- /dev/null
+++ b/libebl/libebl_arm.h
@@ -0,0 +1,37 @@
+/* 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
new file mode 100644
index 0000000..d389526
--- /dev/null
+++ b/libebl/libebl_arm.map
@@ -0,0 +1,11 @@
+ELFUTILS_1.0 {
+  global:
+    arm_backend_name;
+    arm_destr;
+    arm_init;
+    arm_reloc_type_check;
+    arm_reloc_type_name;
+
+  local:
+    *;
+};
diff --git a/libebl/libebl_i386.h b/libebl/libebl_i386.h
new file mode 100644
index 0000000..ef2b319
--- /dev/null
+++ b/libebl/libebl_i386.h
@@ -0,0 +1,54 @@
+/* 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
new file mode 100644
index 0000000..d0c910c
--- /dev/null
+++ b/libebl/libebl_i386.map
@@ -0,0 +1,14 @@
+ELFUTILS_1.0 {
+  global:
+    i386_backend_name;
+    i386_core_note;
+    i386_destr;
+    i386_init;
+    i386_reloc_type_check;
+    i386_reloc_type_name;
+    i386_reloc_valid_use;
+    i386_reloc_simple_type;
+
+  local:
+    *;
+};
diff --git a/libebl/libebl_ia64.h b/libebl/libebl_ia64.h
new file mode 100644
index 0000000..8dea650
--- /dev/null
+++ b/libebl/libebl_ia64.h
@@ -0,0 +1,43 @@
+/* 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);
+
+#endif	/* libebl_ia64.h */
diff --git a/libebl/libebl_ia64.map b/libebl/libebl_ia64.map
new file mode 100644
index 0000000..f67042c
--- /dev/null
+++ b/libebl/libebl_ia64.map
@@ -0,0 +1,11 @@
+ELFUTILS_1.0 {
+  global:
+    ia64_backend_name;
+    ia64_destr;
+    ia64_init;
+    ia64_reloc_type_check;
+    ia64_reloc_type_name;
+
+  local:
+    *;
+};
diff --git a/libebl/libebl_ppc.h b/libebl/libebl_ppc.h
new file mode 100644
index 0000000..1e646d4
--- /dev/null
+++ b/libebl/libebl_ppc.h
@@ -0,0 +1,47 @@
+/* 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);
+
+/* Check whether given relocation is a copy relocation.  */
+extern bool ppc_copy_reloc_p (int reloc);
+
+#endif	/* libebl_ppc.h */
diff --git a/libebl/libebl_ppc.map b/libebl/libebl_ppc.map
new file mode 100644
index 0000000..3d49c0b
--- /dev/null
+++ b/libebl/libebl_ppc.map
@@ -0,0 +1,12 @@
+ELFUTILS_1.0 {
+  global:
+    ppc_backend_name;
+    ppc_destr;
+    ppc_init;
+    ppc_reloc_type_check;
+    ppc_reloc_type_name;
+    ppc_reloc_simple_type;
+
+  local:
+    *;
+};
diff --git a/libebl/libebl_ppc64.h b/libebl/libebl_ppc64.h
new file mode 100644
index 0000000..e737c56
--- /dev/null
+++ b/libebl/libebl_ppc64.h
@@ -0,0 +1,50 @@
+/* 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 whether given relocation is a copy relocation.  */
+extern bool ppc64_copy_reloc_p (int reloc);
+
+#endif	/* libebl_ppc.h */
diff --git a/libebl/libebl_ppc64.map b/libebl/libebl_ppc64.map
new file mode 100644
index 0000000..260805d
--- /dev/null
+++ b/libebl/libebl_ppc64.map
@@ -0,0 +1,12 @@
+ELFUTILS_1.0 {
+  global:
+    ppc64_backend_name;
+    ppc64_destr;
+    ppc64_init;
+    ppc64_reloc_type_check;
+    ppc64_reloc_type_name;
+    ppc64_reloc_simple_type;
+
+  local:
+    *;
+};
diff --git a/libebl/libebl_sh.h b/libebl/libebl_sh.h
new file mode 100644
index 0000000..32b029a
--- /dev/null
+++ b/libebl/libebl_sh.h
@@ -0,0 +1,34 @@
+/* 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
new file mode 100644
index 0000000..252720a
--- /dev/null
+++ b/libebl/libebl_sh.map
@@ -0,0 +1,10 @@
+ELFUTILS_1.0 {
+  global:
+    sh_backend_name;
+    sh_destr;
+    sh_init;
+    sh_reloc_type_name;
+
+  local:
+    *;
+};
diff --git a/libebl/libebl_sparc.h b/libebl/libebl_sparc.h
new file mode 100644
index 0000000..077db17
--- /dev/null
+++ b/libebl/libebl_sparc.h
@@ -0,0 +1,41 @@
+/* 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
new file mode 100644
index 0000000..7ca6038
--- /dev/null
+++ b/libebl/libebl_sparc.map
@@ -0,0 +1,11 @@
+ELFUTILS_1.0 {
+  global:
+    sparc_backend_name;
+    sparc_destr;
+    sparc_init;
+    sparc_reloc_type_check;
+    sparc_reloc_type_name;
+
+  local:
+    *;
+};
diff --git a/libebl/libebl_x86_64.h b/libebl/libebl_x86_64.h
new file mode 100644
index 0000000..025edb6
--- /dev/null
+++ b/libebl/libebl_x86_64.h
@@ -0,0 +1,47 @@
+/* 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
new file mode 100644
index 0000000..e6d1c7b
--- /dev/null
+++ b/libebl/libebl_x86_64.map
@@ -0,0 +1,13 @@
+ELFUTILS_1.0 {
+  global:
+    x86_64_backend_name;
+    x86_64_core_note;
+    x86_64_destr;
+    x86_64_init;
+    x86_64_reloc_type_check;
+    x86_64_reloc_type_name;
+    x86_64_reloc_simple_type;
+
+  local:
+    *;
+};
diff --git a/libebl/ppc64_destr.c b/libebl/ppc64_destr.c
new file mode 100644
index 0000000..8da6a8f
--- /dev/null
+++ b/libebl/ppc64_destr.c
@@ -0,0 +1,27 @@
+/* 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
new file mode 100644
index 0000000..8231a32
--- /dev/null
+++ b/libebl/ppc64_init.c
@@ -0,0 +1,44 @@
+/* Initialization of 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>
+
+
+const char *
+ppc64_init (elf, machine, eh, ehlen)
+     Elf *elf __attribute__ ((unused));
+     GElf_Half machine __attribute__ ((unused));
+     Ebl *eh;
+     size_t ehlen;
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "PowerPC 64-bit";
+  eh->reloc_type_name = ppc64_reloc_type_name;
+  eh->reloc_type_check = ppc64_reloc_type_check;
+  eh->reloc_valid_use = ppc64_reloc_valid_use;
+  eh->reloc_simple_type = ppc64_reloc_simple_type;
+  eh->dynamic_tag_name = ppc64_dynamic_tag_name;
+  eh->copy_reloc_p = ppc64_copy_reloc_p;
+  eh->destr = ppc64_destr;
+
+  return MODVERSION;
+}
diff --git a/libebl/ppc64_symbol.c b/libebl/ppc64_symbol.c
new file mode 100644
index 0000000..f844816
--- /dev/null
+++ b/libebl/ppc64_symbol.c
@@ -0,0 +1,235 @@
+/* PPC64 specific symbolic name handling.
+   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 <assert.h>
+#include <elf.h>
+#include <stddef.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;
+}
+
+
+/* Check for the simple reloc types.  */
+Elf_Type
+ppc64_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_PPC64_ADDR64:
+    case R_PPC64_UADDR64:
+      return ELF_T_XWORD;
+    case R_PPC64_ADDR32:
+    case R_PPC64_UADDR32:
+      return ELF_T_WORD;
+    case R_PPC64_UADDR16:
+      return ELF_T_HALF;
+    default:
+      return ELF_T_NUM;
+    }
+}
+
+
+const char *
+ppc64_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
+			size_t len __attribute__ ((unused)))
+{
+  switch (tag)
+    {
+    case DT_PPC64_GLINK:
+      return "PPC64_GLINK";
+    case DT_PPC64_OPD:
+      return "PPC64_OPD";
+    case DT_PPC64_OPDSZ:
+      return "PPC64_OPDSZ";
+    default:
+      break;
+    }
+  return NULL;
+}
+
+/* Check whether given relocation is a copy relocation.  */
+bool
+ppc64_copy_reloc_p (int reloc)
+{
+  return reloc == R_PPC64_COPY;
+}
diff --git a/libebl/ppc_destr.c b/libebl/ppc_destr.c
new file mode 100644
index 0000000..65bb81c
--- /dev/null
+++ b/libebl/ppc_destr.c
@@ -0,0 +1,27 @@
+/* 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
new file mode 100644
index 0000000..4d72c46
--- /dev/null
+++ b/libebl/ppc_init.c
@@ -0,0 +1,43 @@
+/* Initialization of 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>
+
+
+const char *
+ppc_init (elf, machine, eh, ehlen)
+     Elf *elf __attribute__ ((unused));
+     GElf_Half machine __attribute__ ((unused));
+     Ebl *eh;
+     size_t ehlen;
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "PowerPC";
+  eh->reloc_type_name = ppc_reloc_type_name;
+  eh->reloc_type_check = ppc_reloc_type_check;
+  eh->reloc_valid_use = ppc_reloc_valid_use;
+  eh->reloc_simple_type = ppc_reloc_simple_type;
+  eh->copy_reloc_p = ppc_copy_reloc_p;
+  eh->destr = ppc_destr;
+
+  return MODVERSION;
+}
diff --git a/libebl/ppc_symbol.c b/libebl/ppc_symbol.c
new file mode 100644
index 0000000..20beae3
--- /dev/null
+++ b/libebl/ppc_symbol.c
@@ -0,0 +1,174 @@
+/* PPC specific symbolic name handling.
+   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 <assert.h>
+#include <elf.h>
+#include <stddef.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 }
+  };
+
+
+/* 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 || type >= R_PPC_NUM)
+    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 && type < R_PPC_NUM
+	  && 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;
+}
+
+
+/* Check for the simple reloc types.  */
+Elf_Type
+ppc_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_PPC_ADDR32:
+    case R_PPC_UADDR32:
+      return ELF_T_WORD;
+    case R_PPC_UADDR16:
+      return ELF_T_HALF;
+    default:
+      return ELF_T_NUM;
+    }
+}
+
+/* Check whether given relocation is a copy relocation.  */
+bool
+ppc_copy_reloc_p (int reloc)
+{
+  return reloc == R_PPC_COPY;
+}
diff --git a/libebl/sh_destr.c b/libebl/sh_destr.c
new file mode 100644
index 0000000..4f06534
--- /dev/null
+++ b/libebl/sh_destr.c
@@ -0,0 +1,27 @@
+/* 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
new file mode 100644
index 0000000..bb6c904
--- /dev/null
+++ b/libebl/sh_init.c
@@ -0,0 +1,40 @@
+/* Initialization of SH specific backend library.
+   Copyright (C) 2000, 2001, 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>
+
+
+const char *
+sh_init (elf, machine, eh, ehlen)
+     Elf *elf __attribute__ ((unused));
+     GElf_Half machine __attribute__ ((unused));
+     Ebl *eh;
+     size_t ehlen;
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "Hitachi SH";
+  eh->reloc_type_name = sh_reloc_type_name;
+  eh->copy_reloc_p = sh_copy_reloc_p;
+  eh->destr = sh_destr;
+
+  return MODVERSION;
+}
diff --git a/libebl/sh_symbol.c b/libebl/sh_symbol.c
new file mode 100644
index 0000000..e24fff1
--- /dev/null
+++ b/libebl/sh_symbol.c
@@ -0,0 +1,99 @@
+/* SH specific relocation handling.
+   Copyright (C) 2000, 2001, 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 <elf.h>
+#include <stddef.h>
+
+#include <libebl_sh.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.  */
+bool
+sh_copy_reloc_p (int reloc)
+{
+  return reloc == R_SH_COPY;
+}
diff --git a/libebl/sparc_destr.c b/libebl/sparc_destr.c
new file mode 100644
index 0000000..819f361
--- /dev/null
+++ b/libebl/sparc_destr.c
@@ -0,0 +1,26 @@
+/* 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
new file mode 100644
index 0000000..ac461a1
--- /dev/null
+++ b/libebl/sparc_init.c
@@ -0,0 +1,46 @@
+/* Initialization of SPARC specific backend library.
+   Copyright (C) 2002, 2005 Red Hat, Inc.
+
+   This program is Open Source software; you can redistribute it and/or
+   modify it under the terms of the Open Software License version 1.0 as
+   published by the Open Source Initiative.
+
+   You should have received a copy of the Open Software License along
+   with this program; if not, you may obtain a copy of the Open Software
+   License version 1.0 from http://www.opensource.org/licenses/osl.php or
+   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+   3001 King Ranch Road, Ukiah, CA 95482.   */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libebl_sparc.h>
+
+
+const char *
+sparc_init (elf, machine, eh, ehlen)
+     Elf *elf __attribute__ ((unused));
+     GElf_Half machine __attribute__ ((unused));
+     Ebl *eh;
+     size_t ehlen;
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  if (machine == EM_SPARCV9)
+    eh->name = "SPARC v9";
+  else if (machine == EM_SPARC32PLUS)
+    eh->name = "SPARC v8+";
+  else
+    eh->name = "SPARC";
+  eh->reloc_type_name = sparc_reloc_type_name;
+  eh->reloc_type_check = sparc_reloc_type_check;
+  //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_symbol.c b/libebl/sparc_symbol.c
new file mode 100644
index 0000000..f33ed53
--- /dev/null
+++ b/libebl/sparc_symbol.c
@@ -0,0 +1,149 @@
+/* SPARC specific symbolic name handling.
+   Copyright (C) 2002, 2003, 2005 Red Hat, Inc.
+   Written by Jakub Jelinek <jakub@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 <elf.h>
+#include <stddef.h>
+
+#include <libebl_sparc.h>
+
+
+/* Return of the backend.  */
+const char *
+sparc_backend_name (void)
+{
+  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;
+}
diff --git a/libebl/x86_64_corenote.c b/libebl/x86_64_corenote.c
new file mode 100644
index 0000000..0ee7cea
--- /dev/null
+++ b/libebl/x86_64_corenote.c
@@ -0,0 +1,171 @@
+/* x86-64 specific core note handling.
+   Copyright (C) 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This program is Open Source software; you can redistribute it and/or
+   modify it under the terms of the Open Software License version 1.0 as
+   published by the Open Source Initiative.
+
+   You should have received a copy of the Open Software License along
+   with this program; if not, you may obtain a copy of the Open Software
+   License version 1.0 from http://www.opensource.org/licenses/osl.php or
+   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+   3001 King Ranch Road, Ukiah, CA 95482.   */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#include <libebl_x86_64.h>
+
+
+/* We cannot include <sys/procfs.h> since the definition would be for
+   the host platform and not always x86-64 as required here.  */
+struct elf_prstatus
+  {
+    struct
+    {
+      int32_t si_signo;			/* Signal number.  */
+      int32_t si_code;			/* Extra code.  */
+      int32_t si_errno;			/* Errno.  */
+    } pr_info;				/* Info associated with signal.  */
+    int16_t pr_cursig;			/* Current signal.  */
+    uint64_t pr_sigpend;		/* Set of pending signals.  */
+    uint64_t pr_sighold;		/* Set of held signals.  */
+    int32_t pr_pid;
+    int32_t pr_ppid;
+    int32_t pr_pgrp;
+    int32_t pr_sid;
+    struct x86_64_timeval
+    {
+      int64_t tv_sec;
+      int32_t tv_usec;
+    } pr_utime;				/* User time.  */
+    struct x86_64_timeval pr_stime;	/* System time.  */
+    struct x86_64_timeval pr_cutime;	/* Cumulative user time.  */
+    struct x86_64_timeval pr_cstime;	/* Cumulative system time.  */
+    uint64_t pr_reg[27];	/* GP registers.  */
+    int32_t pr_fpvalid;			/* True if math copro being used.  */
+  };
+
+
+struct elf_prpsinfo
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    uint64_t pr_flag;			/* Flags.  */
+    uint32_t pr_uid;
+    uint32_t pr_gid;
+    int32_t pr_pid;
+    int32_t pr_ppid;
+    int32_t pr_pgrp;
+    int32_t pr_sid;
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[80];			/* Initial part of arg list.  */
+  };
+
+
+bool
+x86_64_core_note (name, type, descsz, desc)
+     const char *name __attribute__ ((unused));
+     uint32_t type;
+     uint32_t descsz;
+     const char *desc;
+{
+  bool result = false;
+
+  switch (type)
+    {
+    case NT_PRSTATUS:
+      if (descsz < sizeof (struct elf_prstatus))
+	/* Not enough data.  */
+	break;
+
+      struct elf_prstatus *stat = (struct elf_prstatus *) desc;
+
+      printf ("    SIGINFO:  signo: %" PRId32 ", code = %" PRId32
+	      ", errno = %" PRId32 "\n"
+	      "    signal: %" PRId16 ", pending: %#08" PRIx64 ", holding: %#08"
+	      PRIx64 "\n"
+	      "    pid: %" PRId32 ", ppid = %" PRId32 ", pgrp = %" PRId32
+	      ", sid = %" PRId32 "\n"
+	      "     utime: %6" PRId64 ".%06" PRId32
+	      "s,  stime: %6" PRId64 ".%06" PRId32 "s\n"
+	      "    cutime: %6" PRId64 ".%06" PRId32
+	      "s, cstime: %6" PRId64 ".%06" PRId32 "s\n"
+	      "    rax: %016" PRIx64 "  rbx: %016" PRIx64 "\n"
+	      "    rcx: %016" PRIx64 "  rdx: %016" PRIx64 "\n"
+	      "    rsi: %016" PRIx64 "  rdi: %016" PRIx64 "\n"
+	      "    rbp: %016" PRIx64 "  rsp: %016" PRIx64 "\n"
+	      "    r8:  %016" PRIx64 "  r9:  %016" PRIx64 "\n"
+	      "    r10: %016" PRIx64 "  r11: %016" PRIx64 "\n"
+	      "    r12: %016" PRIx64 "  r13: %016" PRIx64 "\n"
+	      "    r14: %016" PRIx64 "  r15: %016" PRIx64 "\n"
+	      "    rip: %016" PRIx64 "  eflags: %08" PRIx64 "\n"
+	      "    original rax: %016" PRIx64 "\n"
+	      "    cs: %04" PRIx64 "  ds: %04" PRIx64 "  es: %04" PRIx64
+	      "  ss: %04" PRIx64 "\n"
+	      "    fs: %04" PRIx64 "  fs_base: %016" PRIx64
+	      "  gs: %04" PRIx64 "  gs_base: %016" PRIx64 "\n\n",
+	      stat->pr_info. si_signo,
+	      stat->pr_info. si_code,
+	      stat->pr_info. si_errno,
+	      stat->pr_cursig,
+	      stat->pr_sigpend, stat->pr_sighold,
+	      stat->pr_pid, stat->pr_ppid, stat->pr_pgrp, stat->pr_sid,
+	      stat->pr_utime.tv_sec, stat->pr_utime.tv_usec,
+	      stat->pr_stime.tv_sec, stat->pr_stime.tv_usec,
+	      stat->pr_cutime.tv_sec, stat->pr_cutime.tv_usec,
+	      stat->pr_cstime.tv_sec, stat->pr_cstime.tv_usec,
+	      stat->pr_reg[10], stat->pr_reg[5], stat->pr_reg[11],
+	      stat->pr_reg[12], stat->pr_reg[13], stat->pr_reg[14],
+	      stat->pr_reg[4], stat->pr_reg[10], stat->pr_reg[9],
+	      stat->pr_reg[7], stat->pr_reg[6], stat->pr_reg[5],
+	      stat->pr_reg[3], stat->pr_reg[2], stat->pr_reg[1],
+	      stat->pr_reg[0], stat->pr_reg[16], stat->pr_reg[18],
+	      stat->pr_reg[15], stat->pr_reg[17], stat->pr_reg[23],
+	      stat->pr_reg[24], stat->pr_reg[20],
+	      stat->pr_reg[25], stat->pr_reg[21],
+	      stat->pr_reg[26], stat->pr_reg[22]);
+
+      /* We handled this entry.  */
+      result = true;
+      break;
+
+    case NT_PRPSINFO:
+      if (descsz < sizeof (struct elf_prpsinfo))
+	/* Not enough data.  */
+	break;
+
+      struct elf_prpsinfo *info = (struct elf_prpsinfo *) desc;
+
+      printf ("    state: %c (%hhd),  zombie: %hhd,  nice: %hhd\n"
+	      "    flags: %08" PRIx64 "  uid: %" PRIu32 "  gid: %" PRIu32 "\n"
+	      "    pid: %" PRId32 "  ppid: %" PRId32 "  pgrp: %" PRId32
+	      "  sid: %" PRId32 "\n"
+	      "    fname: %.16s\n"
+	      "     args: %.80s\n\n",
+	      info->pr_sname, info->pr_state, info->pr_zomb, info->pr_nice,
+	      info->pr_flag, info->pr_uid, info->pr_gid,
+	      info->pr_pid, info->pr_ppid, info->pr_pgrp, info->pr_sid,
+	      info->pr_fname, info->pr_psargs);
+
+      /* We handled this entry.  */
+      result = true;
+      break;
+
+    default:
+      break;
+    }
+
+  return result;
+}
diff --git a/libebl/x86_64_destr.c b/libebl/x86_64_destr.c
new file mode 100644
index 0000000..3805829
--- /dev/null
+++ b/libebl/x86_64_destr.c
@@ -0,0 +1,27 @@
+/* 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
new file mode 100644
index 0000000..655a67f
--- /dev/null
+++ b/libebl/x86_64_init.c
@@ -0,0 +1,44 @@
+/* Initialization of 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>
+
+
+const char *
+x86_64_init (elf, machine, eh, ehlen)
+     Elf *elf __attribute__ ((unused));
+     GElf_Half machine __attribute__ ((unused));
+     Ebl *eh;
+     size_t ehlen;
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "AMD x86-64";
+  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;
+  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_symbol.c b/libebl/x86_64_symbol.c
new file mode 100644
index 0000000..38d357c
--- /dev/null
+++ b/libebl/x86_64_symbol.c
@@ -0,0 +1,136 @@
+/* x86_64 specific symbolic name handling.
+   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 <assert.h>
+#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;
+}
+
+/* Check for the simple reloc types.  */
+Elf_Type
+x86_64_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_X86_64_64:
+      return ELF_T_XWORD;
+    case R_X86_64_32:
+      return ELF_T_WORD;
+    case R_X86_64_32S:
+      return ELF_T_SWORD;
+    case R_X86_64_16:
+      return ELF_T_HALF;
+    case R_X86_64_8:
+      return ELF_T_BYTE;
+    default:
+      return ELF_T_NUM;
+    }
+}
+
+/* Check whether given relocation is a copy relocation.  */
+bool
+x86_64_copy_reloc_p (int reloc)
+{
+  return reloc == R_X86_64_COPY;
+}