summaryrefslogtreecommitdiff
path: root/libebl
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2005-07-26 05:00:05 +0000
committerUlrich Drepper <drepper@redhat.com>2005-07-26 05:00:05 +0000
commitb08d5a8fb42f4586d756068065186b5af7e48dad (patch)
tree9f05f86be7877ed461b4dc05f53b29ea4fc0d2a1 /libebl
downloadelfutils-b08d5a8fb42f4586d756068065186b5af7e48dad.tar.gz
Adjust for monotone.
Diffstat (limited to 'libebl')
-rw-r--r--libebl/.cvsignore1
-rw-r--r--libebl/ChangeLog281
-rw-r--r--libebl/Makefile.am201
-rw-r--r--libebl/alpha_destr.c27
-rw-r--r--libebl/alpha_init.c41
-rw-r--r--libebl/alpha_symbol.c101
-rw-r--r--libebl/arm_destr.c27
-rw-r--r--libebl/arm_init.c41
-rw-r--r--libebl/arm_symbol.c121
-rw-r--r--libebl/eblbackendname.c28
-rw-r--r--libebl/eblclosebackend.c39
-rw-r--r--libebl/eblcopyrelocp.c28
-rw-r--r--libebl/eblcorenote.c191
-rw-r--r--libebl/eblcorenotetypename.c68
-rw-r--r--libebl/ebldebugscnp.c29
-rw-r--r--libebl/ebldynamictagcheck.c41
-rw-r--r--libebl/ebldynamictagname.c97
-rw-r--r--libebl/eblgotpcreloccheck.c29
-rw-r--r--libebl/eblgstrtab.c350
-rw-r--r--libebl/eblmachineflagcheck.c28
-rw-r--r--libebl/eblmachineflagname.c76
-rw-r--r--libebl/eblobjecttypename.c48
-rw-r--r--libebl/eblobjnote.c87
-rw-r--r--libebl/eblobjnotetypename.c54
-rw-r--r--libebl/eblopenbackend.c551
-rw-r--r--libebl/eblosabiname.c69
-rw-r--r--libebl/eblrelocsimpletype.c27
-rw-r--r--libebl/eblreloctypecheck.c28
-rw-r--r--libebl/eblreloctypename.c38
-rw-r--r--libebl/eblrelocvaliduse.c28
-rw-r--r--libebl/eblsectionname.c81
-rw-r--r--libebl/eblsectionstripp.c52
-rw-r--r--libebl/eblsectiontypename.c103
-rw-r--r--libebl/eblsegmenttypename.c75
-rw-r--r--libebl/eblshflagscombine.c29
-rw-r--r--libebl/eblstrtab.c337
-rw-r--r--libebl/eblsymbolbindingname.c57
-rw-r--r--libebl/eblsymboltypename.c63
-rw-r--r--libebl/eblwstrtab.c344
-rw-r--r--libebl/i386_corenote.c162
-rw-r--r--libebl/i386_destr.c27
-rw-r--r--libebl/i386_init.c47
-rw-r--r--libebl/i386_symbol.c163
-rw-r--r--libebl/ia64_destr.c27
-rw-r--r--libebl/ia64_init.c43
-rw-r--r--libebl/ia64_symbol.c187
-rw-r--r--libebl/libebl.h208
-rw-r--r--libebl/libeblP.h118
-rw-r--r--libebl/libebl_alpha.h37
-rw-r--r--libebl/libebl_alpha.map11
-rw-r--r--libebl/libebl_arm.h37
-rw-r--r--libebl/libebl_arm.map11
-rw-r--r--libebl/libebl_i386.h54
-rw-r--r--libebl/libebl_i386.map14
-rw-r--r--libebl/libebl_ia64.h43
-rw-r--r--libebl/libebl_ia64.map11
-rw-r--r--libebl/libebl_ppc.h47
-rw-r--r--libebl/libebl_ppc.map12
-rw-r--r--libebl/libebl_ppc64.h50
-rw-r--r--libebl/libebl_ppc64.map12
-rw-r--r--libebl/libebl_sh.h34
-rw-r--r--libebl/libebl_sh.map10
-rw-r--r--libebl/libebl_sparc.h41
-rw-r--r--libebl/libebl_sparc.map11
-rw-r--r--libebl/libebl_x86_64.h47
-rw-r--r--libebl/libebl_x86_64.map13
-rw-r--r--libebl/ppc64_destr.c27
-rw-r--r--libebl/ppc64_init.c44
-rw-r--r--libebl/ppc64_symbol.c235
-rw-r--r--libebl/ppc_destr.c27
-rw-r--r--libebl/ppc_init.c43
-rw-r--r--libebl/ppc_symbol.c174
-rw-r--r--libebl/sh_destr.c27
-rw-r--r--libebl/sh_init.c40
-rw-r--r--libebl/sh_symbol.c99
-rw-r--r--libebl/sparc_destr.c26
-rw-r--r--libebl/sparc_init.c46
-rw-r--r--libebl/sparc_symbol.c149
-rw-r--r--libebl/x86_64_corenote.c171
-rw-r--r--libebl/x86_64_destr.c27
-rw-r--r--libebl/x86_64_init.c44
-rw-r--r--libebl/x86_64_symbol.c136
82 files changed, 6708 insertions, 0 deletions
diff --git a/libebl/.cvsignore b/libebl/.cvsignore
new file mode 100644
index 00000000..70845e08
--- /dev/null
+++ b/libebl/.cvsignore
@@ -0,0 +1 @@
+Makefile.in
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
new file mode 100644
index 00000000..a14572c0
--- /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 00000000..5f7be50b
--- /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 00000000..4fc5cf85
--- /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 00000000..17eff373
--- /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 00000000..49e7c72f
--- /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 00000000..2675720a
--- /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 00000000..a0a65f83
--- /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 00000000..f4de8be9
--- /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 00000000..03830ebe
--- /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 00000000..c5579612
--- /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 00000000..2d3362a2
--- /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 00000000..725d3a1b
--- /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 00000000..4a94d2ba
--- /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 00000000..59310b51
--- /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 00000000..68b41691
--- /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 00000000..464c1e2a
--- /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 00000000..8ae8b7b8
--- /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 00000000..57cb2d8f
--- /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 00000000..abc8d302
--- /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 00000000..228a9945
--- /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 00000000..c099c71d
--- /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 00000000..5adff18e
--- /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 00000000..a963cefb
--- /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 00000000..dc2f7c30
--- /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 00000000..9a1e6534
--- /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 00000000..3e048d1f
--- /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 00000000..cafbc611
--- /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 00000000..5fa95608
--- /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 00000000..74889861
--- /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 00000000..6c801db6
--- /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 00000000..77a22cac
--- /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 00000000..e6857acd
--- /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 00000000..c59f037d
--- /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 00000000..7edcf4e7
--- /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 00000000..165909f4
--- /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 00000000..efcd250e
--- /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 00000000..d11aec1a
--- /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 00000000..8320cb58
--- /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 00000000..3a123e92
--- /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 00000000..50c0fd48
--- /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 00000000..264f3ef7
--- /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 00000000..e9eded23
--- /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 00000000..cb105f64
--- /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 00000000..3cafe5de
--- /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 00000000..77ced76d
--- /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 00000000..aff9ca5e
--- /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 00000000..21bb8fff
--- /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 00000000..7990d995
--- /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 00000000..aa66ad75
--- /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 00000000..18bb99c4
--- /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 00000000..d389526c
--- /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 00000000..ef2b3199
--- /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 00000000..d0c910c7
--- /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 00000000..8dea6500
--- /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 00000000..f67042c6
--- /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 00000000..1e646d4f
--- /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 00000000..3d49c0b3
--- /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 00000000..e737c56a
--- /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 00000000..260805d4
--- /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 00000000..32b029a7
--- /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 00000000..252720a9
--- /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 00000000..077db170
--- /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 00000000..7ca60383
--- /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 00000000..025edb63
--- /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 00000000..e6d1c7bd
--- /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 00000000..8da6a8fd
--- /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 00000000..8231a32d
--- /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 00000000..f844816b
--- /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 00000000..65bb81cc
--- /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 00000000..4d72c46d
--- /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 00000000..20beae31
--- /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 00000000..4f065343
--- /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 00000000..bb6c9040
--- /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 00000000..e24fff15
--- /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 00000000..819f3616
--- /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 00000000..ac461a10
--- /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 00000000..f33ed537
--- /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 00000000..0ee7ceae
--- /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 00000000..38058299
--- /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 00000000..655a67fb
--- /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 00000000..38d357cb
--- /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;
+}