Adjust for monotone.
diff --git a/libelf/.cvsignore b/libelf/.cvsignore
new file mode 100644
index 0000000..70845e0
--- /dev/null
+++ b/libelf/.cvsignore
@@ -0,0 +1 @@
+Makefile.in
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
new file mode 100644
index 0000000..caa2b5b
--- /dev/null
+++ b/libelf/ChangeLog
@@ -0,0 +1,141 @@
+2005-07-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf-knowledge.h (SECTION_STRIP_P): Don't handle removal of debug
+	sections here anymore.
+	* elf32_checksum.c: Adjust for change in SECTION_STRIP_P interface.
+
+	* elf_update.c (elf_update): Get write lock, not read lock.
+
+	* elf32_updatenull.c (updatenull): Get section headers if necessary
+	and possible.
+
+2005-07-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatenull.c (updatenull): If program header hasn't been loaded
+	yet, try to do it now.
+	Don't unnecessarily update overflow of section count in zeroth section
+	sh_size field.
+	If section content hasn't been read yet, do it before looking for the
+	block size.  If no section data present, infer size of section header.
+
+2005-05-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update again.
+
+2005-05-09  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2005-05-08  Roland McGrath  <roland@redhat.com>
+
+	* elf_begin.c (read_file) [_MUDFLAP]: Don't use mmap for now.
+	* elf_update.c (write_file) [_MUDFLAP]: Likewise.
+
+2005-03-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_checksum.c: Use INTUSE and INTDEF to avoid PLTs.
+	* elf_end.c: Likewise.
+	* elf_getdata.c: Likewise.
+	* gelf_getehdr.c: Likewise.
+	* nlist.c: Likewise.
+	* libelfP.h: Add declarations of internal functions.
+
+2005-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* common.h (CONVERT): Make sure all values are unsigned.
+	(CONVERT_TO): Likewise.
+
+	* Makefile.am (AM_CFLAGS): Add -Wformat=2.
+	Fix rule to build libelf.so.
+
+2005-02-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Cleanup AM_CFLAGS handling.  Add -Wunused -Wextra.
+	Remove lint handling.
+	* elf32_getphdr.c: Minor cleanups.
+	* elf32_getshdr.c: Likewise.
+	* elf32_updatefile.c: Likewise.
+	* elf32_updatenull.c: Likewise.
+	* elf_begin.c: Likewise.
+	* elf_error.c: Likewise.
+	* elf_getarsym.c: Likewise.
+	* elf_getdata.c: Likewise.
+	* elf_update.c: Likewise.
+	* gelf_xlate.c: Likewise.
+
+2005-02-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Check for text relocations in constructed DSO.
+
+	* Makefile.am [MUDFLAP] (AM_CFLAGS): Add -Werror -fpic -fmudflap.
+
+2005-02-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* gelf_getehdr.c (gelf_getehdr): Slight optimization.
+
+	* elf32_checksum.c (checksum): Do not look at NOBITS sections.
+
+	* gelf.h: Add gelf_checksum prototype.
+
+2004-09-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_checksum.c: Make compile with gcc 4.0.
+	* elf32_updatefile.c: Likewise.
+	* elf32_updatenull.c: Likewise.
+	* elf_begin.c: Likewise.
+	* elf_error.c: Likewise.
+	* elf_getdata.c: Likewise.
+	* elf_getident.c: Likewise.
+
+2004-04-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2004-01-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_update.c: Fix locking.
+	* elf_clone.c: Likewise.
+
+	* libelf.h: Define ELF_T_LIB.
+	* gelf_getlib.c: New file.
+	* gelf_update_lib.c: New file.
+	* gelf.h: Declare the new functions.  Define GElf_Lib.
+	* abstract.h: Define Lib, Lib32, Lib64.
+	* gelf_xlate.c (__elf_xfctstom): Add ELF_T_LIB entry.
+	* gelf_xlate.h: Add entry for ElfXX_Lib.
+	* elf_getdata.c: Recognize SHT_GNU_LIBLIST as a known section type.
+	* libelf.map: Add new symbols to ELFUTILS_1.1.
+	* Makefile.am (libelf_a_SOURCES): Add gelf_getlib.c and
+	gelf_update_lib.c.
+
+2004-01-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Support building with mudflap.
+
+	* gelf_xlate.c (INLINE3): Avoid using cast as lvalue.
+	* dl-hash.h (_dl_elf_hash): Likewise.
+
+2004-01-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf-knowledge.h: New file.  From libelf subdir.
+	* Makefile.am (euincludedir): Define.
+	(euinclude_HEADERS): Add elf-knowledge.h.
+
+2003-09-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Define some PT_IA_64_HP_* constants.
+
+2003-09-23  Jakub Jelinek  <jakub@redhat.com>
+
+	* libelfP.h (struct Elf): Move state.elf64.sizestr_offset after
+	state.elf64.scnincr to match state.elf{,32}.
+
+2003-08-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c (__updatemmap): When writing back file where
+	some sections have not been read in, count their sizes based on
+	the section header.
+
+2003-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+        * Moved to CVS archive.
diff --git a/libelf/Makefile.am b/libelf/Makefile.am
new file mode 100644
index 0000000..cf58190
--- /dev/null
+++ b/libelf/Makefile.am
@@ -0,0 +1,120 @@
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 1996-2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, version 2.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software Foundation,
+## Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H
+if MUDFLAP
+AM_CFLAGS = -fpic -fmudflap
+else
+AM_CFLAGS =
+endif
+AM_CFLAGS += -Wall -Wshadow -Werror -Wunused -Wextra -Wformat=2 -std=gnu99 \
+	     $($(*F)_CFLAGS)
+INCLUDES = -I$(srcdir) -I$(top_srcdir)/lib -I..
+GCC_INCLUDE = -I$(shell $(CC) -print-file-name=include)
+VERSION = 1
+PACKAGE_VERSION = @PACKAGE_VERSION@
+
+lib_LIBRARIES = libelf.a
+if !MUDFLAP
+noinst_LIBRARIES = libelf_pic.a
+noinst_PROGRAMS = $(noinst_LIBRARIES:_pic.a=.so)
+endif
+include_HEADERS = libelf.h gelf.h nlist.h
+
+euincludedir = $(includedir)/elfutils
+euinclude_HEADERS = elf-knowledge.h
+
+libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \
+		   elf_begin.c elf_next.c elf_rand.c elf_end.c elf_kind.c \
+		   gelf_getclass.c elf_getbase.c elf_getident.c \
+		   elf32_fsize.c elf64_fsize.c gelf_fsize.c \
+		   elf32_xlatetof.c elf32_xlatetom.c elf64_xlatetof.c \
+		   elf64_xlatetom.c gelf_xlate.c \
+		   elf32_getehdr.c elf64_getehdr.c gelf_getehdr.c \
+		   elf32_newehdr.c elf64_newehdr.c gelf_newehdr.c \
+		   gelf_update_ehdr.c \
+		   elf32_getphdr.c elf64_getphdr.c gelf_getphdr.c \
+		   elf32_newphdr.c elf64_newphdr.c gelf_newphdr.c \
+		   gelf_update_phdr.c \
+		   elf_getarhdr.c elf_getarsym.c \
+		   elf_rawfile.c elf_readall.c elf_cntl.c \
+		   elf_getscn.c elf_nextscn.c elf_ndxscn.c elf_newscn.c \
+		   elf32_getshdr.c elf64_getshdr.c gelf_getshdr.c \
+		   gelf_update_shdr.c \
+		   elf_strptr.c elf_rawdata.c elf_getdata.c elf_newdata.c \
+		   elf_flagelf.c elf_flagehdr.c elf_flagphdr.c elf_flagscn.c \
+		   elf_flagshdr.c elf_flagdata.c elf_memory.c \
+		   elf_update.c elf32_updatenull.c elf64_updatenull.c \
+		   elf32_updatefile.c elf64_updatefile.c \
+		   gelf_getsym.c gelf_update_sym.c \
+		   gelf_getversym.c gelf_getverneed.c gelf_getvernaux.c \
+		   gelf_getverdef.c gelf_getverdaux.c \
+		   gelf_getrel.c gelf_getrela.c \
+		   gelf_update_rel.c gelf_update_rela.c \
+		   gelf_getdyn.c gelf_update_dyn.c \
+		   gelf_getmove.c gelf_update_move.c \
+		   gelf_getsyminfo.c gelf_update_syminfo.c \
+		   gelf_xlatetof.c gelf_xlatetom.c \
+		   nlist.c \
+		   gelf_getsymshndx.c gelf_update_symshndx.c \
+		   gelf_update_versym.c gelf_update_verneed.c \
+		   gelf_update_vernaux.c gelf_update_verdef.c \
+		   gelf_update_verdaux.c \
+		   elf_getshnum.c elf_getshstrndx.c \
+		   gelf_checksum.c elf32_checksum.c elf64_checksum.c \
+		   gelf_rawchunk.c gelf_freechunk.c \
+		   libelf_crc32.c libelf_next_prime.c \
+		   elf_clone.c \
+		   gelf_getlib.c gelf_update_lib.c
+
+if !MUDFLAP
+libelf_pic_a_SOURCES =
+am_libelf_pic_a_OBJECTS = $(libelf_a_SOURCES:.c=.os)
+
+libelf_so_SOURCES =
+libelf.so: libelf_pic.a libelf.map
+	$(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
+	      -Wl,--version-script,$(srcdir)/libelf.map,--no-undefined \
+	      -Wl,--soname,$@.$(VERSION),-z,-defs
+	if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi
+	ln -fs $@ $@.$(VERSION)
+
+%.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 libelf.so
+	$(mkinstalldirs) $(DESTDIR)$(libdir)
+	$(INSTALL_PROGRAM) libelf.so $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so
+	ln -fs libelf-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libelf.so.$(VERSION)
+	ln -fs libelf.so.$(VERSION) $(DESTDIR)$(libdir)/libelf.so
+
+uninstall: uninstall-am
+	rm -f $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so
+	rm -f $(DESTDIR)$(libdir)/libelf.so.$(VERSION)
+	rm -f $(DESTDIR)$(libdir)/libelf.so
+endif
+
+noinst_HEADERS = elf.h abstract.h common.h exttypes.h gelf_xlate.h libelfP.h \
+		 version_xlate.h dl-hash.h
+EXTRA_DIST = libelf.map
+
+CLEANFILES = $(am_libelf_pic_a_OBJECTS)
diff --git a/libelf/abstract.h b/libelf/abstract.h
new file mode 100644
index 0000000..d14034e
--- /dev/null
+++ b/libelf/abstract.h
@@ -0,0 +1,283 @@
+/* Abstract description of component ELF types.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* ELF header.  */
+#define Ehdr(Bits, Ext) \
+START (Bits, Ehdr, Ext##Ehdr)						      \
+  TYPE_EXTRA (unsigned char e_ident[EI_NIDENT];)			      \
+  TYPE_XLATE (memmove (tdest->e_ident, tsrc->e_ident, EI_NIDENT);)	      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_type)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_machine)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), e_version)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Addr), e_entry)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Off), e_phoff)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Off), e_shoff)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), e_flags)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_ehsize)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_phentsize)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_phnum)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_shentsize)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_shnum)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_shstrndx)			      \
+END (Bits, Ext##Ehdr)
+
+#define Ehdr32(Ext) \
+  Ehdr(32, Ext)
+#define Ehdr64(Ext) \
+  Ehdr(64, Ext)
+
+
+/* Program header.  */
+#define Phdr32(Ext) \
+START (32, Phdr, Ext##Phdr)						      \
+  TYPE_NAME (ElfW2(32, Ext##Word), p_type)				      \
+  TYPE_NAME (ElfW2(32, Ext##Off), p_offset)				      \
+  TYPE_NAME (ElfW2(32, Ext##Addr), p_vaddr)				      \
+  TYPE_NAME (ElfW2(32, Ext##Addr), p_paddr)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), p_filesz)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), p_memsz)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), p_flags)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), p_align)				      \
+END (32, Ext##Phdr)
+#define Phdr64(Ext) \
+START (64, Phdr, Ext##Phdr)						      \
+  TYPE_NAME (ElfW2(64, Ext##Word), p_type)				      \
+  TYPE_NAME (ElfW2(64, Ext##Word), p_flags)				      \
+  TYPE_NAME (ElfW2(64, Ext##Off), p_offset)				      \
+  TYPE_NAME (ElfW2(64, Ext##Addr), p_vaddr)				      \
+  TYPE_NAME (ElfW2(64, Ext##Addr), p_paddr)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), p_filesz)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), p_memsz)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), p_align)				      \
+END (64, Ext##Phdr)
+
+
+/* Section header.  */
+#define Shdr32(Ext) \
+START (32, Shdr, Ext##Shdr)						      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_name)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_type)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_flags)				      \
+  TYPE_NAME (ElfW2(32, Ext##Addr), sh_addr)				      \
+  TYPE_NAME (ElfW2(32, Ext##Off), sh_offset)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_size)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_link)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_info)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_addralign)			      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_entsize)				      \
+END (32, Ext##Shdr)
+#define Shdr64(Ext) \
+START (64, Shdr, Ext##Shdr)						      \
+  TYPE_NAME (ElfW2(64, Ext##Word), sh_name)				      \
+  TYPE_NAME (ElfW2(64, Ext##Word), sh_type)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), sh_flags)				      \
+  TYPE_NAME (ElfW2(64, Ext##Addr), sh_addr)				      \
+  TYPE_NAME (ElfW2(64, Ext##Off), sh_offset)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), sh_size)				      \
+  TYPE_NAME (ElfW2(64, Ext##Word), sh_link)				      \
+  TYPE_NAME (ElfW2(64, Ext##Word), sh_info)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), sh_addralign)			      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), sh_entsize)				      \
+END (64, Ext##Shdr)
+
+
+/* Symbol table.  */
+#define Sym32(Ext) \
+START (32, Sym, Ext##Sym)						      \
+  TYPE_NAME (ElfW2(32, Ext##Word), st_name)				      \
+  TYPE_NAME (ElfW2(32, Ext##Addr), st_value)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), st_size)				      \
+  TYPE_EXTRA (unsigned char st_info;)					      \
+  TYPE_XLATE (tdest->st_info = tsrc->st_info;)				      \
+  TYPE_EXTRA (unsigned char st_other;)					      \
+  TYPE_XLATE (tdest->st_other = tsrc->st_other;)			      \
+  TYPE_NAME (ElfW2(32, Ext##Half), st_shndx)				      \
+END (32, Ext##Sym)
+#define Sym64(Ext) \
+START (64, Sym, Ext##Sym)						      \
+  TYPE_NAME (ElfW2(64, Ext##Word), st_name)				      \
+  TYPE_EXTRA (unsigned char st_info;)					      \
+  TYPE_XLATE (tdest->st_info = tsrc->st_info;)				      \
+  TYPE_EXTRA (unsigned char st_other;)					      \
+  TYPE_XLATE (tdest->st_other = tsrc->st_other;)			      \
+  TYPE_NAME (ElfW2(64, Ext##Half), st_shndx)				      \
+  TYPE_NAME (ElfW2(64, Ext##Addr), st_value)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), st_size)				      \
+END (64, Ext##Sym)
+
+
+/* Relocation.  */
+#define Rel32(Ext) \
+START (32, Rel, Ext##Rel)						      \
+  TYPE_NAME (ElfW2(32, Ext##Addr), r_offset)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), r_info)				      \
+END (32, Ext##Rel)
+#define Rel64(Ext) \
+START (64, Rel, Ext##Rel)						      \
+  TYPE_NAME (ElfW2(64, Ext##Addr), r_offset)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), r_info)				      \
+END (64, Ext##Rel)
+
+#define Rela32(Ext) \
+START (32, Rela, Ext##Rela)						      \
+  TYPE_NAME (ElfW2(32, Ext##Addr), r_offset)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), r_info)				      \
+  TYPE_NAME (ElfW2(32, Ext##Sword), r_addend)				      \
+END (32, Ext##Rela)
+#define Rela64(Ext) \
+START (64, Rela, Ext##Rela)						      \
+  TYPE_NAME (ElfW2(64, Ext##Addr), r_offset)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), r_info)				      \
+  TYPE_NAME (ElfW2(64, Ext##Sxword), r_addend)				      \
+END (64, Ext##Rela)
+
+
+/* Note entry header.  */
+#define Note(Bits, Ext) \
+START (Bits, Nhdr, Ext##Nhdr)						      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), n_namesz)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), n_descsz)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), n_type)				      \
+END (Bits, Ext##Nhdr)
+
+#define Note32(Ext) \
+  Note (32, Ext)
+#define Note64(Ext) \
+  Note (64, Ext)
+
+
+/* Dynamic section data.  */
+#define Dyn32(Ext) \
+START (32, Dyn, Ext##Dyn)						      \
+  TYPE_NAME (ElfW2(32, Ext##Sword), d_tag)				      \
+  TYPE_EXTRA (union {)							      \
+  TYPE_EXTRA (ElfW2(32, Ext##Word) d_val;)				      \
+  TYPE_EXTRA (ElfW2(32, Ext##Addr) d_ptr;)				      \
+  TYPE_XLATE (Elf32_cvt_Addr1 (&tdest->d_un.d_val, &tsrc->d_un.d_val);)	      \
+  TYPE_EXTRA (ElfW2(32, Ext##Off) d_off;)				      \
+  TYPE_EXTRA (} d_un;)							      \
+END (32, Ext##Dyn)
+#define Dyn64(Ext) \
+START (64, Dyn, Ext##Dyn)						      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), d_tag)				      \
+  TYPE_EXTRA (union {)							      \
+  TYPE_EXTRA (ElfW2(64, Ext##Xword) d_val;)				      \
+  TYPE_EXTRA (ElfW2(64, Ext##Addr) d_ptr;)				      \
+  TYPE_XLATE (Elf64_cvt_Addr1 (&tdest->d_un.d_val, &tsrc->d_un.d_val);)	      \
+  TYPE_EXTRA (} d_un;)							      \
+END (64, Ext##Dyn)
+
+
+#ifndef GENERATE_CONVERSION
+/* Version definitions.  */
+# define Verdef(Bits, Ext) \
+START (Bits, Verdef, Ext##Verdef)					      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vd_version)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vd_flags)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vd_ndx)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vd_cnt)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vd_hash)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vd_aux)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vd_next)				      \
+END (Bits, Ext##Verdef)
+
+# define Verdef32(Ext) \
+  Verdef (32, Ext)
+# define Verdef64(Ext) \
+  Verdef (64, Ext)
+
+# define Verdaux(Bits, Ext) \
+START (Bits, Verdaux, Ext##Verdaux)					      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vda_name)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vda_next)				      \
+END (Bits, Ext##Verdaux)
+
+# define Verdaux32(Ext) \
+  Verdaux (32, Ext)
+# define Verdaux64(Ext) \
+  Verdaux (64, Ext)
+
+/* Required versions.  */
+# define Verneed(Bits, Ext) \
+START (Bits, Verneed, Ext##Verneed)					      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vn_version)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vn_cnt)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vn_file)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vn_aux)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vn_next)				      \
+END (Bits, Ext##Verneed)
+
+# define Verneed32(Ext) \
+  Verneed (32, Ext)
+# define Verneed64(Ext) \
+  Verneed (64, Ext)
+
+# define Vernaux(Bits, Ext) \
+START (Bits, Vernaux, Ext##Vernaux)					      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vna_hash)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vna_flags)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vna_other)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vna_name)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vna_next)				      \
+END (Bits, Ext##Vernaux)
+
+# define Vernaux32(Ext) \
+  Vernaux (32, Ext)
+# define Vernaux64(Ext) \
+  Vernaux (64, Ext)
+#endif
+
+/* Symbol information.  */
+#define Syminfo(Bits, Ext) \
+START (Bits, Syminfo, Ext##Syminfo)					      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), si_boundto)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), si_flags)				      \
+END (Bits, Ext##Syminfo)
+
+#define Syminfo32(Ext) \
+  Syminfo (32, Ext)
+#define Syminfo64(Ext) \
+  Syminfo (64, Ext)
+
+/* Move information.  */
+#define Move(Bits, Ext) \
+START (Bits, Move, Ext##Move)						      \
+  TYPE_NAME (ElfW2(Bits, Ext##Xword), m_value)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Xword), m_info)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Xword), m_poffset)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), m_repeat)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), m_stride)				      \
+END (Bits, Ext##Move)
+
+#define Move32(Ext) \
+  Move (32, Ext)
+#define Move64(Ext) \
+  Move (64, Ext)
+
+#define Lib(Bits, Ext) \
+START (Bits, Lib, Ext##Lib)						      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), l_name)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), l_time_stamp)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), l_checksum)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), l_version)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), l_flags)				      \
+END (Bits, Ext##Lib)
+
+#define Lib32(Ext) \
+  Lib (32, Ext)
+#define Lib64(Ext) \
+  Lib (64, Ext)
diff --git a/libelf/common.h b/libelf/common.h
new file mode 100644
index 0000000..ac1c61d
--- /dev/null
+++ b/libelf/common.h
@@ -0,0 +1,146 @@
+/* Common definitions for handling files in memory or only on disk.
+   Copyright (C) 1998, 1999, 2000, 2002, 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _COMMON_H
+#define _COMMON_H       1
+
+#include <ar.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+static inline Elf_Kind
+determine_kind (void *buf, size_t len)
+{
+  /* First test for an archive.  */
+  if (len >= SARMAG && memcmp (buf, ARMAG, SARMAG) == 0)
+    return ELF_K_AR;
+
+  /* Next try ELF files.  */
+  if (len >= EI_NIDENT && memcmp (buf, ELFMAG, SELFMAG) == 0)
+    {
+      /* Could be an ELF file.  */
+      int eclass = (int) ((unsigned char *) buf)[EI_CLASS];
+      int data = (int) ((unsigned char *) buf)[EI_DATA];
+      int version = (int) ((unsigned char *) buf)[EI_VERSION];
+
+      if (eclass > ELFCLASSNONE && eclass < ELFCLASSNUM
+	  && data > ELFDATANONE && data < ELFDATANUM
+	  && version > EV_NONE && version < EV_NUM)
+	return ELF_K_ELF;
+    }
+
+  /* We do not know this file type.  */
+  return ELF_K_NONE;
+}
+
+
+/* Allocate an Elf descriptor and fill in the generic information.  */
+static inline Elf *
+allocate_elf (int fildes, void *map_address, off_t offset, size_t maxsize,
+              Elf_Cmd cmd, Elf *parent, Elf_Kind kind, size_t extra)
+{
+  Elf *result = (Elf *) calloc (1, sizeof (Elf) + extra);
+  if (result == NULL)
+    __libelf_seterrno (ELF_E_NOMEM);
+  else
+    {
+      result->kind = kind;
+      result->ref_count = 1;
+      result->cmd = cmd;
+      result->fildes = fildes;
+      result->start_offset = offset;
+      result->maximum_size = maxsize;
+      result->map_address = map_address;
+      result->parent = parent;
+
+      rwlock_init (result->lock);
+    }
+
+  return result;
+}
+
+
+/* Acquire lock for the descriptor and all children.  */
+static void
+libelf_acquire_all (Elf *elf)
+{
+  rwlock_wrlock (elf->lock);
+
+  if (elf->kind == ELF_K_AR)
+    {
+      Elf *child = elf->state.ar.children;
+
+      while (child != NULL)
+	{
+	  if (child->ref_count != 0)
+	    libelf_acquire_all (child);
+	  child = child->next;
+	}
+    }
+}
+
+/* Release own lock and those of the children.  */
+static void
+libelf_release_all (Elf *elf)
+{
+  if (elf->kind == ELF_K_AR)
+    {
+      Elf *child = elf->state.ar.children;
+
+      while (child != NULL)
+	{
+	  if (child->ref_count != 0)
+	    libelf_release_all (child);
+	  child = child->next;
+	}
+    }
+
+  rwlock_unlock (elf->lock);
+}
+
+
+/* Macro to convert endianess in place.  It determines the function it
+   has to use itself.  */
+#define CONVERT(Var) \
+  (Var) = (sizeof (Var) == 1						      \
+	   ? (unsigned char) (Var)					      \
+	   : (sizeof (Var) == 2						      \
+	      ? bswap_16 (Var)						      \
+	      : (sizeof (Var) == 4					      \
+		 ? bswap_32 (Var)					      \
+		 : bswap_64 (Var))))
+
+#define CONVERT_TO(Dst, Var) \
+  (Dst) = (sizeof (Var) == 1						      \
+	   ? (unsigned char) (Var)					      \
+	   : (sizeof (Var) == 2						      \
+	      ? bswap_16 (Var)						      \
+	      : (sizeof (Var) == 4					      \
+		 ? bswap_32 (Var)					      \
+		 : bswap_64 (Var))))
+
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define MY_ELFDATA	ELFDATA2LSB
+#else
+# define MY_ELFDATA	ELFDATA2MSB
+#endif
+
+#endif	/* common.h */
diff --git a/libelf/dl-hash.h b/libelf/dl-hash.h
new file mode 100644
index 0000000..c8e8962
--- /dev/null
+++ b/libelf/dl-hash.h
@@ -0,0 +1,70 @@
+/* Compute hash value for given string according to ELF standard.
+   Copyright (C) 1995-1998, 2002, 2004 Free Software Foundation, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1995.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _DL_HASH_H
+#define _DL_HASH_H	1
+
+
+/* This is the hashing function specified by the ELF ABI.  In the
+   first five operations no overflow is possible so we optimized it a
+   bit.  */
+static inline unsigned int
+__attribute__ ((__pure__))
+_dl_elf_hash (const char *name)
+{
+  const unsigned char *iname = (const unsigned char *) name;
+  unsigned int hash = (unsigned int) *iname++;
+  if (*iname != '\0')
+    {
+      hash = (hash << 4) + (unsigned int) *iname++;
+      if (*iname != '\0')
+	{
+	  hash = (hash << 4) + (unsigned int) *iname++;
+	  if (*iname != '\0')
+	    {
+	      hash = (hash << 4) + (unsigned int) *iname++;
+	      if (*iname != '\0')
+		{
+		  hash = (hash << 4) + (unsigned int) *iname++;
+		  while (*iname != '\0')
+		    {
+		      unsigned int hi;
+		      hash = (hash << 4) + (unsigned int) *iname++;
+		      hi = hash & 0xf0000000;
+
+		      /* The algorithm specified in the ELF ABI is as
+			 follows:
+
+			 if (hi != 0)
+			 hash ^= hi >> 24;
+
+			 hash &= ~hi;
+
+			 But the following is equivalent and a lot
+			 faster, especially on modern processors.  */
+
+		      hash ^= hi;
+		      hash ^= hi >> 24;
+		    }
+		}
+	    }
+	}
+    }
+  return hash;
+}
+
+#endif /* dl-hash.h */
diff --git a/libelf/elf-knowledge.h b/libelf/elf-knowledge.h
new file mode 100644
index 0000000..b92fd8a
--- /dev/null
+++ b/libelf/elf-knowledge.h
@@ -0,0 +1,94 @@
+/* Accumulation of various pieces of knowledge about ELF.
+   Copyright (C) 2000, 2001, 2002, 2003, 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _ELF_KNOWLEDGE_H
+#define _ELF_KNOWLEDGE_H	1
+
+#include <stdbool.h>
+
+
+/* Test whether a section can be stripped or not.  */
+#define SECTION_STRIP_P(shdr, name, remove_comment) \
+  /* Sections which are allocated are not removed.  */			      \
+  (((shdr)->sh_flags & SHF_ALLOC) == 0					      \
+   /* We never remove .note sections.  */				      \
+   && (shdr)->sh_type != SHT_NOTE					      \
+   && (((shdr)->sh_type) != SHT_PROGBITS				      \
+       /* Never remove .gnu.warning.* sections.  */			      \
+       || (strncmp (name, ".gnu.warning.", sizeof ".gnu.warning." - 1) != 0   \
+	   /* We remove .comment sections only if explicitly told to do so. */\
+	   && (remove_comment						      \
+	       || strcmp (name, ".comment") != 0)))			      \
+   /* So far we do not remove any of the non-standard sections.		      \
+      XXX Maybe in future.  */						      \
+   && (shdr)->sh_type < SHT_NUM)
+
+
+/* Test whether `sh_info' field in section header contains a section
+   index.  There are two kinds of sections doing this:
+
+   - the sections containing relocation information reference in this
+     field the section to which the relocations apply;
+
+   - section with the SHF_INFO_LINK flag set to signal that `sh_info'
+     references a section.  This allows correct handling of unknown
+     sections.  */
+#define SH_INFO_LINK_P(Shdr) \
+  ((Shdr)->sh_type == SHT_REL || (Shdr)->sh_type == SHT_RELA		      \
+   || ((Shdr)->sh_flags & SHF_INFO_LINK) != 0)
+
+
+/* When combining ELF section flags we must distinguish two kinds:
+
+   - flags which cause problem if not added to the result even if not
+     present in all input sections
+
+   - flags which cause problem if added to the result if not present
+     in all input sections
+
+   The following definition is for the general case.  There might be
+   machine specific extensions.  */
+#define SH_FLAGS_COMBINE(Flags1, Flags2) \
+  (((Flags1 | Flags2)							      \
+    & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_LINK_ORDER		      \
+       | SHF_OS_NONCONFORMING | SHF_GROUP))				      \
+   | (Flags1 & Flags2 & (SHF_MERGE | SHF_STRINGS | SHF_INFO_LINK)))
+
+/* Similar macro: return the bits of the flags which necessarily must
+   match if two sections are automatically combined.  Sections still
+   can be forcefully combined in which case SH_FLAGS_COMBINE can be
+   used to determine the combined flags.  */
+#define SH_FLAGS_IMPORTANT(Flags) \
+  ((Flags) & ~((GElf_Xword) 0 | SHF_LINK_ORDER | SHF_OS_NONCONFORMING))
+
+
+/* Size of an entry in the hash table.  The ELF specification says all
+   entries are regardless of platform 32-bits in size.  Early 64-bit
+   ports (namely Alpha for Linux) got this wrong.  The wording was not
+   clear.
+
+   Several years later the ABI for the 64-bit S390s was developed.
+   Many things were copied from the IA-64 ABI (which uses the correct
+   32-bit entry size) but what do these people do?  They use 64-bit
+   entries.  It is really shocking to see what kind of morons are out
+   there.  And even worse: they are allowed to design ABIs.  */
+#define SH_ENTSIZE_HASH(Ehdr) \
+  ((Ehdr)->e_machine == EM_ALPHA					      \
+   || ((Ehdr)->e_machine == EM_S390					      \
+       && (Ehdr)->e_ident[EI_CLASS] == ELFCLASS64) ? 8 : 4)
+
+#endif	/* elf-knowledge.h */
diff --git a/libelf/elf.h b/libelf/elf.h
new file mode 100644
index 0000000..e246519
--- /dev/null
+++ b/libelf/elf.h
@@ -0,0 +1,2577 @@
+/* This file defines standard ELF types, structures, and macros.
+   Copyright (C) 1995-2003, 2004, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _ELF_H
+#define	_ELF_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Standard ELF types.  */
+
+#include <stdint.h>
+
+/* Type for a 16-bit quantity.  */
+typedef uint16_t Elf32_Half;
+typedef uint16_t Elf64_Half;
+
+/* Types for signed and unsigned 32-bit quantities.  */
+typedef uint32_t Elf32_Word;
+typedef	int32_t  Elf32_Sword;
+typedef uint32_t Elf64_Word;
+typedef	int32_t  Elf64_Sword;
+
+/* Types for signed and unsigned 64-bit quantities.  */
+typedef uint64_t Elf32_Xword;
+typedef	int64_t  Elf32_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef	int64_t  Elf64_Sxword;
+
+/* Type of addresses.  */
+typedef uint32_t Elf32_Addr;
+typedef uint64_t Elf64_Addr;
+
+/* Type of file offsets.  */
+typedef uint32_t Elf32_Off;
+typedef uint64_t Elf64_Off;
+
+/* Type for section indices, which are 16-bit quantities.  */
+typedef uint16_t Elf32_Section;
+typedef uint16_t Elf64_Section;
+
+/* Type for version symbol information.  */
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+
+/* The ELF file header.  This appears at the start of every ELF file.  */
+
+#define EI_NIDENT (16)
+
+typedef struct
+{
+  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+  Elf32_Half	e_type;			/* Object file type */
+  Elf32_Half	e_machine;		/* Architecture */
+  Elf32_Word	e_version;		/* Object file version */
+  Elf32_Addr	e_entry;		/* Entry point virtual address */
+  Elf32_Off	e_phoff;		/* Program header table file offset */
+  Elf32_Off	e_shoff;		/* Section header table file offset */
+  Elf32_Word	e_flags;		/* Processor-specific flags */
+  Elf32_Half	e_ehsize;		/* ELF header size in bytes */
+  Elf32_Half	e_phentsize;		/* Program header table entry size */
+  Elf32_Half	e_phnum;		/* Program header table entry count */
+  Elf32_Half	e_shentsize;		/* Section header table entry size */
+  Elf32_Half	e_shnum;		/* Section header table entry count */
+  Elf32_Half	e_shstrndx;		/* Section header string table index */
+} Elf32_Ehdr;
+
+typedef struct
+{
+  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+  Elf64_Half	e_type;			/* Object file type */
+  Elf64_Half	e_machine;		/* Architecture */
+  Elf64_Word	e_version;		/* Object file version */
+  Elf64_Addr	e_entry;		/* Entry point virtual address */
+  Elf64_Off	e_phoff;		/* Program header table file offset */
+  Elf64_Off	e_shoff;		/* Section header table file offset */
+  Elf64_Word	e_flags;		/* Processor-specific flags */
+  Elf64_Half	e_ehsize;		/* ELF header size in bytes */
+  Elf64_Half	e_phentsize;		/* Program header table entry size */
+  Elf64_Half	e_phnum;		/* Program header table entry count */
+  Elf64_Half	e_shentsize;		/* Section header table entry size */
+  Elf64_Half	e_shnum;		/* Section header table entry count */
+  Elf64_Half	e_shstrndx;		/* Section header string table index */
+} Elf64_Ehdr;
+
+/* Fields in the e_ident array.  The EI_* macros are indices into the
+   array.  The macros under each EI_* macro are the values the byte
+   may have.  */
+
+#define EI_MAG0		0		/* File identification byte 0 index */
+#define ELFMAG0		0x7f		/* Magic number byte 0 */
+
+#define EI_MAG1		1		/* File identification byte 1 index */
+#define ELFMAG1		'E'		/* Magic number byte 1 */
+
+#define EI_MAG2		2		/* File identification byte 2 index */
+#define ELFMAG2		'L'		/* Magic number byte 2 */
+
+#define EI_MAG3		3		/* File identification byte 3 index */
+#define ELFMAG3		'F'		/* Magic number byte 3 */
+
+/* Conglomeration of the identification bytes, for easy testing as a word.  */
+#define	ELFMAG		"\177ELF"
+#define	SELFMAG		4
+
+#define EI_CLASS	4		/* File class byte index */
+#define ELFCLASSNONE	0		/* Invalid class */
+#define ELFCLASS32	1		/* 32-bit objects */
+#define ELFCLASS64	2		/* 64-bit objects */
+#define ELFCLASSNUM	3
+
+#define EI_DATA		5		/* Data encoding byte index */
+#define ELFDATANONE	0		/* Invalid data encoding */
+#define ELFDATA2LSB	1		/* 2's complement, little endian */
+#define ELFDATA2MSB	2		/* 2's complement, big endian */
+#define ELFDATANUM	3
+
+#define EI_VERSION	6		/* File version byte index */
+					/* Value must be EV_CURRENT */
+
+#define EI_OSABI	7		/* OS ABI identification */
+#define ELFOSABI_NONE		0	/* UNIX System V ABI */
+#define ELFOSABI_SYSV		0	/* Alias.  */
+#define ELFOSABI_HPUX		1	/* HP-UX */
+#define ELFOSABI_NETBSD		2	/* NetBSD.  */
+#define ELFOSABI_LINUX		3	/* Linux.  */
+#define ELFOSABI_SOLARIS	6	/* Sun Solaris.  */
+#define ELFOSABI_AIX		7	/* IBM AIX.  */
+#define ELFOSABI_IRIX		8	/* SGI Irix.  */
+#define ELFOSABI_FREEBSD	9	/* FreeBSD.  */
+#define ELFOSABI_TRU64		10	/* Compaq TRU64 UNIX.  */
+#define ELFOSABI_MODESTO	11	/* Novell Modesto.  */
+#define ELFOSABI_OPENBSD	12	/* OpenBSD.  */
+#define ELFOSABI_ARM		97	/* ARM */
+#define ELFOSABI_STANDALONE	255	/* Standalone (embedded) application */
+
+#define EI_ABIVERSION	8		/* ABI version */
+
+#define EI_PAD		9		/* Byte index of padding bytes */
+
+/* Legal values for e_type (object file type).  */
+
+#define ET_NONE		0		/* No file type */
+#define ET_REL		1		/* Relocatable file */
+#define ET_EXEC		2		/* Executable file */
+#define ET_DYN		3		/* Shared object file */
+#define ET_CORE		4		/* Core file */
+#define	ET_NUM		5		/* Number of defined types */
+#define ET_LOOS		0xfe00		/* OS-specific range start */
+#define ET_HIOS		0xfeff		/* OS-specific range end */
+#define ET_LOPROC	0xff00		/* Processor-specific range start */
+#define ET_HIPROC	0xffff		/* Processor-specific range end */
+
+/* Legal values for e_machine (architecture).  */
+
+#define EM_NONE		 0		/* No machine */
+#define EM_M32		 1		/* AT&T WE 32100 */
+#define EM_SPARC	 2		/* SUN SPARC */
+#define EM_386		 3		/* Intel 80386 */
+#define EM_68K		 4		/* Motorola m68k family */
+#define EM_88K		 5		/* Motorola m88k family */
+#define EM_860		 7		/* Intel 80860 */
+#define EM_MIPS		 8		/* MIPS R3000 big-endian */
+#define EM_S370		 9		/* IBM System/370 */
+#define EM_MIPS_RS3_LE	10		/* MIPS R3000 little-endian */
+
+#define EM_PARISC	15		/* HPPA */
+#define EM_VPP500	17		/* Fujitsu VPP500 */
+#define EM_SPARC32PLUS	18		/* Sun's "v8plus" */
+#define EM_960		19		/* Intel 80960 */
+#define EM_PPC		20		/* PowerPC */
+#define EM_PPC64	21		/* PowerPC 64-bit */
+#define EM_S390		22		/* IBM S390 */
+
+#define EM_V800		36		/* NEC V800 series */
+#define EM_FR20		37		/* Fujitsu FR20 */
+#define EM_RH32		38		/* TRW RH-32 */
+#define EM_RCE		39		/* Motorola RCE */
+#define EM_ARM		40		/* ARM */
+#define EM_FAKE_ALPHA	41		/* Digital Alpha */
+#define EM_SH		42		/* Hitachi SH */
+#define EM_SPARCV9	43		/* SPARC v9 64-bit */
+#define EM_TRICORE	44		/* Siemens Tricore */
+#define EM_ARC		45		/* Argonaut RISC Core */
+#define EM_H8_300	46		/* Hitachi H8/300 */
+#define EM_H8_300H	47		/* Hitachi H8/300H */
+#define EM_H8S		48		/* Hitachi H8S */
+#define EM_H8_500	49		/* Hitachi H8/500 */
+#define EM_IA_64	50		/* Intel Merced */
+#define EM_MIPS_X	51		/* Stanford MIPS-X */
+#define EM_COLDFIRE	52		/* Motorola Coldfire */
+#define EM_68HC12	53		/* Motorola M68HC12 */
+#define EM_MMA		54		/* Fujitsu MMA Multimedia Accelerator*/
+#define EM_PCP		55		/* Siemens PCP */
+#define EM_NCPU		56		/* Sony nCPU embeeded RISC */
+#define EM_NDR1		57		/* Denso NDR1 microprocessor */
+#define EM_STARCORE	58		/* Motorola Start*Core processor */
+#define EM_ME16		59		/* Toyota ME16 processor */
+#define EM_ST100	60		/* STMicroelectronic ST100 processor */
+#define EM_TINYJ	61		/* Advanced Logic Corp. Tinyj emb.fam*/
+#define EM_X86_64	62		/* AMD x86-64 architecture */
+#define EM_PDSP		63		/* Sony DSP Processor */
+
+#define EM_FX66		66		/* Siemens FX66 microcontroller */
+#define EM_ST9PLUS	67		/* STMicroelectronics ST9+ 8/16 mc */
+#define EM_ST7		68		/* STmicroelectronics ST7 8 bit mc */
+#define EM_68HC16	69		/* Motorola MC68HC16 microcontroller */
+#define EM_68HC11	70		/* Motorola MC68HC11 microcontroller */
+#define EM_68HC08	71		/* Motorola MC68HC08 microcontroller */
+#define EM_68HC05	72		/* Motorola MC68HC05 microcontroller */
+#define EM_SVX		73		/* Silicon Graphics SVx */
+#define EM_ST19		74		/* STMicroelectronics ST19 8 bit mc */
+#define EM_VAX		75		/* Digital VAX */
+#define EM_CRIS		76		/* Axis Communications 32-bit embedded processor */
+#define EM_JAVELIN	77		/* Infineon Technologies 32-bit embedded processor */
+#define EM_FIREPATH	78		/* Element 14 64-bit DSP Processor */
+#define EM_ZSP		79		/* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX		80		/* Donald Knuth's educational 64-bit processor */
+#define EM_HUANY	81		/* Harvard University machine-independent object files */
+#define EM_PRISM	82		/* SiTera Prism */
+#define EM_AVR		83		/* Atmel AVR 8-bit microcontroller */
+#define EM_FR30		84		/* Fujitsu FR30 */
+#define EM_D10V		85		/* Mitsubishi D10V */
+#define EM_D30V		86		/* Mitsubishi D30V */
+#define EM_V850		87		/* NEC v850 */
+#define EM_M32R		88		/* Mitsubishi M32R */
+#define EM_MN10300	89		/* Matsushita MN10300 */
+#define EM_MN10200	90		/* Matsushita MN10200 */
+#define EM_PJ		91		/* picoJava */
+#define EM_OPENRISC	92		/* OpenRISC 32-bit embedded processor */
+#define EM_ARC_A5	93		/* ARC Cores Tangent-A5 */
+#define EM_XTENSA	94		/* Tensilica Xtensa Architecture */
+#define EM_NUM		95
+
+/* If it is necessary to assign new unofficial EM_* values, please
+   pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
+   chances of collision with official or non-GNU unofficial values.  */
+
+#define EM_ALPHA	0x9026
+
+/* Legal values for e_version (version).  */
+
+#define EV_NONE		0		/* Invalid ELF version */
+#define EV_CURRENT	1		/* Current version */
+#define EV_NUM		2
+
+/* Section header.  */
+
+typedef struct
+{
+  Elf32_Word	sh_name;		/* Section name (string tbl index) */
+  Elf32_Word	sh_type;		/* Section type */
+  Elf32_Word	sh_flags;		/* Section flags */
+  Elf32_Addr	sh_addr;		/* Section virtual addr at execution */
+  Elf32_Off	sh_offset;		/* Section file offset */
+  Elf32_Word	sh_size;		/* Section size in bytes */
+  Elf32_Word	sh_link;		/* Link to another section */
+  Elf32_Word	sh_info;		/* Additional section information */
+  Elf32_Word	sh_addralign;		/* Section alignment */
+  Elf32_Word	sh_entsize;		/* Entry size if section holds table */
+} Elf32_Shdr;
+
+typedef struct
+{
+  Elf64_Word	sh_name;		/* Section name (string tbl index) */
+  Elf64_Word	sh_type;		/* Section type */
+  Elf64_Xword	sh_flags;		/* Section flags */
+  Elf64_Addr	sh_addr;		/* Section virtual addr at execution */
+  Elf64_Off	sh_offset;		/* Section file offset */
+  Elf64_Xword	sh_size;		/* Section size in bytes */
+  Elf64_Word	sh_link;		/* Link to another section */
+  Elf64_Word	sh_info;		/* Additional section information */
+  Elf64_Xword	sh_addralign;		/* Section alignment */
+  Elf64_Xword	sh_entsize;		/* Entry size if section holds table */
+} Elf64_Shdr;
+
+/* Special section indices.  */
+
+#define SHN_UNDEF	0		/* Undefined section */
+#define SHN_LORESERVE	0xff00		/* Start of reserved indices */
+#define SHN_LOPROC	0xff00		/* Start of processor-specific */
+#define SHN_BEFORE	0xff00		/* Order section before all others
+					   (Solaris).  */
+#define SHN_AFTER	0xff01		/* Order section after all others
+					   (Solaris).  */
+#define SHN_HIPROC	0xff1f		/* End of processor-specific */
+#define SHN_LOOS	0xff20		/* Start of OS-specific */
+#define SHN_HIOS	0xff3f		/* End of OS-specific */
+#define SHN_ABS		0xfff1		/* Associated symbol is absolute */
+#define SHN_COMMON	0xfff2		/* Associated symbol is common */
+#define SHN_XINDEX	0xffff		/* Index is in extra table.  */
+#define SHN_HIRESERVE	0xffff		/* End of reserved indices */
+
+/* Legal values for sh_type (section type).  */
+
+#define SHT_NULL	  0		/* Section header table entry unused */
+#define SHT_PROGBITS	  1		/* Program data */
+#define SHT_SYMTAB	  2		/* Symbol table */
+#define SHT_STRTAB	  3		/* String table */
+#define SHT_RELA	  4		/* Relocation entries with addends */
+#define SHT_HASH	  5		/* Symbol hash table */
+#define SHT_DYNAMIC	  6		/* Dynamic linking information */
+#define SHT_NOTE	  7		/* Notes */
+#define SHT_NOBITS	  8		/* Program space with no data (bss) */
+#define SHT_REL		  9		/* Relocation entries, no addends */
+#define SHT_SHLIB	  10		/* Reserved */
+#define SHT_DYNSYM	  11		/* Dynamic linker symbol table */
+#define SHT_INIT_ARRAY	  14		/* Array of constructors */
+#define SHT_FINI_ARRAY	  15		/* Array of destructors */
+#define SHT_PREINIT_ARRAY 16		/* Array of pre-constructors */
+#define SHT_GROUP	  17		/* Section group */
+#define SHT_SYMTAB_SHNDX  18		/* Extended section indeces */
+#define	SHT_NUM		  19		/* Number of defined types.  */
+#define SHT_LOOS	  0x60000000	/* Start OS-specific */
+#define SHT_GNU_LIBLIST	  0x6ffffff7	/* Prelink library list */
+#define SHT_CHECKSUM	  0x6ffffff8	/* Checksum for DSO content.  */
+#define SHT_LOSUNW	  0x6ffffffa	/* Sun-specific low bound.  */
+#define SHT_SUNW_move	  0x6ffffffa
+#define SHT_SUNW_COMDAT   0x6ffffffb
+#define SHT_SUNW_syminfo  0x6ffffffc
+#define SHT_GNU_verdef	  0x6ffffffd	/* Version definition section.  */
+#define SHT_GNU_verneed	  0x6ffffffe	/* Version needs section.  */
+#define SHT_GNU_versym	  0x6fffffff	/* Version symbol table.  */
+#define SHT_HISUNW	  0x6fffffff	/* Sun-specific high bound.  */
+#define SHT_HIOS	  0x6fffffff	/* End OS-specific type */
+#define SHT_LOPROC	  0x70000000	/* Start of processor-specific */
+#define SHT_HIPROC	  0x7fffffff	/* End of processor-specific */
+#define SHT_LOUSER	  0x80000000	/* Start of application-specific */
+#define SHT_HIUSER	  0x8fffffff	/* End of application-specific */
+
+/* Legal values for sh_flags (section flags).  */
+
+#define SHF_WRITE	     (1 << 0)	/* Writable */
+#define SHF_ALLOC	     (1 << 1)	/* Occupies memory during execution */
+#define SHF_EXECINSTR	     (1 << 2)	/* Executable */
+#define SHF_MERGE	     (1 << 4)	/* Might be merged */
+#define SHF_STRINGS	     (1 << 5)	/* Contains nul-terminated strings */
+#define SHF_INFO_LINK	     (1 << 6)	/* `sh_info' contains SHT index */
+#define SHF_LINK_ORDER	     (1 << 7)	/* Preserve order after combining */
+#define SHF_OS_NONCONFORMING (1 << 8)	/* Non-standard OS specific handling
+					   required */
+#define SHF_GROUP	     (1 << 9)	/* Section is member of a group.  */
+#define SHF_TLS		     (1 << 10)	/* Section hold thread-local data.  */
+#define SHF_MASKOS	     0x0ff00000	/* OS-specific.  */
+#define SHF_MASKPROC	     0xf0000000	/* Processor-specific */
+#define SHF_ORDERED	     (1 << 30)	/* Special ordering requirement
+					   (Solaris).  */
+#define SHF_EXCLUDE	     (1 << 31)	/* Section is excluded unless
+					   referenced or allocated (Solaris).*/
+
+/* Section group handling.  */
+#define GRP_COMDAT	0x1		/* Mark group as COMDAT.  */
+
+/* Symbol table entry.  */
+
+typedef struct
+{
+  Elf32_Word	st_name;		/* Symbol name (string tbl index) */
+  Elf32_Addr	st_value;		/* Symbol value */
+  Elf32_Word	st_size;		/* Symbol size */
+  unsigned char	st_info;		/* Symbol type and binding */
+  unsigned char	st_other;		/* Symbol visibility */
+  Elf32_Section	st_shndx;		/* Section index */
+} Elf32_Sym;
+
+typedef struct
+{
+  Elf64_Word	st_name;		/* Symbol name (string tbl index) */
+  unsigned char	st_info;		/* Symbol type and binding */
+  unsigned char st_other;		/* Symbol visibility */
+  Elf64_Section	st_shndx;		/* Section index */
+  Elf64_Addr	st_value;		/* Symbol value */
+  Elf64_Xword	st_size;		/* Symbol size */
+} Elf64_Sym;
+
+/* The syminfo section if available contains additional information about
+   every dynamic symbol.  */
+
+typedef struct
+{
+  Elf32_Half si_boundto;		/* Direct bindings, symbol bound to */
+  Elf32_Half si_flags;			/* Per symbol flags */
+} Elf32_Syminfo;
+
+typedef struct
+{
+  Elf64_Half si_boundto;		/* Direct bindings, symbol bound to */
+  Elf64_Half si_flags;			/* Per symbol flags */
+} Elf64_Syminfo;
+
+/* Possible values for si_boundto.  */
+#define SYMINFO_BT_SELF		0xffff	/* Symbol bound to self */
+#define SYMINFO_BT_PARENT	0xfffe	/* Symbol bound to parent */
+#define SYMINFO_BT_LOWRESERVE	0xff00	/* Beginning of reserved entries */
+
+/* Possible bitmasks for si_flags.  */
+#define SYMINFO_FLG_DIRECT	0x0001	/* Direct bound symbol */
+#define SYMINFO_FLG_PASSTHRU	0x0002	/* Pass-thru symbol for translator */
+#define SYMINFO_FLG_COPY	0x0004	/* Symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD	0x0008	/* Symbol bound to object to be lazy
+					   loaded */
+/* Syminfo version values.  */
+#define SYMINFO_NONE		0
+#define SYMINFO_CURRENT		1
+#define SYMINFO_NUM		2
+
+
+/* How to extract and insert information held in the st_info field.  */
+
+#define ELF32_ST_BIND(val)		(((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val)		((val) & 0xf)
+#define ELF32_ST_INFO(bind, type)	(((bind) << 4) + ((type) & 0xf))
+
+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
+#define ELF64_ST_BIND(val)		ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val)		ELF32_ST_TYPE (val)
+#define ELF64_ST_INFO(bind, type)	ELF32_ST_INFO ((bind), (type))
+
+/* Legal values for ST_BIND subfield of st_info (symbol binding).  */
+
+#define STB_LOCAL	0		/* Local symbol */
+#define STB_GLOBAL	1		/* Global symbol */
+#define STB_WEAK	2		/* Weak symbol */
+#define	STB_NUM		3		/* Number of defined types.  */
+#define STB_LOOS	10		/* Start of OS-specific */
+#define STB_HIOS	12		/* End of OS-specific */
+#define STB_LOPROC	13		/* Start of processor-specific */
+#define STB_HIPROC	15		/* End of processor-specific */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_NOTYPE	0		/* Symbol type is unspecified */
+#define STT_OBJECT	1		/* Symbol is a data object */
+#define STT_FUNC	2		/* Symbol is a code object */
+#define STT_SECTION	3		/* Symbol associated with a section */
+#define STT_FILE	4		/* Symbol's name is file name */
+#define STT_COMMON	5		/* Symbol is a common data object */
+#define STT_TLS		6		/* Symbol is thread-local data object*/
+#define	STT_NUM		7		/* Number of defined types.  */
+#define STT_LOOS	10		/* Start of OS-specific */
+#define STT_HIOS	12		/* End of OS-specific */
+#define STT_LOPROC	13		/* Start of processor-specific */
+#define STT_HIPROC	15		/* End of processor-specific */
+
+
+/* Symbol table indices are found in the hash buckets and chain table
+   of a symbol hash table section.  This special index value indicates
+   the end of a chain, meaning no further symbols are found in that bucket.  */
+
+#define STN_UNDEF	0		/* End of a chain.  */
+
+
+/* How to extract and insert information held in the st_other field.  */
+
+#define ELF32_ST_VISIBILITY(o)	((o) & 0x03)
+
+/* For ELF64 the definitions are the same.  */
+#define ELF64_ST_VISIBILITY(o)	ELF32_ST_VISIBILITY (o)
+
+/* Symbol visibility specification encoded in the st_other field.  */
+#define STV_DEFAULT	0		/* Default symbol visibility rules */
+#define STV_INTERNAL	1		/* Processor specific hidden class */
+#define STV_HIDDEN	2		/* Sym unavailable in other modules */
+#define STV_PROTECTED	3		/* Not preemptible, not exported */
+
+
+/* Relocation table entry without addend (in section of type SHT_REL).  */
+
+typedef struct
+{
+  Elf32_Addr	r_offset;		/* Address */
+  Elf32_Word	r_info;			/* Relocation type and symbol index */
+} Elf32_Rel;
+
+/* I have seen two different definitions of the Elf64_Rel and
+   Elf64_Rela structures, so we'll leave them out until Novell (or
+   whoever) gets their act together.  */
+/* The following, at least, is used on Sparc v9, MIPS, and Alpha.  */
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  Elf64_Xword	r_info;			/* Relocation type and symbol index */
+} Elf64_Rel;
+
+/* Relocation table entry with addend (in section of type SHT_RELA).  */
+
+typedef struct
+{
+  Elf32_Addr	r_offset;		/* Address */
+  Elf32_Word	r_info;			/* Relocation type and symbol index */
+  Elf32_Sword	r_addend;		/* Addend */
+} Elf32_Rela;
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  Elf64_Xword	r_info;			/* Relocation type and symbol index */
+  Elf64_Sxword	r_addend;		/* Addend */
+} Elf64_Rela;
+
+/* How to extract and insert information held in the r_info field.  */
+
+#define ELF32_R_SYM(val)		((val) >> 8)
+#define ELF32_R_TYPE(val)		((val) & 0xff)
+#define ELF32_R_INFO(sym, type)		(((sym) << 8) + ((type) & 0xff))
+
+#define ELF64_R_SYM(i)			((i) >> 32)
+#define ELF64_R_TYPE(i)			((i) & 0xffffffff)
+#define ELF64_R_INFO(sym,type)		((((Elf64_Xword) (sym)) << 32) + (type))
+
+/* Program segment header.  */
+
+typedef struct
+{
+  Elf32_Word	p_type;			/* Segment type */
+  Elf32_Off	p_offset;		/* Segment file offset */
+  Elf32_Addr	p_vaddr;		/* Segment virtual address */
+  Elf32_Addr	p_paddr;		/* Segment physical address */
+  Elf32_Word	p_filesz;		/* Segment size in file */
+  Elf32_Word	p_memsz;		/* Segment size in memory */
+  Elf32_Word	p_flags;		/* Segment flags */
+  Elf32_Word	p_align;		/* Segment alignment */
+} Elf32_Phdr;
+
+typedef struct
+{
+  Elf64_Word	p_type;			/* Segment type */
+  Elf64_Word	p_flags;		/* Segment flags */
+  Elf64_Off	p_offset;		/* Segment file offset */
+  Elf64_Addr	p_vaddr;		/* Segment virtual address */
+  Elf64_Addr	p_paddr;		/* Segment physical address */
+  Elf64_Xword	p_filesz;		/* Segment size in file */
+  Elf64_Xword	p_memsz;		/* Segment size in memory */
+  Elf64_Xword	p_align;		/* Segment alignment */
+} Elf64_Phdr;
+
+/* Legal values for p_type (segment type).  */
+
+#define	PT_NULL		0		/* Program header table entry unused */
+#define PT_LOAD		1		/* Loadable program segment */
+#define PT_DYNAMIC	2		/* Dynamic linking information */
+#define PT_INTERP	3		/* Program interpreter */
+#define PT_NOTE		4		/* Auxiliary information */
+#define PT_SHLIB	5		/* Reserved */
+#define PT_PHDR		6		/* Entry for header table itself */
+#define PT_TLS		7		/* Thread-local storage segment */
+#define	PT_NUM		8		/* Number of defined types */
+#define PT_LOOS		0x60000000	/* Start of OS-specific */
+#define PT_GNU_EH_FRAME	0x6474e550	/* GCC .eh_frame_hdr segment */
+#define PT_GNU_STACK	0x6474e551	/* Indicates stack executability */
+#define PT_GNU_RELRO	0x6474e552	/* Read-only after relocation */
+#define PT_LOSUNW	0x6ffffffa
+#define PT_SUNWBSS	0x6ffffffa	/* Sun Specific segment */
+#define PT_SUNWSTACK	0x6ffffffb	/* Stack segment */
+#define PT_HISUNW	0x6fffffff
+#define PT_HIOS		0x6fffffff	/* End of OS-specific */
+#define PT_LOPROC	0x70000000	/* Start of processor-specific */
+#define PT_HIPROC	0x7fffffff	/* End of processor-specific */
+
+/* Legal values for p_flags (segment flags).  */
+
+#define PF_X		(1 << 0)	/* Segment is executable */
+#define PF_W		(1 << 1)	/* Segment is writable */
+#define PF_R		(1 << 2)	/* Segment is readable */
+#define PF_MASKOS	0x0ff00000	/* OS-specific */
+#define PF_MASKPROC	0xf0000000	/* Processor-specific */
+
+/* Legal values for note segment descriptor types for core files. */
+
+#define NT_PRSTATUS	1		/* Contains copy of prstatus struct */
+#define NT_FPREGSET	2		/* Contains copy of fpregset struct */
+#define NT_PRPSINFO	3		/* Contains copy of prpsinfo struct */
+#define NT_PRXREG	4		/* Contains copy of prxregset struct */
+#define NT_TASKSTRUCT	4		/* Contains copy of task structure */
+#define NT_PLATFORM	5		/* String from sysinfo(SI_PLATFORM) */
+#define NT_AUXV		6		/* Contains copy of auxv array */
+#define NT_GWINDOWS	7		/* Contains copy of gwindows struct */
+#define NT_ASRS		8		/* Contains copy of asrset struct */
+#define NT_PSTATUS	10		/* Contains copy of pstatus struct */
+#define NT_PSINFO	13		/* Contains copy of psinfo struct */
+#define NT_PRCRED	14		/* Contains copy of prcred struct */
+#define NT_UTSNAME	15		/* Contains copy of utsname struct */
+#define NT_LWPSTATUS	16		/* Contains copy of lwpstatus struct */
+#define NT_LWPSINFO	17		/* Contains copy of lwpinfo struct */
+#define NT_PRFPXREG	20		/* Contains copy of fprxregset struct*/
+
+/* Legal values for the note segment descriptor types for object files.  */
+
+#define NT_VERSION	1		/* Contains a version string.  */
+
+
+/* Dynamic section entry.  */
+
+typedef struct
+{
+  Elf32_Sword	d_tag;			/* Dynamic entry type */
+  union
+    {
+      Elf32_Word d_val;			/* Integer value */
+      Elf32_Addr d_ptr;			/* Address value */
+    } d_un;
+} Elf32_Dyn;
+
+typedef struct
+{
+  Elf64_Sxword	d_tag;			/* Dynamic entry type */
+  union
+    {
+      Elf64_Xword d_val;		/* Integer value */
+      Elf64_Addr d_ptr;			/* Address value */
+    } d_un;
+} Elf64_Dyn;
+
+/* Legal values for d_tag (dynamic entry type).  */
+
+#define DT_NULL		0		/* Marks end of dynamic section */
+#define DT_NEEDED	1		/* Name of needed library */
+#define DT_PLTRELSZ	2		/* Size in bytes of PLT relocs */
+#define DT_PLTGOT	3		/* Processor defined value */
+#define DT_HASH		4		/* Address of symbol hash table */
+#define DT_STRTAB	5		/* Address of string table */
+#define DT_SYMTAB	6		/* Address of symbol table */
+#define DT_RELA		7		/* Address of Rela relocs */
+#define DT_RELASZ	8		/* Total size of Rela relocs */
+#define DT_RELAENT	9		/* Size of one Rela reloc */
+#define DT_STRSZ	10		/* Size of string table */
+#define DT_SYMENT	11		/* Size of one symbol table entry */
+#define DT_INIT		12		/* Address of init function */
+#define DT_FINI		13		/* Address of termination function */
+#define DT_SONAME	14		/* Name of shared object */
+#define DT_RPATH	15		/* Library search path (deprecated) */
+#define DT_SYMBOLIC	16		/* Start symbol search here */
+#define DT_REL		17		/* Address of Rel relocs */
+#define DT_RELSZ	18		/* Total size of Rel relocs */
+#define DT_RELENT	19		/* Size of one Rel reloc */
+#define DT_PLTREL	20		/* Type of reloc in PLT */
+#define DT_DEBUG	21		/* For debugging; unspecified */
+#define DT_TEXTREL	22		/* Reloc might modify .text */
+#define DT_JMPREL	23		/* Address of PLT relocs */
+#define	DT_BIND_NOW	24		/* Process relocations of object */
+#define	DT_INIT_ARRAY	25		/* Array with addresses of init fct */
+#define	DT_FINI_ARRAY	26		/* Array with addresses of fini fct */
+#define	DT_INIT_ARRAYSZ	27		/* Size in bytes of DT_INIT_ARRAY */
+#define	DT_FINI_ARRAYSZ	28		/* Size in bytes of DT_FINI_ARRAY */
+#define DT_RUNPATH	29		/* Library search path */
+#define DT_FLAGS	30		/* Flags for the object being loaded */
+#define DT_ENCODING	32		/* Start of encoded range */
+#define DT_PREINIT_ARRAY 32		/* Array with addresses of preinit fct*/
+#define DT_PREINIT_ARRAYSZ 33		/* size in bytes of DT_PREINIT_ARRAY */
+#define	DT_NUM		34		/* Number used */
+#define DT_LOOS		0x6000000d	/* Start of OS-specific */
+#define DT_HIOS		0x6ffff000	/* End of OS-specific */
+#define DT_LOPROC	0x70000000	/* Start of processor-specific */
+#define DT_HIPROC	0x7fffffff	/* End of processor-specific */
+#define	DT_PROCNUM	DT_MIPS_NUM	/* Most used by any processor */
+
+/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
+   Dyn.d_un.d_val field of the Elf*_Dyn structure.  This follows Sun's
+   approach.  */
+#define DT_VALRNGLO	0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5	/* Prelinking timestamp */
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6	/* Size of conflict section */
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7	/* Size of library list */
+#define DT_CHECKSUM	0x6ffffdf8
+#define DT_PLTPADSZ	0x6ffffdf9
+#define DT_MOVEENT	0x6ffffdfa
+#define DT_MOVESZ	0x6ffffdfb
+#define DT_FEATURE_1	0x6ffffdfc	/* Feature selection (DTF_*).  */
+#define DT_POSFLAG_1	0x6ffffdfd	/* Flags for DT_* entries, effecting
+					   the following DT_* entry.  */
+#define DT_SYMINSZ	0x6ffffdfe	/* Size of syminfo table (in bytes) */
+#define DT_SYMINENT	0x6ffffdff	/* Entry size of syminfo */
+#define DT_VALRNGHI	0x6ffffdff
+#define DT_VALTAGIDX(tag)	(DT_VALRNGHI - (tag))	/* Reverse order! */
+#define DT_VALNUM 12
+
+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+   Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+
+   If any adjustment is made to the ELF object after it has been
+   built these entries will need to be adjusted.  */
+#define DT_ADDRRNGLO	0x6ffffe00
+#define DT_GNU_CONFLICT	0x6ffffef8	/* Start of conflict section */
+#define DT_GNU_LIBLIST	0x6ffffef9	/* Library list */
+#define DT_CONFIG	0x6ffffefa	/* Configuration information.  */
+#define DT_DEPAUDIT	0x6ffffefb	/* Dependency auditing.  */
+#define DT_AUDIT	0x6ffffefc	/* Object auditing.  */
+#define	DT_PLTPAD	0x6ffffefd	/* PLT padding.  */
+#define	DT_MOVETAB	0x6ffffefe	/* Move table.  */
+#define DT_SYMINFO	0x6ffffeff	/* Syminfo table.  */
+#define DT_ADDRRNGHI	0x6ffffeff
+#define DT_ADDRTAGIDX(tag)	(DT_ADDRRNGHI - (tag))	/* Reverse order! */
+#define DT_ADDRNUM 10
+
+/* The versioning entry types.  The next are defined as part of the
+   GNU extension.  */
+#define DT_VERSYM	0x6ffffff0
+
+#define DT_RELACOUNT	0x6ffffff9
+#define DT_RELCOUNT	0x6ffffffa
+
+/* These were chosen by Sun.  */
+#define DT_FLAGS_1	0x6ffffffb	/* State flags, see DF_1_* below.  */
+#define	DT_VERDEF	0x6ffffffc	/* Address of version definition
+					   table */
+#define	DT_VERDEFNUM	0x6ffffffd	/* Number of version definitions */
+#define	DT_VERNEED	0x6ffffffe	/* Address of table with needed
+					   versions */
+#define	DT_VERNEEDNUM	0x6fffffff	/* Number of needed versions */
+#define DT_VERSIONTAGIDX(tag)	(DT_VERNEEDNUM - (tag))	/* Reverse order! */
+#define DT_VERSIONTAGNUM 16
+
+/* Sun added these machine-independent extensions in the "processor-specific"
+   range.  Be compatible.  */
+#define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
+#define DT_FILTER       0x7fffffff      /* Shared object to get values from */
+#define DT_EXTRATAGIDX(tag)	((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
+#define DT_EXTRANUM	3
+
+/* Values of `d_un.d_val' in the DT_FLAGS entry.  */
+#define DF_ORIGIN	0x00000001	/* Object may use DF_ORIGIN */
+#define DF_SYMBOLIC	0x00000002	/* Symbol resolutions starts here */
+#define DF_TEXTREL	0x00000004	/* Object contains text relocations */
+#define DF_BIND_NOW	0x00000008	/* No lazy binding for this object */
+#define DF_STATIC_TLS	0x00000010	/* Module uses the static TLS model */
+
+/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
+   entry in the dynamic section.  */
+#define DF_1_NOW	0x00000001	/* Set RTLD_NOW for this object.  */
+#define DF_1_GLOBAL	0x00000002	/* Set RTLD_GLOBAL for this object.  */
+#define DF_1_GROUP	0x00000004	/* Set RTLD_GROUP for this object.  */
+#define DF_1_NODELETE	0x00000008	/* Set RTLD_NODELETE for this object.*/
+#define DF_1_LOADFLTR	0x00000010	/* Trigger filtee loading at runtime.*/
+#define DF_1_INITFIRST	0x00000020	/* Set RTLD_INITFIRST for this object*/
+#define DF_1_NOOPEN	0x00000040	/* Set RTLD_NOOPEN for this object.  */
+#define DF_1_ORIGIN	0x00000080	/* $ORIGIN must be handled.  */
+#define DF_1_DIRECT	0x00000100	/* Direct binding enabled.  */
+#define DF_1_TRANS	0x00000200
+#define DF_1_INTERPOSE	0x00000400	/* Object is used to interpose.  */
+#define DF_1_NODEFLIB	0x00000800	/* Ignore default lib search path.  */
+#define DF_1_NODUMP	0x00001000	/* Object can't be dldump'ed.  */
+#define DF_1_CONFALT	0x00002000	/* Configuration alternative created.*/
+#define DF_1_ENDFILTEE	0x00004000	/* Filtee terminates filters search. */
+#define	DF_1_DISPRELDNE	0x00008000	/* Disp reloc applied at build time. */
+#define	DF_1_DISPRELPND	0x00010000	/* Disp reloc applied at run-time.  */
+
+/* Flags for the feature selection in DT_FEATURE_1.  */
+#define DTF_1_PARINIT	0x00000001
+#define DTF_1_CONFEXP	0x00000002
+
+/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry.  */
+#define DF_P1_LAZYLOAD	0x00000001	/* Lazyload following object.  */
+#define DF_P1_GROUPPERM	0x00000002	/* Symbols from next object are not
+					   generally available.  */
+
+/* Version definition sections.  */
+
+typedef struct
+{
+  Elf32_Half	vd_version;		/* Version revision */
+  Elf32_Half	vd_flags;		/* Version information */
+  Elf32_Half	vd_ndx;			/* Version Index */
+  Elf32_Half	vd_cnt;			/* Number of associated aux entries */
+  Elf32_Word	vd_hash;		/* Version name hash value */
+  Elf32_Word	vd_aux;			/* Offset in bytes to verdaux array */
+  Elf32_Word	vd_next;		/* Offset in bytes to next verdef
+					   entry */
+} Elf32_Verdef;
+
+typedef struct
+{
+  Elf64_Half	vd_version;		/* Version revision */
+  Elf64_Half	vd_flags;		/* Version information */
+  Elf64_Half	vd_ndx;			/* Version Index */
+  Elf64_Half	vd_cnt;			/* Number of associated aux entries */
+  Elf64_Word	vd_hash;		/* Version name hash value */
+  Elf64_Word	vd_aux;			/* Offset in bytes to verdaux array */
+  Elf64_Word	vd_next;		/* Offset in bytes to next verdef
+					   entry */
+} Elf64_Verdef;
+
+
+/* Legal values for vd_version (version revision).  */
+#define VER_DEF_NONE	0		/* No version */
+#define VER_DEF_CURRENT	1		/* Current version */
+#define VER_DEF_NUM	2		/* Given version number */
+
+/* Legal values for vd_flags (version information flags).  */
+#define VER_FLG_BASE	0x1		/* Version definition of file itself */
+#define VER_FLG_WEAK	0x2		/* Weak version identifier */
+
+/* Versym symbol index values.  */
+#define	VER_NDX_LOCAL		0	/* Symbol is local.  */
+#define	VER_NDX_GLOBAL		1	/* Symbol is global.  */
+#define	VER_NDX_LORESERVE	0xff00	/* Beginning of reserved entries.  */
+#define	VER_NDX_ELIMINATE	0xff01	/* Symbol is to be eliminated.  */
+
+/* Auxialiary version information.  */
+
+typedef struct
+{
+  Elf32_Word	vda_name;		/* Version or dependency names */
+  Elf32_Word	vda_next;		/* Offset in bytes to next verdaux
+					   entry */
+} Elf32_Verdaux;
+
+typedef struct
+{
+  Elf64_Word	vda_name;		/* Version or dependency names */
+  Elf64_Word	vda_next;		/* Offset in bytes to next verdaux
+					   entry */
+} Elf64_Verdaux;
+
+
+/* Version dependency section.  */
+
+typedef struct
+{
+  Elf32_Half	vn_version;		/* Version of structure */
+  Elf32_Half	vn_cnt;			/* Number of associated aux entries */
+  Elf32_Word	vn_file;		/* Offset of filename for this
+					   dependency */
+  Elf32_Word	vn_aux;			/* Offset in bytes to vernaux array */
+  Elf32_Word	vn_next;		/* Offset in bytes to next verneed
+					   entry */
+} Elf32_Verneed;
+
+typedef struct
+{
+  Elf64_Half	vn_version;		/* Version of structure */
+  Elf64_Half	vn_cnt;			/* Number of associated aux entries */
+  Elf64_Word	vn_file;		/* Offset of filename for this
+					   dependency */
+  Elf64_Word	vn_aux;			/* Offset in bytes to vernaux array */
+  Elf64_Word	vn_next;		/* Offset in bytes to next verneed
+					   entry */
+} Elf64_Verneed;
+
+
+/* Legal values for vn_version (version revision).  */
+#define VER_NEED_NONE	 0		/* No version */
+#define VER_NEED_CURRENT 1		/* Current version */
+#define VER_NEED_NUM	 2		/* Given version number */
+
+/* Auxiliary needed version information.  */
+
+typedef struct
+{
+  Elf32_Word	vna_hash;		/* Hash value of dependency name */
+  Elf32_Half	vna_flags;		/* Dependency specific information */
+  Elf32_Half	vna_other;		/* Unused */
+  Elf32_Word	vna_name;		/* Dependency name string offset */
+  Elf32_Word	vna_next;		/* Offset in bytes to next vernaux
+					   entry */
+} Elf32_Vernaux;
+
+typedef struct
+{
+  Elf64_Word	vna_hash;		/* Hash value of dependency name */
+  Elf64_Half	vna_flags;		/* Dependency specific information */
+  Elf64_Half	vna_other;		/* Unused */
+  Elf64_Word	vna_name;		/* Dependency name string offset */
+  Elf64_Word	vna_next;		/* Offset in bytes to next vernaux
+					   entry */
+} Elf64_Vernaux;
+
+
+/* Legal values for vna_flags.  */
+#define VER_FLG_WEAK	0x2		/* Weak version identifier */
+
+
+/* Auxiliary vector.  */
+
+/* This vector is normally only used by the program interpreter.  The
+   usual definition in an ABI supplement uses the name auxv_t.  The
+   vector is not usually defined in a standard <elf.h> file, but it
+   can't hurt.  We rename it to avoid conflicts.  The sizes of these
+   types are an arrangement between the exec server and the program
+   interpreter, so we don't fully specify them here.  */
+
+typedef struct
+{
+  uint32_t a_type;		/* Entry type */
+  union
+    {
+      uint32_t a_val;		/* Integer value */
+      /* We use to have pointer elements added here.  We cannot do that,
+	 though, since it does not work when using 32-bit definitions
+	 on 64-bit platforms and vice versa.  */
+    } a_un;
+} Elf32_auxv_t;
+
+typedef struct
+{
+  uint64_t a_type;		/* Entry type */
+  union
+    {
+      uint64_t a_val;		/* Integer value */
+      /* We use to have pointer elements added here.  We cannot do that,
+	 though, since it does not work when using 32-bit definitions
+	 on 64-bit platforms and vice versa.  */
+    } a_un;
+} Elf64_auxv_t;
+
+/* Legal values for a_type (entry type).  */
+
+#define AT_NULL		0		/* End of vector */
+#define AT_IGNORE	1		/* Entry should be ignored */
+#define AT_EXECFD	2		/* File descriptor of program */
+#define AT_PHDR		3		/* Program headers for program */
+#define AT_PHENT	4		/* Size of program header entry */
+#define AT_PHNUM	5		/* Number of program headers */
+#define AT_PAGESZ	6		/* System page size */
+#define AT_BASE		7		/* Base address of interpreter */
+#define AT_FLAGS	8		/* Flags */
+#define AT_ENTRY	9		/* Entry point of program */
+#define AT_NOTELF	10		/* Program is not ELF */
+#define AT_UID		11		/* Real uid */
+#define AT_EUID		12		/* Effective uid */
+#define AT_GID		13		/* Real gid */
+#define AT_EGID		14		/* Effective gid */
+#define AT_CLKTCK	17		/* Frequency of times() */
+
+/* Some more special a_type values describing the hardware.  */
+#define AT_PLATFORM	15		/* String identifying platform.  */
+#define AT_HWCAP	16		/* Machine dependent hints about
+					   processor capabilities.  */
+
+/* This entry gives some information about the FPU initialization
+   performed by the kernel.  */
+#define AT_FPUCW	18		/* Used FPU control word.  */
+
+/* Cache block sizes.  */
+#define AT_DCACHEBSIZE	19		/* Data cache block size.  */
+#define AT_ICACHEBSIZE	20		/* Instruction cache block size.  */
+#define AT_UCACHEBSIZE	21		/* Unified cache block size.  */
+
+/* A special ignored value for PPC, used by the kernel to control the
+   interpretation of the AUXV. Must be > 16.  */
+#define AT_IGNOREPPC	22		/* Entry should be ignored.  */
+
+#define	AT_SECURE	23		/* Boolean, was exec setuid-like?  */
+
+/* Pointer to the global system page used for system calls and other
+   nice things.  */
+#define AT_SYSINFO	32
+#define AT_SYSINFO_EHDR	33
+
+/* Shapes of the caches.  Bits 0-3 contains associativity; bits 4-7 contains
+   log2 of line size; mask those to get cache size.  */
+#define AT_L1I_CACHESHAPE	34
+#define AT_L1D_CACHESHAPE	35
+#define AT_L2_CACHESHAPE	36
+#define AT_L3_CACHESHAPE	37
+
+/* Note section contents.  Each entry in the note section begins with
+   a header of a fixed form.  */
+
+typedef struct
+{
+  Elf32_Word n_namesz;			/* Length of the note's name.  */
+  Elf32_Word n_descsz;			/* Length of the note's descriptor.  */
+  Elf32_Word n_type;			/* Type of the note.  */
+} Elf32_Nhdr;
+
+typedef struct
+{
+  Elf64_Word n_namesz;			/* Length of the note's name.  */
+  Elf64_Word n_descsz;			/* Length of the note's descriptor.  */
+  Elf64_Word n_type;			/* Type of the note.  */
+} Elf64_Nhdr;
+
+/* Known names of notes.  */
+
+/* Solaris entries in the note section have this name.  */
+#define ELF_NOTE_SOLARIS	"SUNW Solaris"
+
+/* Note entries for GNU systems have this name.  */
+#define ELF_NOTE_GNU		"GNU"
+
+
+/* Defined types of notes for Solaris.  */
+
+/* Value of descriptor (one word) is desired pagesize for the binary.  */
+#define ELF_NOTE_PAGESIZE_HINT	1
+
+
+/* Defined note types for GNU systems.  */
+
+/* ABI information.  The descriptor consists of words:
+   word 0: OS descriptor
+   word 1: major version of the ABI
+   word 2: minor version of the ABI
+   word 3: subminor version of the ABI
+*/
+#define ELF_NOTE_ABI		1
+
+/* Known OSes.  These value can appear in word 0 of an ELF_NOTE_ABI
+   note section entry.  */
+#define ELF_NOTE_OS_LINUX	0
+#define ELF_NOTE_OS_GNU		1
+#define ELF_NOTE_OS_SOLARIS2	2
+#define ELF_NOTE_OS_FREEBSD	3
+
+
+/* Move records.  */
+typedef struct
+{
+  Elf32_Xword m_value;		/* Symbol value.  */
+  Elf32_Word m_info;		/* Size and index.  */
+  Elf32_Word m_poffset;		/* Symbol offset.  */
+  Elf32_Half m_repeat;		/* Repeat count.  */
+  Elf32_Half m_stride;		/* Stride info.  */
+} Elf32_Move;
+
+typedef struct
+{
+  Elf64_Xword m_value;		/* Symbol value.  */
+  Elf64_Xword m_info;		/* Size and index.  */
+  Elf64_Xword m_poffset;	/* Symbol offset.  */
+  Elf64_Half m_repeat;		/* Repeat count.  */
+  Elf64_Half m_stride;		/* Stride info.  */
+} Elf64_Move;
+
+/* Macro to construct move records.  */
+#define ELF32_M_SYM(info)	((info) >> 8)
+#define ELF32_M_SIZE(info)	((unsigned char) (info))
+#define ELF32_M_INFO(sym, size)	(((sym) << 8) + (unsigned char) (size))
+
+#define ELF64_M_SYM(info)	ELF32_M_SYM (info)
+#define ELF64_M_SIZE(info)	ELF32_M_SIZE (info)
+#define ELF64_M_INFO(sym, size)	ELF32_M_INFO (sym, size)
+
+
+/* Motorola 68k specific definitions.  */
+
+/* Values for Elf32_Ehdr.e_flags.  */
+#define EF_CPU32	0x00810000
+
+/* m68k relocs.  */
+
+#define R_68K_NONE	0		/* No reloc */
+#define R_68K_32	1		/* Direct 32 bit  */
+#define R_68K_16	2		/* Direct 16 bit  */
+#define R_68K_8		3		/* Direct 8 bit  */
+#define R_68K_PC32	4		/* PC relative 32 bit */
+#define R_68K_PC16	5		/* PC relative 16 bit */
+#define R_68K_PC8	6		/* PC relative 8 bit */
+#define R_68K_GOT32	7		/* 32 bit PC relative GOT entry */
+#define R_68K_GOT16	8		/* 16 bit PC relative GOT entry */
+#define R_68K_GOT8	9		/* 8 bit PC relative GOT entry */
+#define R_68K_GOT32O	10		/* 32 bit GOT offset */
+#define R_68K_GOT16O	11		/* 16 bit GOT offset */
+#define R_68K_GOT8O	12		/* 8 bit GOT offset */
+#define R_68K_PLT32	13		/* 32 bit PC relative PLT address */
+#define R_68K_PLT16	14		/* 16 bit PC relative PLT address */
+#define R_68K_PLT8	15		/* 8 bit PC relative PLT address */
+#define R_68K_PLT32O	16		/* 32 bit PLT offset */
+#define R_68K_PLT16O	17		/* 16 bit PLT offset */
+#define R_68K_PLT8O	18		/* 8 bit PLT offset */
+#define R_68K_COPY	19		/* Copy symbol at runtime */
+#define R_68K_GLOB_DAT	20		/* Create GOT entry */
+#define R_68K_JMP_SLOT	21		/* Create PLT entry */
+#define R_68K_RELATIVE	22		/* Adjust by program base */
+/* Keep this the last entry.  */
+#define R_68K_NUM	23
+
+/* Intel 80386 specific definitions.  */
+
+/* i386 relocs.  */
+
+#define R_386_NONE	   0		/* No reloc */
+#define R_386_32	   1		/* Direct 32 bit  */
+#define R_386_PC32	   2		/* PC relative 32 bit */
+#define R_386_GOT32	   3		/* 32 bit GOT entry */
+#define R_386_PLT32	   4		/* 32 bit PLT address */
+#define R_386_COPY	   5		/* Copy symbol at runtime */
+#define R_386_GLOB_DAT	   6		/* Create GOT entry */
+#define R_386_JMP_SLOT	   7		/* Create PLT entry */
+#define R_386_RELATIVE	   8		/* Adjust by program base */
+#define R_386_GOTOFF	   9		/* 32 bit offset to GOT */
+#define R_386_GOTPC	   10		/* 32 bit PC relative offset to GOT */
+#define R_386_32PLT	   11
+#define R_386_TLS_TPOFF	   14		/* Offset in static TLS block */
+#define R_386_TLS_IE	   15		/* Address of GOT entry for static TLS
+					   block offset */
+#define R_386_TLS_GOTIE	   16		/* GOT entry for static TLS block
+					   offset */
+#define R_386_TLS_LE	   17		/* Offset relative to static TLS
+					   block */
+#define R_386_TLS_GD	   18		/* Direct 32 bit for GNU version of
+					   general dynamic thread local data */
+#define R_386_TLS_LDM	   19		/* Direct 32 bit for GNU version of
+					   local dynamic thread local data
+					   in LE code */
+#define R_386_16	   20
+#define R_386_PC16	   21
+#define R_386_8		   22
+#define R_386_PC8	   23
+#define R_386_TLS_GD_32	   24		/* Direct 32 bit for general dynamic
+					   thread local data */
+#define R_386_TLS_GD_PUSH  25		/* Tag for pushl in GD TLS code */
+#define R_386_TLS_GD_CALL  26		/* Relocation for call to
+					   __tls_get_addr() */
+#define R_386_TLS_GD_POP   27		/* Tag for popl in GD TLS code */
+#define R_386_TLS_LDM_32   28		/* Direct 32 bit for local dynamic
+					   thread local data in LE code */
+#define R_386_TLS_LDM_PUSH 29		/* Tag for pushl in LDM TLS code */
+#define R_386_TLS_LDM_CALL 30		/* Relocation for call to
+					   __tls_get_addr() in LDM code */
+#define R_386_TLS_LDM_POP  31		/* Tag for popl in LDM TLS code */
+#define R_386_TLS_LDO_32   32		/* Offset relative to TLS block */
+#define R_386_TLS_IE_32	   33		/* GOT entry for negated static TLS
+					   block offset */
+#define R_386_TLS_LE_32	   34		/* Negated offset relative to static
+					   TLS block */
+#define R_386_TLS_DTPMOD32 35		/* ID of module containing symbol */
+#define R_386_TLS_DTPOFF32 36		/* Offset in TLS block */
+#define R_386_TLS_TPOFF32  37		/* Negated offset in static TLS block */
+/* Keep this the last entry.  */
+#define R_386_NUM	   38
+
+/* SUN SPARC specific definitions.  */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_SPARC_REGISTER	13	/* Global register reserved to app. */
+
+/* Values for Elf64_Ehdr.e_flags.  */
+
+#define EF_SPARCV9_MM		3
+#define EF_SPARCV9_TSO		0
+#define EF_SPARCV9_PSO		1
+#define EF_SPARCV9_RMO		2
+#define EF_SPARC_LEDATA		0x800000 /* little endian data */
+#define EF_SPARC_EXT_MASK	0xFFFF00
+#define EF_SPARC_32PLUS		0x000100 /* generic V8+ features */
+#define EF_SPARC_SUN_US1	0x000200 /* Sun UltraSPARC1 extensions */
+#define EF_SPARC_HAL_R1		0x000400 /* HAL R1 extensions */
+#define EF_SPARC_SUN_US3	0x000800 /* Sun UltraSPARCIII extensions */
+
+/* SPARC relocs.  */
+
+#define R_SPARC_NONE		0	/* No reloc */
+#define R_SPARC_8		1	/* Direct 8 bit */
+#define R_SPARC_16		2	/* Direct 16 bit */
+#define R_SPARC_32		3	/* Direct 32 bit */
+#define R_SPARC_DISP8		4	/* PC relative 8 bit */
+#define R_SPARC_DISP16		5	/* PC relative 16 bit */
+#define R_SPARC_DISP32		6	/* PC relative 32 bit */
+#define R_SPARC_WDISP30		7	/* PC relative 30 bit shifted */
+#define R_SPARC_WDISP22		8	/* PC relative 22 bit shifted */
+#define R_SPARC_HI22		9	/* High 22 bit */
+#define R_SPARC_22		10	/* Direct 22 bit */
+#define R_SPARC_13		11	/* Direct 13 bit */
+#define R_SPARC_LO10		12	/* Truncated 10 bit */
+#define R_SPARC_GOT10		13	/* Truncated 10 bit GOT entry */
+#define R_SPARC_GOT13		14	/* 13 bit GOT entry */
+#define R_SPARC_GOT22		15	/* 22 bit GOT entry shifted */
+#define R_SPARC_PC10		16	/* PC relative 10 bit truncated */
+#define R_SPARC_PC22		17	/* PC relative 22 bit shifted */
+#define R_SPARC_WPLT30		18	/* 30 bit PC relative PLT address */
+#define R_SPARC_COPY		19	/* Copy symbol at runtime */
+#define R_SPARC_GLOB_DAT	20	/* Create GOT entry */
+#define R_SPARC_JMP_SLOT	21	/* Create PLT entry */
+#define R_SPARC_RELATIVE	22	/* Adjust by program base */
+#define R_SPARC_UA32		23	/* Direct 32 bit unaligned */
+
+/* Additional Sparc64 relocs.  */
+
+#define R_SPARC_PLT32		24	/* Direct 32 bit ref to PLT entry */
+#define R_SPARC_HIPLT22		25	/* High 22 bit PLT entry */
+#define R_SPARC_LOPLT10		26	/* Truncated 10 bit PLT entry */
+#define R_SPARC_PCPLT32		27	/* PC rel 32 bit ref to PLT entry */
+#define R_SPARC_PCPLT22		28	/* PC rel high 22 bit PLT entry */
+#define R_SPARC_PCPLT10		29	/* PC rel trunc 10 bit PLT entry */
+#define R_SPARC_10		30	/* Direct 10 bit */
+#define R_SPARC_11		31	/* Direct 11 bit */
+#define R_SPARC_64		32	/* Direct 64 bit */
+#define R_SPARC_OLO10		33	/* 10bit with secondary 13bit addend */
+#define R_SPARC_HH22		34	/* Top 22 bits of direct 64 bit */
+#define R_SPARC_HM10		35	/* High middle 10 bits of ... */
+#define R_SPARC_LM22		36	/* Low middle 22 bits of ... */
+#define R_SPARC_PC_HH22		37	/* Top 22 bits of pc rel 64 bit */
+#define R_SPARC_PC_HM10		38	/* High middle 10 bit of ... */
+#define R_SPARC_PC_LM22		39	/* Low miggle 22 bits of ... */
+#define R_SPARC_WDISP16		40	/* PC relative 16 bit shifted */
+#define R_SPARC_WDISP19		41	/* PC relative 19 bit shifted */
+#define R_SPARC_7		43	/* Direct 7 bit */
+#define R_SPARC_5		44	/* Direct 5 bit */
+#define R_SPARC_6		45	/* Direct 6 bit */
+#define R_SPARC_DISP64		46	/* PC relative 64 bit */
+#define R_SPARC_PLT64		47	/* Direct 64 bit ref to PLT entry */
+#define R_SPARC_HIX22		48	/* High 22 bit complemented */
+#define R_SPARC_LOX10		49	/* Truncated 11 bit complemented */
+#define R_SPARC_H44		50	/* Direct high 12 of 44 bit */
+#define R_SPARC_M44		51	/* Direct mid 22 of 44 bit */
+#define R_SPARC_L44		52	/* Direct low 10 of 44 bit */
+#define R_SPARC_REGISTER	53	/* Global register usage */
+#define R_SPARC_UA64		54	/* Direct 64 bit unaligned */
+#define R_SPARC_UA16		55	/* Direct 16 bit unaligned */
+#define R_SPARC_TLS_GD_HI22	56
+#define R_SPARC_TLS_GD_LO10	57
+#define R_SPARC_TLS_GD_ADD	58
+#define R_SPARC_TLS_GD_CALL	59
+#define R_SPARC_TLS_LDM_HI22	60
+#define R_SPARC_TLS_LDM_LO10	61
+#define R_SPARC_TLS_LDM_ADD	62
+#define R_SPARC_TLS_LDM_CALL	63
+#define R_SPARC_TLS_LDO_HIX22	64
+#define R_SPARC_TLS_LDO_LOX10	65
+#define R_SPARC_TLS_LDO_ADD	66
+#define R_SPARC_TLS_IE_HI22	67
+#define R_SPARC_TLS_IE_LO10	68
+#define R_SPARC_TLS_IE_LD	69
+#define R_SPARC_TLS_IE_LDX	70
+#define R_SPARC_TLS_IE_ADD	71
+#define R_SPARC_TLS_LE_HIX22	72
+#define R_SPARC_TLS_LE_LOX10	73
+#define R_SPARC_TLS_DTPMOD32	74
+#define R_SPARC_TLS_DTPMOD64	75
+#define R_SPARC_TLS_DTPOFF32	76
+#define R_SPARC_TLS_DTPOFF64	77
+#define R_SPARC_TLS_TPOFF32	78
+#define R_SPARC_TLS_TPOFF64	79
+/* Keep this the last entry.  */
+#define R_SPARC_NUM		80
+
+/* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_SPARC_NUM	2
+
+/* Bits present in AT_HWCAP, primarily for Sparc32.  */
+
+#define HWCAP_SPARC_FLUSH	1	/* The cpu supports flush insn.  */
+#define HWCAP_SPARC_STBAR	2
+#define HWCAP_SPARC_SWAP	4
+#define HWCAP_SPARC_MULDIV	8
+#define HWCAP_SPARC_V9		16	/* The cpu is v9, so v8plus is ok.  */
+#define HWCAP_SPARC_ULTRA3	32
+
+/* MIPS R3000 specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_MIPS_NOREORDER   1		/* A .noreorder directive was used */
+#define EF_MIPS_PIC	    2		/* Contains PIC code */
+#define EF_MIPS_CPIC	    4		/* Uses PIC calling sequence */
+#define EF_MIPS_XGOT	    8
+#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_ABI2	    32
+#define EF_MIPS_ABI_ON32    64
+#define EF_MIPS_ARCH	    0xf0000000	/* MIPS architecture level */
+
+/* Legal values for MIPS architecture level.  */
+
+#define EF_MIPS_ARCH_1	    0x00000000	/* -mips1 code.  */
+#define EF_MIPS_ARCH_2	    0x10000000	/* -mips2 code.  */
+#define EF_MIPS_ARCH_3	    0x20000000	/* -mips3 code.  */
+#define EF_MIPS_ARCH_4	    0x30000000	/* -mips4 code.  */
+#define EF_MIPS_ARCH_5	    0x40000000	/* -mips5 code.  */
+#define EF_MIPS_ARCH_32	    0x60000000	/* MIPS32 code.  */
+#define EF_MIPS_ARCH_64	    0x70000000	/* MIPS64 code.  */
+
+/* The following are non-official names and should not be used.  */
+
+#define E_MIPS_ARCH_1	  0x00000000	/* -mips1 code.  */
+#define E_MIPS_ARCH_2	  0x10000000	/* -mips2 code.  */
+#define E_MIPS_ARCH_3	  0x20000000	/* -mips3 code.  */
+#define E_MIPS_ARCH_4	  0x30000000	/* -mips4 code.  */
+#define E_MIPS_ARCH_5	  0x40000000	/* -mips5 code.  */
+#define E_MIPS_ARCH_32	  0x60000000	/* MIPS32 code.  */
+#define E_MIPS_ARCH_64	  0x70000000	/* MIPS64 code.  */
+
+/* Special section indices.  */
+
+#define SHN_MIPS_ACOMMON    0xff00	/* Allocated common symbols */
+#define SHN_MIPS_TEXT	    0xff01	/* Allocated test symbols.  */
+#define SHN_MIPS_DATA	    0xff02	/* Allocated data symbols.  */
+#define SHN_MIPS_SCOMMON    0xff03	/* Small common symbols */
+#define SHN_MIPS_SUNDEFINED 0xff04	/* Small undefined symbols */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
+#define SHT_MIPS_MSYM	       0x70000001
+#define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
+#define SHT_MIPS_GPTAB	       0x70000003 /* Global data area sizes */
+#define SHT_MIPS_UCODE	       0x70000004 /* Reserved for SGI/MIPS compilers */
+#define SHT_MIPS_DEBUG	       0x70000005 /* MIPS ECOFF debugging information*/
+#define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
+#define SHT_MIPS_PACKAGE       0x70000007
+#define SHT_MIPS_PACKSYM       0x70000008
+#define SHT_MIPS_RELD	       0x70000009
+#define SHT_MIPS_IFACE         0x7000000b
+#define SHT_MIPS_CONTENT       0x7000000c
+#define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
+#define SHT_MIPS_SHDR	       0x70000010
+#define SHT_MIPS_FDESC	       0x70000011
+#define SHT_MIPS_EXTSYM	       0x70000012
+#define SHT_MIPS_DENSE	       0x70000013
+#define SHT_MIPS_PDESC	       0x70000014
+#define SHT_MIPS_LOCSYM	       0x70000015
+#define SHT_MIPS_AUXSYM	       0x70000016
+#define SHT_MIPS_OPTSYM	       0x70000017
+#define SHT_MIPS_LOCSTR	       0x70000018
+#define SHT_MIPS_LINE	       0x70000019
+#define SHT_MIPS_RFDESC	       0x7000001a
+#define SHT_MIPS_DELTASYM      0x7000001b
+#define SHT_MIPS_DELTAINST     0x7000001c
+#define SHT_MIPS_DELTACLASS    0x7000001d
+#define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
+#define SHT_MIPS_DELTADECL     0x7000001f
+#define SHT_MIPS_SYMBOL_LIB    0x70000020
+#define SHT_MIPS_EVENTS	       0x70000021 /* Event section.  */
+#define SHT_MIPS_TRANSLATE     0x70000022
+#define SHT_MIPS_PIXIE	       0x70000023
+#define SHT_MIPS_XLATE	       0x70000024
+#define SHT_MIPS_XLATE_DEBUG   0x70000025
+#define SHT_MIPS_WHIRL	       0x70000026
+#define SHT_MIPS_EH_REGION     0x70000027
+#define SHT_MIPS_XLATE_OLD     0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_MIPS_GPREL	 0x10000000	/* Must be part of global data area */
+#define SHF_MIPS_MERGE	 0x20000000
+#define SHF_MIPS_ADDR	 0x40000000
+#define SHF_MIPS_STRINGS 0x80000000
+#define SHF_MIPS_NOSTRIP 0x08000000
+#define SHF_MIPS_LOCAL	 0x04000000
+#define SHF_MIPS_NAMES	 0x02000000
+#define SHF_MIPS_NODUPE	 0x01000000
+
+
+/* Symbol tables.  */
+
+/* MIPS specific values for `st_other'.  */
+#define STO_MIPS_DEFAULT		0x0
+#define STO_MIPS_INTERNAL		0x1
+#define STO_MIPS_HIDDEN			0x2
+#define STO_MIPS_PROTECTED		0x3
+#define STO_MIPS_SC_ALIGN_UNUSED	0xff
+
+/* MIPS specific values for `st_info'.  */
+#define STB_MIPS_SPLIT_COMMON		13
+
+/* Entries found in sections of type SHT_MIPS_GPTAB.  */
+
+typedef union
+{
+  struct
+    {
+      Elf32_Word gt_current_g_value;	/* -G value used for compilation */
+      Elf32_Word gt_unused;		/* Not used */
+    } gt_header;			/* First entry in section */
+  struct
+    {
+      Elf32_Word gt_g_value;		/* If this value were used for -G */
+      Elf32_Word gt_bytes;		/* This many bytes would be used */
+    } gt_entry;				/* Subsequent entries in section */
+} Elf32_gptab;
+
+/* Entry found in sections of type SHT_MIPS_REGINFO.  */
+
+typedef struct
+{
+  Elf32_Word	ri_gprmask;		/* General registers used */
+  Elf32_Word	ri_cprmask[4];		/* Coprocessor registers used */
+  Elf32_Sword	ri_gp_value;		/* $gp register value */
+} Elf32_RegInfo;
+
+/* Entries found in sections of type SHT_MIPS_OPTIONS.  */
+
+typedef struct
+{
+  unsigned char kind;		/* Determines interpretation of the
+				   variable part of descriptor.  */
+  unsigned char size;		/* Size of descriptor, including header.  */
+  Elf32_Section section;	/* Section header index of section affected,
+				   0 for global options.  */
+  Elf32_Word info;		/* Kind-specific information.  */
+} Elf_Options;
+
+/* Values for `kind' field in Elf_Options.  */
+
+#define ODK_NULL	0	/* Undefined.  */
+#define ODK_REGINFO	1	/* Register usage information.  */
+#define ODK_EXCEPTIONS	2	/* Exception processing options.  */
+#define ODK_PAD		3	/* Section padding options.  */
+#define ODK_HWPATCH	4	/* Hardware workarounds performed */
+#define ODK_FILL	5	/* record the fill value used by the linker. */
+#define ODK_TAGS	6	/* reserve space for desktop tools to write. */
+#define ODK_HWAND	7	/* HW workarounds.  'AND' bits when merging. */
+#define ODK_HWOR	8	/* HW workarounds.  'OR' bits when merging.  */
+
+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
+
+#define OEX_FPU_MIN	0x1f	/* FPE's which MUST be enabled.  */
+#define OEX_FPU_MAX	0x1f00	/* FPE's which MAY be enabled.  */
+#define OEX_PAGE0	0x10000	/* page zero must be mapped.  */
+#define OEX_SMM		0x20000	/* Force sequential memory mode?  */
+#define OEX_FPDBUG	0x40000	/* Force floating point debug mode?  */
+#define OEX_PRECISEFP	OEX_FPDBUG
+#define OEX_DISMISS	0x80000	/* Dismiss invalid address faults?  */
+
+#define OEX_FPU_INVAL	0x10
+#define OEX_FPU_DIV0	0x08
+#define OEX_FPU_OFLO	0x04
+#define OEX_FPU_UFLO	0x02
+#define OEX_FPU_INEX	0x01
+
+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
+
+#define OHW_R4KEOP	0x1	/* R4000 end-of-page patch.  */
+#define OHW_R8KPFETCH	0x2	/* may need R8000 prefetch patch.  */
+#define OHW_R5KEOP	0x4	/* R5000 end-of-page patch.  */
+#define OHW_R5KCVTL	0x8	/* R5000 cvt.[ds].l bug.  clean=1.  */
+
+#define OPAD_PREFIX	0x1
+#define OPAD_POSTFIX	0x2
+#define OPAD_SYMBOL	0x4
+
+/* Entry found in `.options' section.  */
+
+typedef struct
+{
+  Elf32_Word hwp_flags1;	/* Extra flags.  */
+  Elf32_Word hwp_flags2;	/* Extra flags.  */
+} Elf_Options_Hw;
+
+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
+
+#define OHWA0_R4KEOP_CHECKED	0x00000001
+#define OHWA1_R4KEOP_CLEAN	0x00000002
+
+/* MIPS relocs.  */
+
+#define R_MIPS_NONE		0	/* No reloc */
+#define R_MIPS_16		1	/* Direct 16 bit */
+#define R_MIPS_32		2	/* Direct 32 bit */
+#define R_MIPS_REL32		3	/* PC relative 32 bit */
+#define R_MIPS_26		4	/* Direct 26 bit shifted */
+#define R_MIPS_HI16		5	/* High 16 bit */
+#define R_MIPS_LO16		6	/* Low 16 bit */
+#define R_MIPS_GPREL16		7	/* GP relative 16 bit */
+#define R_MIPS_LITERAL		8	/* 16 bit literal entry */
+#define R_MIPS_GOT16		9	/* 16 bit GOT entry */
+#define R_MIPS_PC16		10	/* PC relative 16 bit */
+#define R_MIPS_CALL16		11	/* 16 bit GOT entry for function */
+#define R_MIPS_GPREL32		12	/* GP relative 32 bit */
+
+#define R_MIPS_SHIFT5		16
+#define R_MIPS_SHIFT6		17
+#define R_MIPS_64		18
+#define R_MIPS_GOT_DISP		19
+#define R_MIPS_GOT_PAGE		20
+#define R_MIPS_GOT_OFST		21
+#define R_MIPS_GOT_HI16		22
+#define R_MIPS_GOT_LO16		23
+#define R_MIPS_SUB		24
+#define R_MIPS_INSERT_A		25
+#define R_MIPS_INSERT_B		26
+#define R_MIPS_DELETE		27
+#define R_MIPS_HIGHER		28
+#define R_MIPS_HIGHEST		29
+#define R_MIPS_CALL_HI16	30
+#define R_MIPS_CALL_LO16	31
+#define R_MIPS_SCN_DISP		32
+#define R_MIPS_REL16		33
+#define R_MIPS_ADD_IMMEDIATE	34
+#define R_MIPS_PJUMP		35
+#define R_MIPS_RELGOT		36
+#define R_MIPS_JALR		37
+#define R_MIPS_TLS_DTPMOD32	38	/* Module number 32 bit */
+#define R_MIPS_TLS_DTPREL32	39	/* Module-relative offset 32 bit */
+#define R_MIPS_TLS_DTPMOD64	40	/* Module number 64 bit */
+#define R_MIPS_TLS_DTPREL64	41	/* Module-relative offset 64 bit */
+#define R_MIPS_TLS_GD		42	/* 16 bit GOT offset for GD */
+#define R_MIPS_TLS_LDM		43	/* 16 bit GOT offset for LDM */
+#define R_MIPS_TLS_DTPREL_HI16	44	/* Module-relative offset, high 16 bits */
+#define R_MIPS_TLS_DTPREL_LO16	45	/* Module-relative offset, low 16 bits */
+#define R_MIPS_TLS_GOTTPREL	46	/* 16 bit GOT offset for IE */
+#define R_MIPS_TLS_TPREL32	47	/* TP-relative offset, 32 bit */
+#define R_MIPS_TLS_TPREL64	48	/* TP-relative offset, 64 bit */
+#define R_MIPS_TLS_TPREL_HI16	49	/* TP-relative offset, high 16 bits */
+#define R_MIPS_TLS_TPREL_LO16	50	/* TP-relative offset, low 16 bits */
+/* Keep this the last entry.  */
+#define R_MIPS_NUM		51
+
+/* Legal values for p_type field of Elf32_Phdr.  */
+
+#define PT_MIPS_REGINFO	0x70000000	/* Register usage information */
+#define PT_MIPS_RTPROC  0x70000001	/* Runtime procedure table. */
+#define PT_MIPS_OPTIONS 0x70000002
+
+/* Special program header types.  */
+
+#define PF_MIPS_LOCAL	0x10000000
+
+/* Legal values for d_tag field of Elf32_Dyn.  */
+
+#define DT_MIPS_RLD_VERSION  0x70000001	/* Runtime linker interface version */
+#define DT_MIPS_TIME_STAMP   0x70000002	/* Timestamp */
+#define DT_MIPS_ICHECKSUM    0x70000003	/* Checksum */
+#define DT_MIPS_IVERSION     0x70000004	/* Version string (string tbl index) */
+#define DT_MIPS_FLAGS	     0x70000005	/* Flags */
+#define DT_MIPS_BASE_ADDRESS 0x70000006	/* Base address */
+#define DT_MIPS_MSYM	     0x70000007
+#define DT_MIPS_CONFLICT     0x70000008	/* Address of CONFLICT section */
+#define DT_MIPS_LIBLIST	     0x70000009	/* Address of LIBLIST section */
+#define DT_MIPS_LOCAL_GOTNO  0x7000000a	/* Number of local GOT entries */
+#define DT_MIPS_CONFLICTNO   0x7000000b	/* Number of CONFLICT entries */
+#define DT_MIPS_LIBLISTNO    0x70000010	/* Number of LIBLIST entries */
+#define DT_MIPS_SYMTABNO     0x70000011	/* Number of DYNSYM entries */
+#define DT_MIPS_UNREFEXTNO   0x70000012	/* First external DYNSYM */
+#define DT_MIPS_GOTSYM	     0x70000013	/* First GOT entry in DYNSYM */
+#define DT_MIPS_HIPAGENO     0x70000014	/* Number of GOT page table entries */
+#define DT_MIPS_RLD_MAP	     0x70000016	/* Address of run time loader map.  */
+#define DT_MIPS_DELTA_CLASS  0x70000017	/* Delta C++ class definition.  */
+#define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
+						DT_MIPS_DELTA_CLASS.  */
+#define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
+						DT_MIPS_DELTA_INSTANCE.  */
+#define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
+					     DT_MIPS_DELTA_RELOC.  */
+#define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
+					   relocations refer to.  */
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
+					   DT_MIPS_DELTA_SYM.  */
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
+					     class declaration.  */
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
+						DT_MIPS_DELTA_CLASSSYM.  */
+#define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
+#define DT_MIPS_PIXIE_INIT   0x70000023
+#define DT_MIPS_SYMBOL_LIB   0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS	     0x70000029 /* Address of .options.  */
+#define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
+						    function stored in GOT.  */
+#define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
+					   by rld on dlopen() calls.  */
+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
+#define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
+#define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
+#define DT_MIPS_NUM	     0x32
+
+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
+
+#define RHF_NONE		   0		/* No flags */
+#define RHF_QUICKSTART		   (1 << 0)	/* Use quickstart */
+#define RHF_NOTPOT		   (1 << 1)	/* Hash size not power of 2 */
+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)	/* Ignore LD_LIBRARY_PATH */
+#define RHF_NO_MOVE		   (1 << 3)
+#define RHF_SGI_ONLY		   (1 << 4)
+#define RHF_GUARANTEE_INIT	   (1 << 5)
+#define RHF_DELTA_C_PLUS_PLUS	   (1 << 6)
+#define RHF_GUARANTEE_START_INIT   (1 << 7)
+#define RHF_PIXIE		   (1 << 8)
+#define RHF_DEFAULT_DELAY_LOAD	   (1 << 9)
+#define RHF_REQUICKSTART	   (1 << 10)
+#define RHF_REQUICKSTARTED	   (1 << 11)
+#define RHF_CORD		   (1 << 12)
+#define RHF_NO_UNRES_UNDEF	   (1 << 13)
+#define RHF_RLD_ORDER_SAFE	   (1 << 14)
+
+/* Entries found in sections of type SHT_MIPS_LIBLIST.  */
+
+typedef struct
+{
+  Elf32_Word l_name;		/* Name (string table index) */
+  Elf32_Word l_time_stamp;	/* Timestamp */
+  Elf32_Word l_checksum;	/* Checksum */
+  Elf32_Word l_version;		/* Interface version */
+  Elf32_Word l_flags;		/* Flags */
+} Elf32_Lib;
+
+typedef struct
+{
+  Elf64_Word l_name;		/* Name (string table index) */
+  Elf64_Word l_time_stamp;	/* Timestamp */
+  Elf64_Word l_checksum;	/* Checksum */
+  Elf64_Word l_version;		/* Interface version */
+  Elf64_Word l_flags;		/* Flags */
+} Elf64_Lib;
+
+
+/* Legal values for l_flags.  */
+
+#define LL_NONE		  0
+#define LL_EXACT_MATCH	  (1 << 0)	/* Require exact match */
+#define LL_IGNORE_INT_VER (1 << 1)	/* Ignore interface version */
+#define LL_REQUIRE_MINOR  (1 << 2)
+#define LL_EXPORTS	  (1 << 3)
+#define LL_DELAY_LOAD	  (1 << 4)
+#define LL_DELTA	  (1 << 5)
+
+/* Entries found in sections of type SHT_MIPS_CONFLICT.  */
+
+typedef Elf32_Addr Elf32_Conflict;
+
+
+/* HPPA specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_PARISC_TRAPNIL	0x00010000 /* Trap nil pointer dereference.  */
+#define EF_PARISC_EXT		0x00020000 /* Program uses arch. extensions. */
+#define EF_PARISC_LSB		0x00040000 /* Program expects little endian. */
+#define EF_PARISC_WIDE		0x00080000 /* Program expects wide mode.  */
+#define EF_PARISC_NO_KABP	0x00100000 /* No kernel assisted branch
+					      prediction.  */
+#define EF_PARISC_LAZYSWAP	0x00400000 /* Allow lazy swapping.  */
+#define EF_PARISC_ARCH		0x0000ffff /* Architecture version.  */
+
+/* Defined values for `e_flags & EF_PARISC_ARCH' are:  */
+
+#define EFA_PARISC_1_0		    0x020b /* PA-RISC 1.0 big-endian.  */
+#define EFA_PARISC_1_1		    0x0210 /* PA-RISC 1.1 big-endian.  */
+#define EFA_PARISC_2_0		    0x0214 /* PA-RISC 2.0 big-endian.  */
+
+/* Additional section indeces.  */
+
+#define SHN_PARISC_ANSI_COMMON	0xff00	   /* Section for tenatively declared
+					      symbols in ANSI C.  */
+#define SHN_PARISC_HUGE_COMMON	0xff01	   /* Common blocks in huge model.  */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_PARISC_EXT		0x70000000 /* Contains product specific ext. */
+#define SHT_PARISC_UNWIND	0x70000001 /* Unwind information.  */
+#define SHT_PARISC_DOC		0x70000002 /* Debug info for optimized code. */
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_PARISC_SHORT	0x20000000 /* Section with short addressing. */
+#define SHF_PARISC_HUGE		0x40000000 /* Section far from gp.  */
+#define SHF_PARISC_SBP		0x80000000 /* Static branch prediction code. */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_PARISC_MILLICODE	13	/* Millicode function entry point.  */
+
+#define STT_HP_OPAQUE		(STT_LOOS + 0x1)
+#define STT_HP_STUB		(STT_LOOS + 0x2)
+
+/* HPPA relocs.  */
+
+#define R_PARISC_NONE		0	/* No reloc.  */
+#define R_PARISC_DIR32		1	/* Direct 32-bit reference.  */
+#define R_PARISC_DIR21L		2	/* Left 21 bits of eff. address.  */
+#define R_PARISC_DIR17R		3	/* Right 17 bits of eff. address.  */
+#define R_PARISC_DIR17F		4	/* 17 bits of eff. address.  */
+#define R_PARISC_DIR14R		6	/* Right 14 bits of eff. address.  */
+#define R_PARISC_PCREL32	9	/* 32-bit rel. address.  */
+#define R_PARISC_PCREL21L	10	/* Left 21 bits of rel. address.  */
+#define R_PARISC_PCREL17R	11	/* Right 17 bits of rel. address.  */
+#define R_PARISC_PCREL17F	12	/* 17 bits of rel. address.  */
+#define R_PARISC_PCREL14R	14	/* Right 14 bits of rel. address.  */
+#define R_PARISC_DPREL21L	18	/* Left 21 bits of rel. address.  */
+#define R_PARISC_DPREL14R	22	/* Right 14 bits of rel. address.  */
+#define R_PARISC_GPREL21L	26	/* GP-relative, left 21 bits.  */
+#define R_PARISC_GPREL14R	30	/* GP-relative, right 14 bits.  */
+#define R_PARISC_LTOFF21L	34	/* LT-relative, left 21 bits.  */
+#define R_PARISC_LTOFF14R	38	/* LT-relative, right 14 bits.  */
+#define R_PARISC_SECREL32	41	/* 32 bits section rel. address.  */
+#define R_PARISC_SEGBASE	48	/* No relocation, set segment base.  */
+#define R_PARISC_SEGREL32	49	/* 32 bits segment rel. address.  */
+#define R_PARISC_PLTOFF21L	50	/* PLT rel. address, left 21 bits.  */
+#define R_PARISC_PLTOFF14R	54	/* PLT rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_FPTR32	57	/* 32 bits LT-rel. function pointer. */
+#define R_PARISC_LTOFF_FPTR21L	58	/* LT-rel. fct ptr, left 21 bits. */
+#define R_PARISC_LTOFF_FPTR14R	62	/* LT-rel. fct ptr, right 14 bits. */
+#define R_PARISC_FPTR64		64	/* 64 bits function address.  */
+#define R_PARISC_PLABEL32	65	/* 32 bits function address.  */
+#define R_PARISC_PCREL64	72	/* 64 bits PC-rel. address.  */
+#define R_PARISC_PCREL22F	74	/* 22 bits PC-rel. address.  */
+#define R_PARISC_PCREL14WR	75	/* PC-rel. address, right 14 bits.  */
+#define R_PARISC_PCREL14DR	76	/* PC rel. address, right 14 bits.  */
+#define R_PARISC_PCREL16F	77	/* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16WF	78	/* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16DF	79	/* 16 bits PC-rel. address.  */
+#define R_PARISC_DIR64		80	/* 64 bits of eff. address.  */
+#define R_PARISC_DIR14WR	83	/* 14 bits of eff. address.  */
+#define R_PARISC_DIR14DR	84	/* 14 bits of eff. address.  */
+#define R_PARISC_DIR16F		85	/* 16 bits of eff. address.  */
+#define R_PARISC_DIR16WF	86	/* 16 bits of eff. address.  */
+#define R_PARISC_DIR16DF	87	/* 16 bits of eff. address.  */
+#define R_PARISC_GPREL64	88	/* 64 bits of GP-rel. address.  */
+#define R_PARISC_GPREL14WR	91	/* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL14DR	92	/* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL16F	93	/* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16WF	94	/* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16DF	95	/* 16 bits GP-rel. address.  */
+#define R_PARISC_LTOFF64	96	/* 64 bits LT-rel. address.  */
+#define R_PARISC_LTOFF14WR	99	/* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF14DR	100	/* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF16F	101	/* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16WF	102	/* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16DF	103	/* 16 bits LT-rel. address.  */
+#define R_PARISC_SECREL64	104	/* 64 bits section rel. address.  */
+#define R_PARISC_SEGREL64	112	/* 64 bits segment rel. address.  */
+#define R_PARISC_PLTOFF14WR	115	/* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF14DR	116	/* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF16F	117	/* 16 bits LT-rel. address.  */
+#define R_PARISC_PLTOFF16WF	118	/* 16 bits PLT-rel. address.  */
+#define R_PARISC_PLTOFF16DF	119	/* 16 bits PLT-rel. address.  */
+#define R_PARISC_LTOFF_FPTR64	120	/* 64 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR14WR	123	/* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR14DR	124	/* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR16F	125	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16WF	126	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16DF	127	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LORESERVE	128
+#define R_PARISC_COPY		128	/* Copy relocation.  */
+#define R_PARISC_IPLT		129	/* Dynamic reloc, imported PLT */
+#define R_PARISC_EPLT		130	/* Dynamic reloc, exported PLT */
+#define R_PARISC_TPREL32	153	/* 32 bits TP-rel. address.  */
+#define R_PARISC_TPREL21L	154	/* TP-rel. address, left 21 bits.  */
+#define R_PARISC_TPREL14R	158	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_TP21L	162	/* LT-TP-rel. address, left 21 bits. */
+#define R_PARISC_LTOFF_TP14R	166	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14F	167	/* 14 bits LT-TP-rel. address.  */
+#define R_PARISC_TPREL64	216	/* 64 bits TP-rel. address.  */
+#define R_PARISC_TPREL14WR	219	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL14DR	220	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL16F	221	/* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16WF	222	/* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16DF	223	/* 16 bits TP-rel. address.  */
+#define R_PARISC_LTOFF_TP64	224	/* 64 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP14WR	227	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14DR	228	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP16F	229	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16WF	230	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16DF	231	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_HIRESERVE	255
+
+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PT_HP_TLS		(PT_LOOS + 0x0)
+#define PT_HP_CORE_NONE		(PT_LOOS + 0x1)
+#define PT_HP_CORE_VERSION	(PT_LOOS + 0x2)
+#define PT_HP_CORE_KERNEL	(PT_LOOS + 0x3)
+#define PT_HP_CORE_COMM		(PT_LOOS + 0x4)
+#define PT_HP_CORE_PROC		(PT_LOOS + 0x5)
+#define PT_HP_CORE_LOADABLE	(PT_LOOS + 0x6)
+#define PT_HP_CORE_STACK	(PT_LOOS + 0x7)
+#define PT_HP_CORE_SHM		(PT_LOOS + 0x8)
+#define PT_HP_CORE_MMF		(PT_LOOS + 0x9)
+#define PT_HP_PARALLEL		(PT_LOOS + 0x10)
+#define PT_HP_FASTBIND		(PT_LOOS + 0x11)
+#define PT_HP_OPT_ANNOT		(PT_LOOS + 0x12)
+#define PT_HP_HSL_ANNOT		(PT_LOOS + 0x13)
+#define PT_HP_STACK		(PT_LOOS + 0x14)
+
+#define PT_PARISC_ARCHEXT	0x70000000
+#define PT_PARISC_UNWIND	0x70000001
+
+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PF_PARISC_SBP		0x08000000
+
+#define PF_HP_PAGE_SIZE		0x00100000
+#define PF_HP_FAR_SHARED	0x00200000
+#define PF_HP_NEAR_SHARED	0x00400000
+#define PF_HP_CODE		0x01000000
+#define PF_HP_MODIFY		0x02000000
+#define PF_HP_LAZYSWAP		0x04000000
+#define PF_HP_SBP		0x08000000
+
+
+/* Alpha specific definitions.  */
+
+/* Legal values for e_flags field of Elf64_Ehdr.  */
+
+#define EF_ALPHA_32BIT		1	/* All addresses must be < 2GB.  */
+#define EF_ALPHA_CANRELAX	2	/* Relocations for relaxing exist.  */
+
+/* Legal values for sh_type field of Elf64_Shdr.  */
+
+/* These two are primerily concerned with ECOFF debugging info.  */
+#define SHT_ALPHA_DEBUG		0x70000001
+#define SHT_ALPHA_REGINFO	0x70000002
+
+/* Legal values for sh_flags field of Elf64_Shdr.  */
+
+#define SHF_ALPHA_GPREL		0x10000000
+
+/* Legal values for st_other field of Elf64_Sym.  */
+#define STO_ALPHA_NOPV		0x80	/* No PV required.  */
+#define STO_ALPHA_STD_GPLOAD	0x88	/* PV only used for initial ldgp.  */
+
+/* Alpha relocs.  */
+
+#define R_ALPHA_NONE		0	/* No reloc */
+#define R_ALPHA_REFLONG		1	/* Direct 32 bit */
+#define R_ALPHA_REFQUAD		2	/* Direct 64 bit */
+#define R_ALPHA_GPREL32		3	/* GP relative 32 bit */
+#define R_ALPHA_LITERAL		4	/* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE		5	/* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP		6	/* Add displacement to GP */
+#define R_ALPHA_BRADDR		7	/* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT		8	/* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16		9	/* PC relative 16 bit */
+#define R_ALPHA_SREL32		10	/* PC relative 32 bit */
+#define R_ALPHA_SREL64		11	/* PC relative 64 bit */
+#define R_ALPHA_GPRELHIGH	17	/* GP relative 32 bit, high 16 bits */
+#define R_ALPHA_GPRELLOW	18	/* GP relative 32 bit, low 16 bits */
+#define R_ALPHA_GPREL16		19	/* GP relative 16 bit */
+#define R_ALPHA_COPY		24	/* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT	25	/* Create GOT entry */
+#define R_ALPHA_JMP_SLOT	26	/* Create PLT entry */
+#define R_ALPHA_RELATIVE	27	/* Adjust by program base */
+#define R_ALPHA_TLS_GD_HI	28
+#define R_ALPHA_TLSGD		29
+#define R_ALPHA_TLS_LDM		30
+#define R_ALPHA_DTPMOD64	31
+#define R_ALPHA_GOTDTPREL	32
+#define R_ALPHA_DTPREL64	33
+#define R_ALPHA_DTPRELHI	34
+#define R_ALPHA_DTPRELLO	35
+#define R_ALPHA_DTPREL16	36
+#define R_ALPHA_GOTTPREL	37
+#define R_ALPHA_TPREL64		38
+#define R_ALPHA_TPRELHI		39
+#define R_ALPHA_TPRELLO		40
+#define R_ALPHA_TPREL16		41
+/* Keep this the last entry.  */
+#define R_ALPHA_NUM		46
+
+/* Magic values of the LITUSE relocation addend.  */
+#define LITUSE_ALPHA_ADDR	0
+#define LITUSE_ALPHA_BASE	1
+#define LITUSE_ALPHA_BYTOFF	2
+#define LITUSE_ALPHA_JSR	3
+#define LITUSE_ALPHA_TLS_GD	4
+#define LITUSE_ALPHA_TLS_LDM	5
+
+
+/* PowerPC specific declarations */
+
+/* Values for Elf32/64_Ehdr.e_flags.  */
+#define EF_PPC_EMB		0x80000000	/* PowerPC embedded flag */
+
+/* Cygnus local bits below */
+#define EF_PPC_RELOCATABLE	0x00010000	/* PowerPC -mrelocatable flag*/
+#define EF_PPC_RELOCATABLE_LIB	0x00008000	/* PowerPC -mrelocatable-lib
+						   flag */
+
+/* PowerPC relocations defined by the ABIs */
+#define R_PPC_NONE		0
+#define R_PPC_ADDR32		1	/* 32bit absolute address */
+#define R_PPC_ADDR24		2	/* 26bit address, 2 bits ignored.  */
+#define R_PPC_ADDR16		3	/* 16bit absolute address */
+#define R_PPC_ADDR16_LO		4	/* lower 16bit of absolute address */
+#define R_PPC_ADDR16_HI		5	/* high 16bit of absolute address */
+#define R_PPC_ADDR16_HA		6	/* adjusted high 16bit */
+#define R_PPC_ADDR14		7	/* 16bit address, 2 bits ignored */
+#define R_PPC_ADDR14_BRTAKEN	8
+#define R_PPC_ADDR14_BRNTAKEN	9
+#define R_PPC_REL24		10	/* PC relative 26 bit */
+#define R_PPC_REL14		11	/* PC relative 16 bit */
+#define R_PPC_REL14_BRTAKEN	12
+#define R_PPC_REL14_BRNTAKEN	13
+#define R_PPC_GOT16		14
+#define R_PPC_GOT16_LO		15
+#define R_PPC_GOT16_HI		16
+#define R_PPC_GOT16_HA		17
+#define R_PPC_PLTREL24		18
+#define R_PPC_COPY		19
+#define R_PPC_GLOB_DAT		20
+#define R_PPC_JMP_SLOT		21
+#define R_PPC_RELATIVE		22
+#define R_PPC_LOCAL24PC		23
+#define R_PPC_UADDR32		24
+#define R_PPC_UADDR16		25
+#define R_PPC_REL32		26
+#define R_PPC_PLT32		27
+#define R_PPC_PLTREL32		28
+#define R_PPC_PLT16_LO		29
+#define R_PPC_PLT16_HI		30
+#define R_PPC_PLT16_HA		31
+#define R_PPC_SDAREL16		32
+#define R_PPC_SECTOFF		33
+#define R_PPC_SECTOFF_LO	34
+#define R_PPC_SECTOFF_HI	35
+#define R_PPC_SECTOFF_HA	36
+
+/* PowerPC relocations defined for the TLS access ABI.  */
+#define R_PPC_TLS		67 /* none	(sym+add)@tls */
+#define R_PPC_DTPMOD32		68 /* word32	(sym+add)@dtpmod */
+#define R_PPC_TPREL16		69 /* half16*	(sym+add)@tprel */
+#define R_PPC_TPREL16_LO	70 /* half16	(sym+add)@tprel@l */
+#define R_PPC_TPREL16_HI	71 /* half16	(sym+add)@tprel@h */
+#define R_PPC_TPREL16_HA	72 /* half16	(sym+add)@tprel@ha */
+#define R_PPC_TPREL32		73 /* word32	(sym+add)@tprel */
+#define R_PPC_DTPREL16		74 /* half16*	(sym+add)@dtprel */
+#define R_PPC_DTPREL16_LO	75 /* half16	(sym+add)@dtprel@l */
+#define R_PPC_DTPREL16_HI	76 /* half16	(sym+add)@dtprel@h */
+#define R_PPC_DTPREL16_HA	77 /* half16	(sym+add)@dtprel@ha */
+#define R_PPC_DTPREL32		78 /* word32	(sym+add)@dtprel */
+#define R_PPC_GOT_TLSGD16	79 /* half16*	(sym+add)@got@tlsgd */
+#define R_PPC_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got@tlsgd@l */
+#define R_PPC_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got@tlsgd@h */
+#define R_PPC_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got@tlsgd@ha */
+#define R_PPC_GOT_TLSLD16	83 /* half16*	(sym+add)@got@tlsld */
+#define R_PPC_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got@tlsld@l */
+#define R_PPC_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got@tlsld@h */
+#define R_PPC_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got@tlsld@ha */
+#define R_PPC_GOT_TPREL16	87 /* half16*	(sym+add)@got@tprel */
+#define R_PPC_GOT_TPREL16_LO	88 /* half16	(sym+add)@got@tprel@l */
+#define R_PPC_GOT_TPREL16_HI	89 /* half16	(sym+add)@got@tprel@h */
+#define R_PPC_GOT_TPREL16_HA	90 /* half16	(sym+add)@got@tprel@ha */
+#define R_PPC_GOT_DTPREL16	91 /* half16*	(sym+add)@got@dtprel */
+#define R_PPC_GOT_DTPREL16_LO	92 /* half16*	(sym+add)@got@dtprel@l */
+#define R_PPC_GOT_DTPREL16_HI	93 /* half16*	(sym+add)@got@dtprel@h */
+#define R_PPC_GOT_DTPREL16_HA	94 /* half16*	(sym+add)@got@dtprel@ha */
+
+/* Keep this the last entry.  */
+#define R_PPC_NUM		95
+
+/* The remaining relocs are from the Embedded ELF ABI, and are not
+   in the SVR4 ELF ABI.  */
+#define R_PPC_EMB_NADDR32	101
+#define R_PPC_EMB_NADDR16	102
+#define R_PPC_EMB_NADDR16_LO	103
+#define R_PPC_EMB_NADDR16_HI	104
+#define R_PPC_EMB_NADDR16_HA	105
+#define R_PPC_EMB_SDAI16	106
+#define R_PPC_EMB_SDA2I16	107
+#define R_PPC_EMB_SDA2REL	108
+#define R_PPC_EMB_SDA21		109	/* 16 bit offset in SDA */
+#define R_PPC_EMB_MRKREF	110
+#define R_PPC_EMB_RELSEC16	111
+#define R_PPC_EMB_RELST_LO	112
+#define R_PPC_EMB_RELST_HI	113
+#define R_PPC_EMB_RELST_HA	114
+#define R_PPC_EMB_BIT_FLD	115
+#define R_PPC_EMB_RELSDA	116	/* 16 bit relative offset in SDA */
+
+/* Diab tool relocations.  */
+#define R_PPC_DIAB_SDA21_LO	180	/* like EMB_SDA21, but lower 16 bit */
+#define R_PPC_DIAB_SDA21_HI	181	/* like EMB_SDA21, but high 16 bit */
+#define R_PPC_DIAB_SDA21_HA	182	/* like EMB_SDA21, adjusted high 16 */
+#define R_PPC_DIAB_RELSDA_LO	183	/* like EMB_RELSDA, but lower 16 bit */
+#define R_PPC_DIAB_RELSDA_HI	184	/* like EMB_RELSDA, but high 16 bit */
+#define R_PPC_DIAB_RELSDA_HA	185	/* like EMB_RELSDA, adjusted high 16 */
+
+/* This is a phony reloc to handle any old fashioned TOC16 references
+   that may still be in object files.  */
+#define R_PPC_TOC16		255
+
+
+/* PowerPC64 relocations defined by the ABIs */
+#define R_PPC64_NONE		R_PPC_NONE
+#define R_PPC64_ADDR32		R_PPC_ADDR32 /* 32bit absolute address */
+#define R_PPC64_ADDR24		R_PPC_ADDR24 /* 26bit address, word aligned */
+#define R_PPC64_ADDR16		R_PPC_ADDR16 /* 16bit absolute address */
+#define R_PPC64_ADDR16_LO	R_PPC_ADDR16_LO	/* lower 16bits of address */
+#define R_PPC64_ADDR16_HI	R_PPC_ADDR16_HI	/* high 16bits of address. */
+#define R_PPC64_ADDR16_HA	R_PPC_ADDR16_HA /* adjusted high 16bits.  */
+#define R_PPC64_ADDR14		R_PPC_ADDR14 /* 16bit address, word aligned */
+#define R_PPC64_ADDR14_BRTAKEN	R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN	R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24		R_PPC_REL24 /* PC-rel. 26 bit, word aligned */
+#define R_PPC64_REL14		R_PPC_REL14 /* PC relative 16 bit */
+#define R_PPC64_REL14_BRTAKEN	R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN	R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16		R_PPC_GOT16
+#define R_PPC64_GOT16_LO	R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI	R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA	R_PPC_GOT16_HA
+
+#define R_PPC64_COPY		R_PPC_COPY
+#define R_PPC64_GLOB_DAT	R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT	R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE	R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32		R_PPC_UADDR32
+#define R_PPC64_UADDR16		R_PPC_UADDR16
+#define R_PPC64_REL32		R_PPC_REL32
+#define R_PPC64_PLT32		R_PPC_PLT32
+#define R_PPC64_PLTREL32	R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO	R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI	R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA	R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF		R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO	R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI	R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA	R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30		37 /* word30 (S + A - P) >> 2 */
+#define R_PPC64_ADDR64		38 /* doubleword64 S + A */
+#define R_PPC64_ADDR16_HIGHER	39 /* half16 #higher(S + A) */
+#define R_PPC64_ADDR16_HIGHERA	40 /* half16 #highera(S + A) */
+#define R_PPC64_ADDR16_HIGHEST	41 /* half16 #highest(S + A) */
+#define R_PPC64_ADDR16_HIGHESTA	42 /* half16 #highesta(S + A) */
+#define R_PPC64_UADDR64		43 /* doubleword64 S + A */
+#define R_PPC64_REL64		44 /* doubleword64 S + A - P */
+#define R_PPC64_PLT64		45 /* doubleword64 L + A */
+#define R_PPC64_PLTREL64	46 /* doubleword64 L + A - P */
+#define R_PPC64_TOC16		47 /* half16* S + A - .TOC */
+#define R_PPC64_TOC16_LO	48 /* half16 #lo(S + A - .TOC.) */
+#define R_PPC64_TOC16_HI	49 /* half16 #hi(S + A - .TOC.) */
+#define R_PPC64_TOC16_HA	50 /* half16 #ha(S + A - .TOC.) */
+#define R_PPC64_TOC		51 /* doubleword64 .TOC */
+#define R_PPC64_PLTGOT16	52 /* half16* M + A */
+#define R_PPC64_PLTGOT16_LO	53 /* half16 #lo(M + A) */
+#define R_PPC64_PLTGOT16_HI	54 /* half16 #hi(M + A) */
+#define R_PPC64_PLTGOT16_HA	55 /* half16 #ha(M + A) */
+
+#define R_PPC64_ADDR16_DS	56 /* half16ds* (S + A) >> 2 */
+#define R_PPC64_ADDR16_LO_DS	57 /* half16ds  #lo(S + A) >> 2 */
+#define R_PPC64_GOT16_DS	58 /* half16ds* (G + A) >> 2 */
+#define R_PPC64_GOT16_LO_DS	59 /* half16ds  #lo(G + A) >> 2 */
+#define R_PPC64_PLT16_LO_DS	60 /* half16ds  #lo(L + A) >> 2 */
+#define R_PPC64_SECTOFF_DS	61 /* half16ds* (R + A) >> 2 */
+#define R_PPC64_SECTOFF_LO_DS	62 /* half16ds  #lo(R + A) >> 2 */
+#define R_PPC64_TOC16_DS	63 /* half16ds* (S + A - .TOC.) >> 2 */
+#define R_PPC64_TOC16_LO_DS	64 /* half16ds  #lo(S + A - .TOC.) >> 2 */
+#define R_PPC64_PLTGOT16_DS	65 /* half16ds* (M + A) >> 2 */
+#define R_PPC64_PLTGOT16_LO_DS	66 /* half16ds  #lo(M + A) >> 2 */
+
+/* PowerPC64 relocations defined for the TLS access ABI.  */
+#define R_PPC64_TLS		67 /* none	(sym+add)@tls */
+#define R_PPC64_DTPMOD64	68 /* doubleword64 (sym+add)@dtpmod */
+#define R_PPC64_TPREL16		69 /* half16*	(sym+add)@tprel */
+#define R_PPC64_TPREL16_LO	70 /* half16	(sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HI	71 /* half16	(sym+add)@tprel@h */
+#define R_PPC64_TPREL16_HA	72 /* half16	(sym+add)@tprel@ha */
+#define R_PPC64_TPREL64		73 /* doubleword64 (sym+add)@tprel */
+#define R_PPC64_DTPREL16	74 /* half16*	(sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO	75 /* half16	(sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HI	76 /* half16	(sym+add)@dtprel@h */
+#define R_PPC64_DTPREL16_HA	77 /* half16	(sym+add)@dtprel@ha */
+#define R_PPC64_DTPREL64	78 /* doubleword64 (sym+add)@dtprel */
+#define R_PPC64_GOT_TLSGD16	79 /* half16*	(sym+add)@got@tlsgd */
+#define R_PPC64_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got@tlsgd@l */
+#define R_PPC64_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got@tlsgd@h */
+#define R_PPC64_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got@tlsgd@ha */
+#define R_PPC64_GOT_TLSLD16	83 /* half16*	(sym+add)@got@tlsld */
+#define R_PPC64_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got@tlsld@l */
+#define R_PPC64_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got@tlsld@h */
+#define R_PPC64_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got@tlsld@ha */
+#define R_PPC64_GOT_TPREL16_DS	87 /* half16ds*	(sym+add)@got@tprel */
+#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
+#define R_PPC64_GOT_TPREL16_HI	89 /* half16	(sym+add)@got@tprel@h */
+#define R_PPC64_GOT_TPREL16_HA	90 /* half16	(sym+add)@got@tprel@ha */
+#define R_PPC64_GOT_DTPREL16_DS	91 /* half16ds*	(sym+add)@got@dtprel */
+#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
+#define R_PPC64_GOT_DTPREL16_HI	93 /* half16	(sym+add)@got@dtprel@h */
+#define R_PPC64_GOT_DTPREL16_HA	94 /* half16	(sym+add)@got@dtprel@ha */
+#define R_PPC64_TPREL16_DS	95 /* half16ds*	(sym+add)@tprel */
+#define R_PPC64_TPREL16_LO_DS	96 /* half16ds	(sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HIGHER	97 /* half16	(sym+add)@tprel@higher */
+#define R_PPC64_TPREL16_HIGHERA	98 /* half16	(sym+add)@tprel@highera */
+#define R_PPC64_TPREL16_HIGHEST	99 /* half16	(sym+add)@tprel@highest */
+#define R_PPC64_TPREL16_HIGHESTA 100 /* half16	(sym+add)@tprel@highesta */
+#define R_PPC64_DTPREL16_DS	101 /* half16ds* (sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO_DS	102 /* half16ds	(sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HIGHER	103 /* half16	(sym+add)@dtprel@higher */
+#define R_PPC64_DTPREL16_HIGHERA 104 /* half16	(sym+add)@dtprel@highera */
+#define R_PPC64_DTPREL16_HIGHEST 105 /* half16	(sym+add)@dtprel@highest */
+#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16	(sym+add)@dtprel@highesta */
+
+/* Keep this the last entry.  */
+#define R_PPC64_NUM		107
+
+/* PowerPC64 specific values for the Dyn d_tag field.  */
+#define DT_PPC64_GLINK  (DT_LOPROC + 0)
+#define DT_PPC64_OPD	(DT_LOPROC + 1)
+#define DT_PPC64_OPDSZ	(DT_LOPROC + 2)
+#define DT_PPC64_NUM    3
+
+
+/* ARM specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+#define EF_ARM_RELEXEC     0x01
+#define EF_ARM_HASENTRY    0x02
+#define EF_ARM_INTERWORK   0x04
+#define EF_ARM_APCS_26     0x08
+#define EF_ARM_APCS_FLOAT  0x10
+#define EF_ARM_PIC         0x20
+#define EF_ARM_ALIGN8      0x40		/* 8-bit structure alignment is in use */
+#define EF_ARM_NEW_ABI     0x80
+#define EF_ARM_OLD_ABI     0x100
+
+/* Other constants defined in the ARM ELF spec. version B-01.  */
+/* NB. These conflict with values defined above.  */
+#define EF_ARM_SYMSARESORTED	0x04
+#define EF_ARM_DYNSYMSUSESEGIDX 0x08
+#define EF_ARM_MAPSYMSFIRST	0x10
+#define EF_ARM_EABIMASK		0XFF000000
+
+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN  0x00000000
+#define EF_ARM_EABI_VER1     0x01000000
+#define EF_ARM_EABI_VER2     0x02000000
+
+/* Additional symbol types for Thumb */
+#define STT_ARM_TFUNC      0xd
+
+/* ARM-specific values for sh_flags */
+#define SHF_ARM_ENTRYSECT  0x10000000   /* Section contains an entry point */
+#define SHF_ARM_COMDEF     0x80000000   /* Section may be multiply defined
+					   in the input to a link step */
+
+/* ARM-specific program header flags */
+#define PF_ARM_SB          0x10000000   /* Segment contains the location
+					   addressed by the static base */
+
+/* Processor specific values for the Phdr p_type field.  */
+#define PT_ARM_EXIDX	0x70000001	/* .ARM.exidx segment */
+
+/* ARM relocs.  */
+
+#define R_ARM_NONE		0	/* No reloc */
+#define R_ARM_PC24		1	/* PC relative 26 bit branch */
+#define R_ARM_ABS32		2	/* Direct 32 bit  */
+#define R_ARM_REL32		3	/* PC relative 32 bit */
+#define R_ARM_PC13		4
+#define R_ARM_ABS16		5	/* Direct 16 bit */
+#define R_ARM_ABS12		6	/* Direct 12 bit */
+#define R_ARM_THM_ABS5		7
+#define R_ARM_ABS8		8	/* Direct 8 bit */
+#define R_ARM_SBREL32		9
+#define R_ARM_THM_PC22		10
+#define R_ARM_THM_PC8		11
+#define R_ARM_AMP_VCALL9	12
+#define R_ARM_SWI24		13
+#define R_ARM_THM_SWI8		14
+#define R_ARM_XPC25		15
+#define R_ARM_THM_XPC22		16
+#define R_ARM_COPY		20	/* Copy symbol at runtime */
+#define R_ARM_GLOB_DAT		21	/* Create GOT entry */
+#define R_ARM_JUMP_SLOT		22	/* Create PLT entry */
+#define R_ARM_RELATIVE		23	/* Adjust by program base */
+#define R_ARM_GOTOFF		24	/* 32 bit offset to GOT */
+#define R_ARM_GOTPC		25	/* 32 bit PC relative offset to GOT */
+#define R_ARM_GOT32		26	/* 32 bit GOT entry */
+#define R_ARM_PLT32		27	/* 32 bit PLT address */
+#define R_ARM_ALU_PCREL_7_0	32
+#define R_ARM_ALU_PCREL_15_8	33
+#define R_ARM_ALU_PCREL_23_15	34
+#define R_ARM_LDR_SBREL_11_0	35
+#define R_ARM_ALU_SBREL_19_12	36
+#define R_ARM_ALU_SBREL_27_20	37
+#define R_ARM_GNU_VTENTRY	100
+#define R_ARM_GNU_VTINHERIT	101
+#define R_ARM_THM_PC11		102	/* thumb unconditional branch */
+#define R_ARM_THM_PC9		103	/* thumb conditional branch */
+#define R_ARM_RXPC25		249
+#define R_ARM_RSBREL32		250
+#define R_ARM_THM_RPC22		251
+#define R_ARM_RREL32		252
+#define R_ARM_RABS22		253
+#define R_ARM_RPC24		254
+#define R_ARM_RBASE		255
+/* Keep this the last entry.  */
+#define R_ARM_NUM		256
+
+/* IA-64 specific declarations.  */
+
+/* Processor specific flags for the Ehdr e_flags field.  */
+#define EF_IA_64_MASKOS		0x0000000f	/* os-specific flags */
+#define EF_IA_64_ABI64		0x00000010	/* 64-bit ABI */
+#define EF_IA_64_ARCH		0xff000000	/* arch. version mask */
+
+/* Processor specific values for the Phdr p_type field.  */
+#define PT_IA_64_ARCHEXT	(PT_LOPROC + 0)	/* arch extension bits */
+#define PT_IA_64_UNWIND		(PT_LOPROC + 1)	/* ia64 unwind bits */
+#define PT_IA_64_HP_OPT_ANOT	(PT_LOOS + 0x12)
+#define PT_IA_64_HP_HSL_ANOT	(PT_LOOS + 0x13)
+#define PT_IA_64_HP_STACK	(PT_LOOS + 0x14)
+
+/* Processor specific flags for the Phdr p_flags field.  */
+#define PF_IA_64_NORECOV	0x80000000	/* spec insns w/o recovery */
+
+/* Processor specific values for the Shdr sh_type field.  */
+#define SHT_IA_64_EXT		(SHT_LOPROC + 0) /* extension bits */
+#define SHT_IA_64_UNWIND	(SHT_LOPROC + 1) /* unwind bits */
+
+/* Processor specific flags for the Shdr sh_flags field.  */
+#define SHF_IA_64_SHORT		0x10000000	/* section near gp */
+#define SHF_IA_64_NORECOV	0x20000000	/* spec insns w/o recovery */
+
+/* Processor specific values for the Dyn d_tag field.  */
+#define DT_IA_64_PLT_RESERVE	(DT_LOPROC + 0)
+#define DT_IA_64_NUM		1
+
+/* IA-64 relocations.  */
+#define R_IA64_NONE		0x00	/* none */
+#define R_IA64_IMM14		0x21	/* symbol + addend, add imm14 */
+#define R_IA64_IMM22		0x22	/* symbol + addend, add imm22 */
+#define R_IA64_IMM64		0x23	/* symbol + addend, mov imm64 */
+#define R_IA64_DIR32MSB		0x24	/* symbol + addend, data4 MSB */
+#define R_IA64_DIR32LSB		0x25	/* symbol + addend, data4 LSB */
+#define R_IA64_DIR64MSB		0x26	/* symbol + addend, data8 MSB */
+#define R_IA64_DIR64LSB		0x27	/* symbol + addend, data8 LSB */
+#define R_IA64_GPREL22		0x2a	/* @gprel(sym + add), add imm22 */
+#define R_IA64_GPREL64I		0x2b	/* @gprel(sym + add), mov imm64 */
+#define R_IA64_GPREL32MSB	0x2c	/* @gprel(sym + add), data4 MSB */
+#define R_IA64_GPREL32LSB	0x2d	/* @gprel(sym + add), data4 LSB */
+#define R_IA64_GPREL64MSB	0x2e	/* @gprel(sym + add), data8 MSB */
+#define R_IA64_GPREL64LSB	0x2f	/* @gprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF22		0x32	/* @ltoff(sym + add), add imm22 */
+#define R_IA64_LTOFF64I		0x33	/* @ltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF22		0x3a	/* @pltoff(sym + add), add imm22 */
+#define R_IA64_PLTOFF64I	0x3b	/* @pltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF64MSB	0x3e	/* @pltoff(sym + add), data8 MSB */
+#define R_IA64_PLTOFF64LSB	0x3f	/* @pltoff(sym + add), data8 LSB */
+#define R_IA64_FPTR64I		0x43	/* @fptr(sym + add), mov imm64 */
+#define R_IA64_FPTR32MSB	0x44	/* @fptr(sym + add), data4 MSB */
+#define R_IA64_FPTR32LSB	0x45	/* @fptr(sym + add), data4 LSB */
+#define R_IA64_FPTR64MSB	0x46	/* @fptr(sym + add), data8 MSB */
+#define R_IA64_FPTR64LSB	0x47	/* @fptr(sym + add), data8 LSB */
+#define R_IA64_PCREL60B		0x48	/* @pcrel(sym + add), brl */
+#define R_IA64_PCREL21B		0x49	/* @pcrel(sym + add), ptb, call */
+#define R_IA64_PCREL21M		0x4a	/* @pcrel(sym + add), chk.s */
+#define R_IA64_PCREL21F		0x4b	/* @pcrel(sym + add), fchkf */
+#define R_IA64_PCREL32MSB	0x4c	/* @pcrel(sym + add), data4 MSB */
+#define R_IA64_PCREL32LSB	0x4d	/* @pcrel(sym + add), data4 LSB */
+#define R_IA64_PCREL64MSB	0x4e	/* @pcrel(sym + add), data8 MSB */
+#define R_IA64_PCREL64LSB	0x4f	/* @pcrel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_FPTR22	0x52	/* @ltoff(@fptr(s+a)), imm22 */
+#define R_IA64_LTOFF_FPTR64I	0x53	/* @ltoff(@fptr(s+a)), imm64 */
+#define R_IA64_LTOFF_FPTR32MSB	0x54	/* @ltoff(@fptr(s+a)), data4 MSB */
+#define R_IA64_LTOFF_FPTR32LSB	0x55	/* @ltoff(@fptr(s+a)), data4 LSB */
+#define R_IA64_LTOFF_FPTR64MSB	0x56	/* @ltoff(@fptr(s+a)), data8 MSB */
+#define R_IA64_LTOFF_FPTR64LSB	0x57	/* @ltoff(@fptr(s+a)), data8 LSB */
+#define R_IA64_SEGREL32MSB	0x5c	/* @segrel(sym + add), data4 MSB */
+#define R_IA64_SEGREL32LSB	0x5d	/* @segrel(sym + add), data4 LSB */
+#define R_IA64_SEGREL64MSB	0x5e	/* @segrel(sym + add), data8 MSB */
+#define R_IA64_SEGREL64LSB	0x5f	/* @segrel(sym + add), data8 LSB */
+#define R_IA64_SECREL32MSB	0x64	/* @secrel(sym + add), data4 MSB */
+#define R_IA64_SECREL32LSB	0x65	/* @secrel(sym + add), data4 LSB */
+#define R_IA64_SECREL64MSB	0x66	/* @secrel(sym + add), data8 MSB */
+#define R_IA64_SECREL64LSB	0x67	/* @secrel(sym + add), data8 LSB */
+#define R_IA64_REL32MSB		0x6c	/* data 4 + REL */
+#define R_IA64_REL32LSB		0x6d	/* data 4 + REL */
+#define R_IA64_REL64MSB		0x6e	/* data 8 + REL */
+#define R_IA64_REL64LSB		0x6f	/* data 8 + REL */
+#define R_IA64_LTV32MSB		0x74	/* symbol + addend, data4 MSB */
+#define R_IA64_LTV32LSB		0x75	/* symbol + addend, data4 LSB */
+#define R_IA64_LTV64MSB		0x76	/* symbol + addend, data8 MSB */
+#define R_IA64_LTV64LSB		0x77	/* symbol + addend, data8 LSB */
+#define R_IA64_PCREL21BI	0x79	/* @pcrel(sym + add), 21bit inst */
+#define R_IA64_PCREL22		0x7a	/* @pcrel(sym + add), 22bit inst */
+#define R_IA64_PCREL64I		0x7b	/* @pcrel(sym + add), 64bit inst */
+#define R_IA64_IPLTMSB		0x80	/* dynamic reloc, imported PLT, MSB */
+#define R_IA64_IPLTLSB		0x81	/* dynamic reloc, imported PLT, LSB */
+#define R_IA64_COPY		0x84	/* copy relocation */
+#define R_IA64_SUB		0x85	/* Addend and symbol difference */
+#define R_IA64_LTOFF22X		0x86	/* LTOFF22, relaxable.  */
+#define R_IA64_LDXMOV		0x87	/* Use of LTOFF22X.  */
+#define R_IA64_TPREL14		0x91	/* @tprel(sym + add), imm14 */
+#define R_IA64_TPREL22		0x92	/* @tprel(sym + add), imm22 */
+#define R_IA64_TPREL64I		0x93	/* @tprel(sym + add), imm64 */
+#define R_IA64_TPREL64MSB	0x96	/* @tprel(sym + add), data8 MSB */
+#define R_IA64_TPREL64LSB	0x97	/* @tprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_TPREL22	0x9a	/* @ltoff(@tprel(s+a)), imm2 */
+#define R_IA64_DTPMOD64MSB	0xa6	/* @dtpmod(sym + add), data8 MSB */
+#define R_IA64_DTPMOD64LSB	0xa7	/* @dtpmod(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPMOD22	0xaa	/* @ltoff(@dtpmod(sym + add)), imm22 */
+#define R_IA64_DTPREL14		0xb1	/* @dtprel(sym + add), imm14 */
+#define R_IA64_DTPREL22		0xb2	/* @dtprel(sym + add), imm22 */
+#define R_IA64_DTPREL64I	0xb3	/* @dtprel(sym + add), imm64 */
+#define R_IA64_DTPREL32MSB	0xb4	/* @dtprel(sym + add), data4 MSB */
+#define R_IA64_DTPREL32LSB	0xb5	/* @dtprel(sym + add), data4 LSB */
+#define R_IA64_DTPREL64MSB	0xb6	/* @dtprel(sym + add), data8 MSB */
+#define R_IA64_DTPREL64LSB	0xb7	/* @dtprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPREL22	0xba	/* @ltoff(@dtprel(s+a)), imm22 */
+
+/* SH specific declarations */
+
+/* SH relocs.  */
+#define	R_SH_NONE		0
+#define	R_SH_DIR32		1
+#define	R_SH_REL32		2
+#define	R_SH_DIR8WPN		3
+#define	R_SH_IND12W		4
+#define	R_SH_DIR8WPL		5
+#define	R_SH_DIR8WPZ		6
+#define	R_SH_DIR8BP		7
+#define	R_SH_DIR8W		8
+#define	R_SH_DIR8L		9
+#define	R_SH_SWITCH16		25
+#define	R_SH_SWITCH32		26
+#define	R_SH_USES		27
+#define	R_SH_COUNT		28
+#define	R_SH_ALIGN		29
+#define	R_SH_CODE		30
+#define	R_SH_DATA		31
+#define	R_SH_LABEL		32
+#define	R_SH_SWITCH8		33
+#define	R_SH_GNU_VTINHERIT	34
+#define	R_SH_GNU_VTENTRY	35
+#define	R_SH_TLS_GD_32		144
+#define	R_SH_TLS_LD_32		145
+#define	R_SH_TLS_LDO_32		146
+#define	R_SH_TLS_IE_32		147
+#define	R_SH_TLS_LE_32		148
+#define	R_SH_TLS_DTPMOD32	149
+#define	R_SH_TLS_DTPOFF32	150
+#define	R_SH_TLS_TPOFF32	151
+#define	R_SH_GOT32		160
+#define	R_SH_PLT32		161
+#define	R_SH_COPY		162
+#define	R_SH_GLOB_DAT		163
+#define	R_SH_JMP_SLOT		164
+#define	R_SH_RELATIVE		165
+#define	R_SH_GOTOFF		166
+#define	R_SH_GOTPC		167
+/* Keep this the last entry.  */
+#define	R_SH_NUM		256
+
+/* Additional s390 relocs */
+
+#define R_390_NONE		0	/* No reloc.  */
+#define R_390_8			1	/* Direct 8 bit.  */
+#define R_390_12		2	/* Direct 12 bit.  */
+#define R_390_16		3	/* Direct 16 bit.  */
+#define R_390_32		4	/* Direct 32 bit.  */
+#define R_390_PC32		5	/* PC relative 32 bit.	*/
+#define R_390_GOT12		6	/* 12 bit GOT offset.  */
+#define R_390_GOT32		7	/* 32 bit GOT offset.  */
+#define R_390_PLT32		8	/* 32 bit PC relative PLT address.  */
+#define R_390_COPY		9	/* Copy symbol at runtime.  */
+#define R_390_GLOB_DAT		10	/* Create GOT entry.  */
+#define R_390_JMP_SLOT		11	/* Create PLT entry.  */
+#define R_390_RELATIVE		12	/* Adjust by program base.  */
+#define R_390_GOTOFF32		13	/* 32 bit offset to GOT.	 */
+#define R_390_GOTPC		14	/* 32 bit PC relative offset to GOT.  */
+#define R_390_GOT16		15	/* 16 bit GOT offset.  */
+#define R_390_PC16		16	/* PC relative 16 bit.	*/
+#define R_390_PC16DBL		17	/* PC relative 16 bit shifted by 1.  */
+#define R_390_PLT16DBL		18	/* 16 bit PC rel. PLT shifted by 1.  */
+#define R_390_PC32DBL		19	/* PC relative 32 bit shifted by 1.  */
+#define R_390_PLT32DBL		20	/* 32 bit PC rel. PLT shifted by 1.  */
+#define R_390_GOTPCDBL		21	/* 32 bit PC rel. GOT shifted by 1.  */
+#define R_390_64		22	/* Direct 64 bit.  */
+#define R_390_PC64		23	/* PC relative 64 bit.	*/
+#define R_390_GOT64		24	/* 64 bit GOT offset.  */
+#define R_390_PLT64		25	/* 64 bit PC relative PLT address.  */
+#define R_390_GOTENT		26	/* 32 bit PC rel. to GOT entry >> 1. */
+#define R_390_GOTOFF16		27	/* 16 bit offset to GOT. */
+#define R_390_GOTOFF64		28	/* 64 bit offset to GOT. */
+#define R_390_GOTPLT12		29	/* 12 bit offset to jump slot.	*/
+#define R_390_GOTPLT16		30	/* 16 bit offset to jump slot.	*/
+#define R_390_GOTPLT32		31	/* 32 bit offset to jump slot.	*/
+#define R_390_GOTPLT64		32	/* 64 bit offset to jump slot.	*/
+#define R_390_GOTPLTENT		33	/* 32 bit rel. offset to jump slot.  */
+#define R_390_PLTOFF16		34	/* 16 bit offset from GOT to PLT. */
+#define R_390_PLTOFF32		35	/* 32 bit offset from GOT to PLT. */
+#define R_390_PLTOFF64		36	/* 16 bit offset from GOT to PLT. */
+#define R_390_TLS_LOAD		37	/* Tag for load insn in TLS code.  */
+#define R_390_TLS_GDCALL	38	/* Tag for function call in general
+					   dynamic TLS code. */
+#define R_390_TLS_LDCALL	39	/* Tag for function call in local
+					   dynamic TLS code. */
+#define R_390_TLS_GD32		40	/* Direct 32 bit for general dynamic
+					   thread local data.  */
+#define R_390_TLS_GD64		41	/* Direct 64 bit for general dynamic
+					  thread local data.  */
+#define R_390_TLS_GOTIE12	42	/* 12 bit GOT offset for static TLS
+					   block offset.  */
+#define R_390_TLS_GOTIE32	43	/* 32 bit GOT offset for static TLS
+					   block offset.  */
+#define R_390_TLS_GOTIE64	44	/* 64 bit GOT offset for static TLS
+					   block offset. */
+#define R_390_TLS_LDM32		45	/* Direct 32 bit for local dynamic
+					   thread local data in LE code.  */
+#define R_390_TLS_LDM64		46	/* Direct 64 bit for local dynamic
+					   thread local data in LE code.  */
+#define R_390_TLS_IE32		47	/* 32 bit address of GOT entry for
+					   negated static TLS block offset.  */
+#define R_390_TLS_IE64		48	/* 64 bit address of GOT entry for
+					   negated static TLS block offset.  */
+#define R_390_TLS_IEENT		49	/* 32 bit rel. offset to GOT entry for
+					   negated static TLS block offset.  */
+#define R_390_TLS_LE32		50	/* 32 bit negated offset relative to
+					   static TLS block.  */
+#define R_390_TLS_LE64		51	/* 64 bit negated offset relative to
+					   static TLS block.  */
+#define R_390_TLS_LDO32		52	/* 32 bit offset relative to TLS
+					   block.  */
+#define R_390_TLS_LDO64		53	/* 64 bit offset relative to TLS
+					   block.  */
+#define R_390_TLS_DTPMOD	54	/* ID of module containing symbol.  */
+#define R_390_TLS_DTPOFF	55	/* Offset in TLS block.	 */
+#define R_390_TLS_TPOFF		56	/* Negated offset in static TLS
+					   block.  */
+#define R_390_20		57	/* Direct 20 bit.  */
+#define R_390_GOT20		58	/* 20 bit GOT offset.  */
+#define R_390_GOTPLT20		59	/* 20 bit offset to jump slot.  */
+#define R_390_TLS_GOTIE20	60	/* 20 bit GOT offset for static TLS
+					   block offset.  */
+/* Keep this the last entry.  */
+#define R_390_NUM		61
+
+
+/* CRIS relocations.  */
+#define R_CRIS_NONE		0
+#define R_CRIS_8		1
+#define R_CRIS_16		2
+#define R_CRIS_32		3
+#define R_CRIS_8_PCREL		4
+#define R_CRIS_16_PCREL		5
+#define R_CRIS_32_PCREL		6
+#define R_CRIS_GNU_VTINHERIT	7
+#define R_CRIS_GNU_VTENTRY	8
+#define R_CRIS_COPY		9
+#define R_CRIS_GLOB_DAT		10
+#define R_CRIS_JUMP_SLOT	11
+#define R_CRIS_RELATIVE		12
+#define R_CRIS_16_GOT		13
+#define R_CRIS_32_GOT		14
+#define R_CRIS_16_GOTPLT	15
+#define R_CRIS_32_GOTPLT	16
+#define R_CRIS_32_GOTREL	17
+#define R_CRIS_32_PLT_GOTREL	18
+#define R_CRIS_32_PLT_PCREL	19
+
+#define R_CRIS_NUM		20
+
+
+/* AMD x86-64 relocations.  */
+#define R_X86_64_NONE		0	/* No reloc */
+#define R_X86_64_64		1	/* Direct 64 bit  */
+#define R_X86_64_PC32		2	/* PC relative 32 bit signed */
+#define R_X86_64_GOT32		3	/* 32 bit GOT entry */
+#define R_X86_64_PLT32		4	/* 32 bit PLT address */
+#define R_X86_64_COPY		5	/* Copy symbol at runtime */
+#define R_X86_64_GLOB_DAT	6	/* Create GOT entry */
+#define R_X86_64_JUMP_SLOT	7	/* Create PLT entry */
+#define R_X86_64_RELATIVE	8	/* Adjust by program base */
+#define R_X86_64_GOTPCREL	9	/* 32 bit signed PC relative
+					   offset to GOT */
+#define R_X86_64_32		10	/* Direct 32 bit zero extended */
+#define R_X86_64_32S		11	/* Direct 32 bit sign extended */
+#define R_X86_64_16		12	/* Direct 16 bit zero extended */
+#define R_X86_64_PC16		13	/* 16 bit sign extended pc relative */
+#define R_X86_64_8		14	/* Direct 8 bit sign extended  */
+#define R_X86_64_PC8		15	/* 8 bit sign extended pc relative */
+#define R_X86_64_DTPMOD64	16	/* ID of module containing symbol */
+#define R_X86_64_DTPOFF64	17	/* Offset in module's TLS block */
+#define R_X86_64_TPOFF64	18	/* Offset in initial TLS block */
+#define R_X86_64_TLSGD		19	/* 32 bit signed PC relative offset
+					   to two GOT entries for GD symbol */
+#define R_X86_64_TLSLD		20	/* 32 bit signed PC relative offset
+					   to two GOT entries for LD symbol */
+#define R_X86_64_DTPOFF32	21	/* Offset in TLS block */
+#define R_X86_64_GOTTPOFF	22	/* 32 bit signed PC relative offset
+					   to GOT entry for IE symbol */
+#define R_X86_64_TPOFF32	23	/* Offset in initial TLS block */
+
+#define R_X86_64_NUM		24
+
+
+/* AM33 relocations.  */
+#define R_MN10300_NONE		0	/* No reloc.  */
+#define R_MN10300_32		1	/* Direct 32 bit.  */
+#define R_MN10300_16		2	/* Direct 16 bit.  */
+#define R_MN10300_8		3	/* Direct 8 bit.  */
+#define R_MN10300_PCREL32	4	/* PC-relative 32-bit.  */
+#define R_MN10300_PCREL16	5	/* PC-relative 16-bit signed.  */
+#define R_MN10300_PCREL8	6	/* PC-relative 8-bit signed.  */
+#define R_MN10300_GNU_VTINHERIT	7	/* Ancient C++ vtable garbage... */
+#define R_MN10300_GNU_VTENTRY	8	/* ... collection annotation.  */
+#define R_MN10300_24		9	/* Direct 24 bit.  */
+#define R_MN10300_GOTPC32	10	/* 32-bit PCrel offset to GOT.  */
+#define R_MN10300_GOTPC16	11	/* 16-bit PCrel offset to GOT.  */
+#define R_MN10300_GOTOFF32	12	/* 32-bit offset from GOT.  */
+#define R_MN10300_GOTOFF24	13	/* 24-bit offset from GOT.  */
+#define R_MN10300_GOTOFF16	14	/* 16-bit offset from GOT.  */
+#define R_MN10300_PLT32		15	/* 32-bit PCrel to PLT entry.  */
+#define R_MN10300_PLT16		16	/* 16-bit PCrel to PLT entry.  */
+#define R_MN10300_GOT32		17	/* 32-bit offset to GOT entry.  */
+#define R_MN10300_GOT24		18	/* 24-bit offset to GOT entry.  */
+#define R_MN10300_GOT16		19	/* 16-bit offset to GOT entry.  */
+#define R_MN10300_COPY		20	/* Copy symbol at runtime.  */
+#define R_MN10300_GLOB_DAT	21	/* Create GOT entry.  */
+#define R_MN10300_JMP_SLOT	22	/* Create PLT entry.  */
+#define R_MN10300_RELATIVE	23	/* Adjust by program base.  */
+
+#define R_MN10300_NUM		24
+
+
+/* M32R relocs.  */
+#define R_M32R_NONE		0	/* No reloc. */
+#define R_M32R_16		1	/* Direct 16 bit. */
+#define R_M32R_32		2	/* Direct 32 bit. */
+#define R_M32R_24		3	/* Direct 24 bit. */
+#define R_M32R_10_PCREL		4	/* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL		5	/* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL		6	/* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO		7	/* High 16 bit with unsigned low. */
+#define R_M32R_HI16_SLO		8	/* High 16 bit with signed low. */
+#define R_M32R_LO16		9	/* Low 16 bit. */
+#define R_M32R_SDA16		10	/* 16 bit offset in SDA. */
+#define R_M32R_GNU_VTINHERIT	11
+#define R_M32R_GNU_VTENTRY	12
+/* M32R relocs use SHT_RELA.  */
+#define R_M32R_16_RELA		33	/* Direct 16 bit. */
+#define R_M32R_32_RELA		34	/* Direct 32 bit. */
+#define R_M32R_24_RELA		35	/* Direct 24 bit. */
+#define R_M32R_10_PCREL_RELA	36	/* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL_RELA	37	/* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL_RELA	38	/* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO_RELA	39	/* High 16 bit with unsigned low */
+#define R_M32R_HI16_SLO_RELA	40	/* High 16 bit with signed low */
+#define R_M32R_LO16_RELA	41	/* Low 16 bit */
+#define R_M32R_SDA16_RELA	42	/* 16 bit offset in SDA */
+#define R_M32R_RELA_GNU_VTINHERIT	43
+#define R_M32R_RELA_GNU_VTENTRY	44
+
+#define R_M32R_GOT24		48	/* 24 bit GOT entry */
+#define R_M32R_26_PLTREL	49	/* 26 bit PC relative to PLT shifted */
+#define R_M32R_COPY		50	/* Copy symbol at runtime */
+#define R_M32R_GLOB_DAT		51	/* Create GOT entry */
+#define R_M32R_JMP_SLOT		52	/* Create PLT entry */
+#define R_M32R_RELATIVE		53	/* Adjust by program base */
+#define R_M32R_GOTOFF		54	/* 24 bit offset to GOT */
+#define R_M32R_GOTPC24		55	/* 24 bit PC relative offset to GOT */
+#define R_M32R_GOT16_HI_ULO	56	/* High 16 bit GOT entry with unsigned
+					   low */
+#define R_M32R_GOT16_HI_SLO	57	/* High 16 bit GOT entry with signed
+					   low */
+#define R_M32R_GOT16_LO		58	/* Low 16 bit GOT entry */
+#define R_M32R_GOTPC_HI_ULO	59	/* High 16 bit PC relative offset to
+					   GOT with unsigned low */
+#define R_M32R_GOTPC_HI_SLO	60	/* High 16 bit PC relative offset to
+					   GOT with signed low */
+#define R_M32R_GOTPC_LO		61	/* Low 16 bit PC relative offset to
+					   GOT */
+#define R_M32R_GOTOFF_HI_ULO	62	/* High 16 bit offset to GOT
+					   with unsigned low */
+#define R_M32R_GOTOFF_HI_SLO	63	/* High 16 bit offset to GOT
+					   with signed low */
+#define R_M32R_GOTOFF_LO	64	/* Low 16 bit offset to GOT */
+#define R_M32R_NUM		256	/* Keep this the last entry. */
+
+
+__END_DECLS
+
+#endif	/* elf.h */
diff --git a/libelf/elf32_checksum.c b/libelf/elf32_checksum.c
new file mode 100644
index 0000000..a54ebbc
--- /dev/null
+++ b/libelf/elf32_checksum.c
@@ -0,0 +1,145 @@
+/* Compute simple checksum from permanent parts of the ELF file.
+   Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <endian.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "gelf.h"
+#include "libelfP.h"
+#include "elf-knowledge.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+/* The SECTION_STRIP_P macro wants to call into libebl which we cannot
+   do and do not have to do here.  Provide a dummy replacement.  */
+#define ebl_debugscn_p(ebl, name) true
+
+
+#define process_block(crc, data) \
+  __libelf_crc32 (crc, data->d_buf, data->d_size)
+
+
+long int
+elfw2(LIBELFBITS,checksum) (elf)
+     Elf *elf;
+{
+  size_t shstrndx;
+  Elf_Scn *scn;
+  long int result = 0;
+  unsigned char *ident;
+  bool same_byte_order;
+
+  if (elf == NULL)
+    return -1l;
+
+  /* Find the section header string table.  */
+  if  (INTUSE(elf_getshstrndx) (elf, &shstrndx) < 0)
+    {
+      /* This can only happen if the ELF handle is not for real.  */
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return -1l;
+    }
+
+  /* Determine whether the byte order of the file and that of the host
+     is the same.  */
+  ident = elf->state.ELFW(elf,LIBELFBITS).ehdr->e_ident;
+  same_byte_order = ((ident[EI_DATA] == ELFDATA2LSB
+		      && __BYTE_ORDER == __LITTLE_ENDIAN)
+		     || (ident[EI_DATA] == ELFDATA2MSB
+			 && __BYTE_ORDER == __BIG_ENDIAN));
+
+  /* Iterate over all sections to find those which are not strippable.  */
+  scn = NULL;
+  while ((scn = INTUSE(elf_nextscn) (elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr;
+      Elf_Data *data;
+
+      /* Get the section header.  */
+      shdr = INTUSE(gelf_getshdr) (scn, &shdr_mem);
+      if (shdr == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+	  return -1l;
+	}
+
+      if (SECTION_STRIP_P (shdr,
+			   INTUSE(elf_strptr) (elf, shstrndx, shdr->sh_name),
+			   true))
+	/* The section can be stripped.  Don't use it.  */
+	continue;
+
+      /* Do not look at NOBITS sections.  */
+      if (shdr->sh_type == SHT_NOBITS)
+	continue;
+
+      /* To compute the checksum we need to get to the data.  For
+	 repeatable results we must use the external format.  The data
+	 we get with 'elf'getdata' might be changed for endianess
+	 reasons.  Therefore we use 'elf_rawdata' if possible.  But
+	 this function can fail if the data was constructed by the
+	 program.  In this case we have to use 'elf_getdata' and
+	 eventually convert the data to the external format.  */
+      data = INTUSE(elf_rawdata) (scn, NULL);
+      if (data != NULL)
+	{
+	  /* The raw data is available.  */
+	  result = process_block (result, data);
+
+	  /* Maybe the user added more data.  These blocks cannot be
+	     read using 'elf_rawdata'.  Simply proceed with looking
+	     for more data block with 'elf_getdata'.  */
+	}
+
+      /* Iterate through the list of data blocks.  */
+      while ((data = INTUSE(elf_getdata) (scn, data)) != NULL)
+	/* If the file byte order is the same as the host byte order
+	   process the buffer directly.  If the data is just a stream
+	   of bytes which the library will not convert we can use it
+	   as well.  */
+	if (likely (same_byte_order) || data->d_type == ELF_T_BYTE)
+	  result = process_block (result, data);
+	else
+	  {
+	    /* Convert the data to file byte order.  */
+	    if (INTUSE(elfw2(LIBELFBITS,xlatetof)) (data, data, ident[EI_DATA])
+		== NULL)
+	      return -1l;
+
+	    result = process_block (result, data);
+
+	    /* And convert it back.  */
+	    if (INTUSE(elfw2(LIBELFBITS,xlatetom)) (data, data, ident[EI_DATA])
+		== NULL)
+	      return -1l;
+	  }
+    }
+
+  return result;
+}
+INTDEF(elfw2(LIBELFBITS,checksum))
diff --git a/libelf/elf32_fsize.c b/libelf/elf32_fsize.c
new file mode 100644
index 0000000..5075019
--- /dev/null
+++ b/libelf/elf32_fsize.c
@@ -0,0 +1,59 @@
+/* Return the size of an object file type.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+size_t
+elfw2(LIBELFBITS, fsize) (type, count, version)
+     Elf_Type type;
+     size_t count;
+     unsigned int version;
+{
+  /* We do not have differences between file and memory sizes.  Better
+     not since otherwise `mmap' would not work.  */
+  if (unlikely (version == EV_NONE) || unlikely (version >= EV_NUM))
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
+      return 0;
+    }
+
+  if (unlikely (type >= ELF_T_NUM))
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_TYPE);
+      return 0;
+    }
+
+#if EV_NUM != 2
+  return (count
+	  * __libelf_type_sizes[version - 1][ELFW(ELFCLASS,LIBELFBITS) - 1][type]);
+#else
+  return (count
+	  * __libelf_type_sizes[0][ELFW(ELFCLASS,LIBELFBITS) - 1][type]);
+#endif
+}
+#define local_strong_alias(n1, n2) strong_alias (n1, n2)
+local_strong_alias (elfw2(LIBELFBITS, fsize), __elfw2(LIBELFBITS, msize))
diff --git a/libelf/elf32_getehdr.c b/libelf/elf32_getehdr.c
new file mode 100644
index 0000000..efd6002
--- /dev/null
+++ b/libelf/elf32_getehdr.c
@@ -0,0 +1,65 @@
+/* Get ELF header.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+ElfW2(LIBELFBITS,Ehdr) *
+elfw2(LIBELFBITS,getehdr) (elf)
+     Elf *elf;
+{
+  ElfW2(LIBELFBITS,Ehdr) *result;
+
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  rwlock_rdlock (elf->lock);
+
+  if (elf->class == 0)
+    elf->class = ELFW(ELFCLASS,LIBELFBITS);
+  else if (unlikely (elf->class != ELFW(ELFCLASS,LIBELFBITS)))
+    {
+      __libelf_seterrno (ELF_E_INVALID_CLASS);
+      result = NULL;
+      goto out;
+    }
+
+  result = elf->state.ELFW(elf,LIBELFBITS).ehdr;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elfw2(LIBELFBITS,getehdr))
diff --git a/libelf/elf32_getphdr.c b/libelf/elf32_getphdr.c
new file mode 100644
index 0000000..2569368
--- /dev/null
+++ b/libelf/elf32_getphdr.c
@@ -0,0 +1,198 @@
+/* Get ELF program header table.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "libelfP.h"
+#include "common.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+ElfW2(LIBELFBITS,Phdr) *
+elfw2(LIBELFBITS,getphdr) (elf)
+     Elf *elf;
+{
+  ElfW2(LIBELFBITS,Phdr) *result;
+
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* If the program header entry has already been filled in the code
+     below must already have been run.  So the class is set, too.  No
+     need to waste any more time here.  */
+  result = elf->state.ELFW(elf,LIBELFBITS).phdr;
+  if (likely (result != NULL))
+    return result;
+
+  rwlock_wrlock (elf->lock);
+
+  if (elf->class == 0)
+    elf->class = ELFW(ELFCLASS,LIBELFBITS);
+  else if (elf->class != ELFW(ELFCLASS,LIBELFBITS))
+    {
+      __libelf_seterrno (ELF_E_INVALID_CLASS);
+      result = NULL;
+      goto out;
+    }
+
+  if (likely (result == NULL))
+    {
+      /* Read the section header table.  */
+      ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
+
+      /* If no program header exists return NULL.  */
+      size_t phnum = ehdr->e_phnum;
+      if (phnum == 0)
+	{
+	  __libelf_seterrno (ELF_E_NO_PHDR);
+	  goto out;
+	}
+
+      size_t size = phnum * sizeof (ElfW2(LIBELFBITS,Phdr));
+
+      if (elf->map_address != NULL)
+	{
+	  /* All the data is already mapped.  Use it.  */
+	  if (ehdr->e_ident[EI_DATA] == MY_ELFDATA
+	      && (ALLOW_UNALIGNED
+		  || (ehdr->e_phoff
+		      & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0))
+	    /* Simply use the mapped data.  */
+	    elf->state.ELFW(elf,LIBELFBITS).phdr = (ElfW2(LIBELFBITS,Phdr) *)
+	      ((char *) elf->map_address + elf->start_offset + ehdr->e_phoff);
+	  else
+	    {
+	      ElfW2(LIBELFBITS,Phdr) *notcvt;
+	      ElfW2(LIBELFBITS,Phdr) *phdr;
+
+	      /* Allocate memory for the program headers.  We know the number
+		 of entries from the ELF header.  */
+	      phdr = elf->state.ELFW(elf,LIBELFBITS).phdr =
+		(ElfW2(LIBELFBITS,Phdr) *) malloc (size);
+	      if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
+		{
+		  __libelf_seterrno (ELF_E_NOMEM);
+		  goto out;
+		}
+	      elf->state.ELFW(elf,LIBELFBITS).phdr_flags |=
+		ELF_F_MALLOCED | ELF_F_DIRTY;
+
+	      /* Now copy the data and at the same time convert the
+		 byte order.  */
+	      if (ALLOW_UNALIGNED
+		  || (ehdr->e_phoff
+		      & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0)
+		notcvt = (ElfW2(LIBELFBITS,Phdr) *)
+		  ((char *) elf->map_address
+		   + elf->start_offset + ehdr->e_phoff);
+	      else
+		{
+		  notcvt = (ElfW2(LIBELFBITS,Phdr) *) alloca (size);
+		  memcpy (notcvt, ((char *) elf->map_address +
+				   elf->start_offset + ehdr->e_phoff),
+			  size);
+		}
+
+	      for (size_t cnt = 0; cnt < phnum; ++cnt)
+		{
+		  CONVERT_TO (phdr[cnt].p_type, notcvt[cnt].p_type);
+		  CONVERT_TO (phdr[cnt].p_offset, notcvt[cnt].p_offset);
+		  CONVERT_TO (phdr[cnt].p_vaddr, notcvt[cnt].p_vaddr);
+		  CONVERT_TO (phdr[cnt].p_paddr, notcvt[cnt].p_paddr);
+		  CONVERT_TO (phdr[cnt].p_filesz, notcvt[cnt].p_filesz);
+		  CONVERT_TO (phdr[cnt].p_memsz, notcvt[cnt].p_memsz);
+		  CONVERT_TO (phdr[cnt].p_flags, notcvt[cnt].p_flags);
+		  CONVERT_TO (phdr[cnt].p_align, notcvt[cnt].p_align);
+		}
+	    }
+	}
+      else if (likely (elf->fildes != -1))
+	{
+	  /* Allocate memory for the program headers.  We know the number
+	     of entries from the ELF header.  */
+	  elf->state.ELFW(elf,LIBELFBITS).phdr =
+	    (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
+	  if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
+	    {
+	      __libelf_seterrno (ELF_E_NOMEM);
+	      goto out;
+	    }
+	  elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_MALLOCED;
+
+	  /* Read the header.  */
+	  if ((size_t) pread (elf->fildes,
+			      elf->state.ELFW(elf,LIBELFBITS).phdr, size,
+			      (elf->start_offset + ehdr->e_phoff)) != size)
+	    {
+	      /* Severe problems.  We cannot read the data.  */
+	      __libelf_seterrno (ELF_E_READ_ERROR);
+	      free (elf->state.ELFW(elf,LIBELFBITS).phdr);
+	      elf->state.ELFW(elf,LIBELFBITS).phdr = NULL;
+	      goto out;
+	    }
+
+	  /* If the byte order of the file is not the same as the one
+	     of the host convert the data now.  */
+	  if (ehdr->e_ident[EI_DATA] != MY_ELFDATA)
+	    {
+	      ElfW2(LIBELFBITS,Phdr) *phdr
+		= elf->state.ELFW(elf,LIBELFBITS).phdr;
+
+	      for (size_t cnt = 0; cnt < phnum; ++cnt)
+		{
+		  CONVERT (phdr[cnt].p_type);
+		  CONVERT (phdr[cnt].p_offset);
+		  CONVERT (phdr[cnt].p_vaddr);
+		  CONVERT (phdr[cnt].p_paddr);
+		  CONVERT (phdr[cnt].p_filesz);
+		  CONVERT (phdr[cnt].p_memsz);
+		  CONVERT (phdr[cnt].p_flags);
+		  CONVERT (phdr[cnt].p_align);
+		}
+	    }
+	}
+      else
+	{
+	  /* The file descriptor was already enabled and not all data was
+	     read.  */
+	  __libelf_seterrno (ELF_E_FD_DISABLED);
+	  goto out;
+	}
+
+      result = elf->state.ELFW(elf,LIBELFBITS).phdr;
+    }
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elfw2(LIBELFBITS,getphdr))
diff --git a/libelf/elf32_getshdr.c b/libelf/elf32_getshdr.c
new file mode 100644
index 0000000..1e26e85
--- /dev/null
+++ b/libelf/elf32_getshdr.c
@@ -0,0 +1,182 @@
+/* Return section header.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <unistd.h>
+
+#include "libelfP.h"
+#include "common.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+ElfW2(LIBELFBITS,Shdr) *
+elfw2(LIBELFBITS,getshdr) (scn)
+     Elf_Scn *scn;
+{
+  ElfW2(LIBELFBITS,Shdr) *result;
+
+  if (scn == NULL)
+    return NULL;
+
+  if (unlikely (scn->elf->state.elf.ehdr == NULL))
+    {
+      __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+      return NULL;
+    }
+
+  if (unlikely (scn->elf->class != ELFW(ELFCLASS,LIBELFBITS)))
+    {
+      __libelf_seterrno (ELF_E_INVALID_CLASS);
+      return NULL;
+    }
+
+  result = scn->shdr.ELFW(e,LIBELFBITS);
+  if (result == NULL)
+    {
+      /* Read the section header table.  */
+      Elf *elf = scn->elf;
+      ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
+
+      rwlock_wrlock (elf->lock);
+
+      /* Try again, maybe the data is there now.  */
+      result = scn->shdr.ELFW(e,LIBELFBITS);
+      if (result != NULL)
+	goto out;
+
+      size_t shnum;
+      if (INTUSE (elf_getshnum) (elf, &shnum) != 0)
+	goto out;
+      size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr));
+
+      /* Allocate memory for the program headers.  We know the number
+	 of entries from the ELF header.  */
+      ElfW2(LIBELFBITS,Shdr) *shdr = elf->state.ELFW(elf,LIBELFBITS).shdr =
+	(ElfW2(LIBELFBITS,Shdr) *) malloc (size);
+      if (elf->state.ELFW(elf,LIBELFBITS).shdr == NULL)
+	{
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  goto out;
+	}
+      elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 1;
+
+      if (elf->map_address != NULL)
+	{
+	  ElfW2(LIBELFBITS,Shdr) *notcvt;
+
+	  /* All the data is already mapped.  If we could use it
+	     directly this would already have happened.  */
+	  assert (ehdr->e_ident[EI_DATA] != MY_ELFDATA
+		  || (! ALLOW_UNALIGNED
+		      && (ehdr->e_shoff
+			  & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0));
+
+	  /* Now copy the data and at the same time convert the byte
+	     order.  */
+	  if (ALLOW_UNALIGNED
+	      || (ehdr->e_shoff
+		  & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) == 0)
+	    notcvt = (ElfW2(LIBELFBITS,Shdr) *)
+	      ((char *) elf->map_address
+	       + elf->start_offset + ehdr->e_shoff);
+	  else
+	    {
+	      notcvt = (ElfW2(LIBELFBITS,Shdr) *) alloca (size);
+	      memcpy (notcvt, ((char *) elf->map_address
+			       + elf->start_offset + ehdr->e_shoff),
+		      size);
+	    }
+
+	  for (size_t cnt = 0; cnt < shnum; ++cnt)
+	    {
+	      CONVERT_TO (shdr[cnt].sh_name, notcvt[cnt].sh_name);
+	      CONVERT_TO (shdr[cnt].sh_type, notcvt[cnt].sh_type);
+	      CONVERT_TO (shdr[cnt].sh_flags, notcvt[cnt].sh_flags);
+	      CONVERT_TO (shdr[cnt].sh_addr, notcvt[cnt].sh_addr);
+	      CONVERT_TO (shdr[cnt].sh_offset, notcvt[cnt].sh_offset);
+	      CONVERT_TO (shdr[cnt].sh_size, notcvt[cnt].sh_size);
+	      CONVERT_TO (shdr[cnt].sh_link, notcvt[cnt].sh_link);
+	      CONVERT_TO (shdr[cnt].sh_info, notcvt[cnt].sh_info);
+	      CONVERT_TO (shdr[cnt].sh_addralign, notcvt[cnt].sh_addralign);
+	      CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize);
+	    }
+	}
+      else if (elf->fildes != -1)
+	{
+	  /* Read the header.  */
+	  if ((size_t) pread (elf->fildes,
+			      elf->state.ELFW(elf,LIBELFBITS).shdr, size,
+			      elf->start_offset + ehdr->e_shoff) != size)
+	    {
+	      /* Severe problems.  We cannot read the data.  */
+	      __libelf_seterrno (ELF_E_READ_ERROR);
+	      goto free_and_out;
+	    }
+
+	  /* If the byte order of the file is not the same as the one
+	     of the host convert the data now.  */
+	  if (ehdr->e_ident[EI_DATA] != MY_ELFDATA)
+	    for (size_t cnt = 0; cnt < shnum; ++cnt)
+	      {
+		CONVERT (shdr[cnt].sh_name);
+		CONVERT (shdr[cnt].sh_type);
+		CONVERT (shdr[cnt].sh_flags);
+		CONVERT (shdr[cnt].sh_addr);
+		CONVERT (shdr[cnt].sh_offset);
+		CONVERT (shdr[cnt].sh_size);
+		CONVERT (shdr[cnt].sh_link);
+		CONVERT (shdr[cnt].sh_info);
+		CONVERT (shdr[cnt].sh_addralign);
+		CONVERT (shdr[cnt].sh_entsize);
+	      }
+	}
+      else
+	{
+	  /* The file descriptor was already enabled and not all data was
+	     read.  Undo the allocation.  */
+	  __libelf_seterrno (ELF_E_FD_DISABLED);
+
+	free_and_out:
+	  free (shdr);
+	  elf->state.ELFW(elf,LIBELFBITS).shdr = NULL;
+	  elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 0;
+
+	  goto out;
+	}
+
+      /* Set the pointers in the `scn's.  */
+      for (size_t cnt = 0; cnt < shnum; ++cnt)
+	elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shdr.ELFW(e,LIBELFBITS)
+	  = &elf->state.ELFW(elf,LIBELFBITS).shdr[cnt];
+
+      result = scn->shdr.ELFW(e,LIBELFBITS);
+      assert (result != NULL);
+
+    out:
+      rwlock_unlock (elf->lock);
+    }
+
+  return result;
+}
+INTDEF(elfw2(LIBELFBITS,getshdr))
diff --git a/libelf/elf32_newehdr.c b/libelf/elf32_newehdr.c
new file mode 100644
index 0000000..658ad46
--- /dev/null
+++ b/libelf/elf32_newehdr.c
@@ -0,0 +1,80 @@
+/* Create new ELF header.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+ElfW2(LIBELFBITS,Ehdr) *
+elfw2(LIBELFBITS,newehdr) (elf)
+     Elf *elf;
+{
+  ElfW2(LIBELFBITS,Ehdr) *result;
+
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  rwlock_wrlock (elf->lock);
+
+  if (elf->class == 0)
+    elf->class = ELFW(ELFCLASS,LIBELFBITS);
+  else if (unlikely (elf->class != ELFW(ELFCLASS,LIBELFBITS)))
+    {
+      __libelf_seterrno (ELF_E_INVALID_CLASS);
+      result = NULL;
+      goto out;
+    }
+
+  /* Don't create an ELF header if one already exists.  */
+  if (elf->state.ELFW(elf,LIBELFBITS).ehdr == NULL)
+    {
+      /* We use the memory in the ELF descriptor.  */
+      elf->state.ELFW(elf,LIBELFBITS).ehdr =
+	&elf->state.ELFW(elf,LIBELFBITS).ehdr_mem;
+
+      /* We clear this memory.  */
+      memset (elf->state.ELFW(elf,LIBELFBITS).ehdr, '\0',
+	      sizeof (ElfW2(LIBELFBITS,Ehdr)));
+
+      /* Mark the ELF header has modified.  */
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
+    }
+
+  result = elf->state.ELFW(elf,LIBELFBITS).ehdr;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elfw2(LIBELFBITS,newehdr))
diff --git a/libelf/elf32_newphdr.c b/libelf/elf32_newphdr.c
new file mode 100644
index 0000000..74a2387
--- /dev/null
+++ b/libelf/elf32_newphdr.c
@@ -0,0 +1,138 @@
+/* Create new ELF program header table.
+   Copyright (C) 1999, 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+ElfW2(LIBELFBITS,Phdr) *
+elfw2(LIBELFBITS,newphdr) (elf, count)
+     Elf *elf;
+     size_t count;
+{
+  ElfW2(LIBELFBITS,Phdr) *result;
+
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  rwlock_wrlock (elf->lock);
+
+  if (elf->class == 0)
+    elf->class = ELFW(ELFCLASS,LIBELFBITS);
+  else if (unlikely (elf->class != ELFW(ELFCLASS,LIBELFBITS)))
+    {
+      __libelf_seterrno (ELF_E_INVALID_CLASS);
+      result = NULL;
+      goto out;
+    }
+
+  if (unlikely (elf->state.ELFW(elf,LIBELFBITS).ehdr == NULL))
+    {
+      __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+      result = NULL;
+      goto out;
+    }
+
+  /* A COUNT of zero means remove existing table.  */
+  if (count == 0)
+    {
+      /* Free the old program header.  */
+      if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL)
+	{
+	  if (elf->state.ELFW(elf,LIBELFBITS).phdr_flags & ELF_F_MALLOCED)
+	    free (elf->state.ELFW(elf,LIBELFBITS).phdr);
+
+	  /* Set the pointer to NULL.  */
+	  elf->state.ELFW(elf,LIBELFBITS).phdr = NULL;
+	  /* Set the `e_phnum' member to the new value.  */
+	  elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = 0;
+	  /* Also set the size.  */
+	  elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize =
+	    sizeof (ElfW2(LIBELFBITS,Phdr));
+
+	  elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_DIRTY;
+	  elf->flags |= ELF_F_DIRTY;
+	  __libelf_seterrno (ELF_E_NOERROR);
+	}
+
+      result = NULL;
+    }
+  else if (elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum != count
+	   || elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
+    {
+      /* Allocate a new program header with the appropriate number of
+	 elements.  */
+      result = (ElfW2(LIBELFBITS,Phdr) *)
+	realloc (elf->state.ELFW(elf,LIBELFBITS).phdr,
+		 count * sizeof (ElfW2(LIBELFBITS,Phdr)));
+      if (result == NULL)
+	__libelf_seterrno (ELF_E_NOMEM);
+      else
+	{
+	  /* Now set the result.  */
+	  elf->state.ELFW(elf,LIBELFBITS).phdr = result;
+	  /* Clear the whole memory.  */
+	  memset (result, '\0', count * sizeof (ElfW2(LIBELFBITS,Phdr)));
+	  /* Set the `e_phnum' member to the new value.  */
+	  elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = count;
+	  /* Also set the size.  */
+	  elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize =
+	    elf_typesize (LIBELFBITS, ELF_T_PHDR, 1);
+	  /* Remember we allocated the array and mark the structure is
+	     modified.  */
+	  elf->state.ELFW(elf,LIBELFBITS).phdr_flags |=
+	    ELF_F_DIRTY | ELF_F_MALLOCED;
+	  /* We have to rewrite the entire file if the size of the
+	     program header is changed.  */
+	  elf->flags |= ELF_F_DIRTY;
+	}
+    }
+  else
+    {
+      /* We have the same number of entries.  Just clear the array.  */
+      assert (elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize
+	      == elf_typesize (LIBELFBITS, ELF_T_PHDR, 1));
+
+      /* Mark the structure as modified.  */
+      elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_DIRTY;
+
+      result = elf->state.ELFW(elf,LIBELFBITS).phdr;
+    }
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elfw2(LIBELFBITS,newphdr))
diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c
new file mode 100644
index 0000000..14893de
--- /dev/null
+++ b/libelf/elf32_updatefile.c
@@ -0,0 +1,610 @@
+/* Write changed data structures.
+   Copyright (C) 2000, 2001, 2002, 2004, 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libelf.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+#include "libelfP.h"
+
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+static int
+compare_sections (const void *a, const void *b)
+{
+  const Elf_Scn **scna = (const Elf_Scn **) a;
+  const Elf_Scn **scnb = (const Elf_Scn **) b;
+
+  if ((*scna)->shdr.ELFW(e,LIBELFBITS)->sh_offset
+      < (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_offset)
+    return -1;
+
+  if ((*scna)->shdr.ELFW(e,LIBELFBITS)->sh_offset
+      > (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_offset)
+    return 1;
+
+  if ((*scna)->index < (*scnb)->index)
+    return -1;
+
+  if ((*scna)->index > (*scnb)->index)
+    return 1;
+
+  return 0;
+}
+
+
+/* Insert the sections in the list into the provided array and sort
+   them according to their start offsets.  For sections with equal
+   start offsets the section index is used.  */
+static void
+sort_sections (Elf_Scn **scns, Elf_ScnList *list)
+{
+  Elf_Scn **scnp = scns;
+  do
+    for (size_t cnt = 0; cnt < list->cnt; ++cnt)
+      *scnp++ = &list->data[cnt];
+  while ((list = list->next) != NULL);
+
+  qsort (scns, scnp - scns, sizeof (*scns), compare_sections);
+}
+
+
+int
+internal_function_def
+__elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
+{
+  ElfW2(LIBELFBITS,Ehdr) *ehdr;
+  xfct_t fctp;
+  char *last_position;
+
+  /* We need the ELF header several times.  */
+  ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
+
+  /* Write out the ELF header.  */
+  if ((elf->state.ELFW(elf,LIBELFBITS).ehdr_flags | elf->flags) & ELF_F_DIRTY)
+    {
+      /* If the type sizes should be different at some time we have to
+	 rewrite this code.  */
+      assert (sizeof (ElfW2(LIBELFBITS,Ehdr))
+	      == elf_typesize (LIBELFBITS, ELF_T_EHDR, 1));
+
+      if (unlikely (change_bo))
+	{
+	  /* Today there is only one version of the ELF header.  */
+#if EV_NUM != 2
+	  fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR]
+#endif
+
+	  /* Do the real work.  */
+	  (*fctp) ((char *) elf->map_address + elf->start_offset, ehdr,
+		   sizeof (ElfW2(LIBELFBITS,Ehdr)), 1);
+	}
+      else
+	memcpy (elf->map_address + elf->start_offset, ehdr,
+		sizeof (ElfW2(LIBELFBITS,Ehdr)));
+
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags &= ~ELF_F_DIRTY;
+    }
+
+  /* Write out the program header table.  */
+  if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL
+      && ((elf->state.ELFW(elf,LIBELFBITS).phdr_flags | elf->flags)
+	  & ELF_F_DIRTY))
+    {
+      /* If the type sizes should be different at some time we have to
+	 rewrite this code.  */
+      assert (sizeof (ElfW2(LIBELFBITS,Phdr))
+	      == elf_typesize (LIBELFBITS, ELF_T_PHDR, 1));
+
+      /* Maybe the user wants a gap between the ELF header and the program
+	 header.  */
+      if (ehdr->e_phoff > ehdr->e_ehsize)
+	memset (elf->map_address + elf->start_offset + ehdr->e_ehsize,
+		__libelf_fill_byte, ehdr->e_phoff - ehdr->e_ehsize);
+
+      if (unlikely (change_bo))
+	{
+	  /* Today there is only one version of the ELF header.  */
+#if EV_NUM != 2
+	  fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR]
+#endif
+
+	  /* Do the real work.  */
+	  (*fctp) (elf->map_address + elf->start_offset + ehdr->e_phoff,
+		   elf->state.ELFW(elf,LIBELFBITS).phdr,
+		   sizeof (ElfW2(LIBELFBITS,Phdr)) * ehdr->e_phnum, 1);
+	}
+      else
+	memcpy (elf->map_address + elf->start_offset + ehdr->e_phoff,
+		elf->state.ELFW(elf,LIBELFBITS).phdr,
+		sizeof (ElfW2(LIBELFBITS,Phdr)) * ehdr->e_phnum);
+
+      elf->state.ELFW(elf,LIBELFBITS).phdr_flags &= ~ELF_F_DIRTY;
+    }
+
+  /* From now on we have to keep track of the last position to eventually
+     fill the gaps with the prescribed fill byte.  */
+  last_position = ((char *) elf->map_address + elf->start_offset
+		   + MAX (elf_typesize (LIBELFBITS, ELF_T_EHDR, 1),
+			  ehdr->e_phoff)
+		   + elf_typesize (LIBELFBITS, ELF_T_PHDR, ehdr->e_phnum));
+
+  /* Write all the sections.  Well, only those which are modified.  */
+  if (shnum > 0)
+    {
+      ElfW2(LIBELFBITS,Shdr) *shdr_dest;
+      Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns;
+      Elf_Scn **scns = (Elf_Scn **) alloca (shnum * sizeof (Elf_Scn *));
+      char *shdr_start = ((char *) elf->map_address + elf->start_offset
+			  + ehdr->e_shoff);
+      char *shdr_end = shdr_start + ehdr->e_shnum * ehdr->e_shentsize;
+
+#if EV_NUM != 2
+      xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR];
+#else
+# undef shdr_fctp
+# define shdr_fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR]
+#endif
+      shdr_dest = (ElfW2(LIBELFBITS,Shdr) *)
+	((char *) elf->map_address + elf->start_offset + ehdr->e_shoff);
+
+      /* Get all sections into the array and sort them.  */
+      sort_sections (scns, list);
+
+      /* Iterate over all the section in the order in which they
+	 appear in the output file.  */
+      for (size_t cnt = 0; cnt < shnum; ++cnt)
+	{
+	  Elf_Scn *scn = scns[cnt];
+	  ElfW2(LIBELFBITS,Shdr) *shdr;
+	  char *scn_start;
+	  Elf_Data_List *dl;
+
+	  shdr = scn->shdr.ELFW(e,LIBELFBITS);
+
+	  scn_start = ((char *) elf->map_address
+		       + elf->start_offset + shdr->sh_offset);
+	  dl = &scn->data_list;
+
+	  if (shdr->sh_type != SHT_NOBITS && scn->data_list_rear != NULL)
+	    do
+	      {
+		if ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY)
+		  {
+		    if (scn_start + dl->data.d.d_off != last_position)
+		      {
+			if (scn_start + dl->data.d.d_off > last_position)
+			  {
+			    /* This code assumes that the data blocks for
+			       a section are ordered by offset.  */
+			    size_t written = 0;
+
+			    if (last_position < shdr_start)
+			      {
+				written = MIN (scn_start + dl->data.d.d_off
+					       - last_position,
+					       shdr_start - last_position);
+
+				memset (last_position, __libelf_fill_byte,
+					written);
+			      }
+
+			    if (last_position + written
+				!= scn_start + dl->data.d.d_off
+				&& shdr_end < scn_start + dl->data.d.d_off)
+			      memset (shdr_end, __libelf_fill_byte,
+				      scn_start + dl->data.d.d_off - shdr_end);
+
+			    last_position = scn_start + dl->data.d.d_off;
+			  }
+		      }
+
+		    if (unlikely (change_bo))
+		      {
+#if EV_NUM != 2
+			fctp = __elf_xfctstom[__libelf_version - 1][dl->data.d.d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type];
+#else
+# undef fctp
+			fctp = __elf_xfctstom[0][0][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type];
+#endif
+
+			/* Do the real work.  */
+			(*fctp) (last_position, dl->data.d.d_buf,
+				 dl->data.d.d_size, 1);
+
+			last_position += dl->data.d.d_size;
+		      }
+		    else
+		      last_position = mempcpy (last_position,
+					       dl->data.d.d_buf,
+					       dl->data.d.d_size);
+		  }
+		else
+		  last_position += dl->data.d.d_size;
+
+		dl->flags &= ~ELF_F_DIRTY;
+
+		dl = dl->next;
+	      }
+	    while (dl != NULL);
+	  else if (shdr->sh_type != SHT_NOBITS && scn->index != 0)
+	    /* We have to trust the existing section header information.  */
+	    last_position += shdr->sh_size;
+
+	  /* Write the section header table entry if necessary.  */
+	  if ((scn->shdr_flags | elf->flags) & ELF_F_DIRTY)
+	    {
+	      if (unlikely (change_bo))
+		(*shdr_fctp) (&shdr_dest[scn->index],
+			      scn->shdr.ELFW(e,LIBELFBITS),
+			      sizeof (ElfW2(LIBELFBITS,Shdr)), 1);
+	      else
+		memcpy (&shdr_dest[scn->index],
+			scn->shdr.ELFW(e,LIBELFBITS),
+			sizeof (ElfW2(LIBELFBITS,Shdr)));
+
+	      scn->shdr_flags  &= ~ELF_F_DIRTY;
+	    }
+
+	  scn->flags &= ~ELF_F_DIRTY;
+	}
+
+      /* Fill the gap between last section and section header table if
+	 necessary.  */
+      if ((elf->flags & ELF_F_DIRTY)
+	  && last_position < ((char *) elf->map_address + elf->start_offset
+			       + ehdr->e_shoff))
+	memset (last_position, __libelf_fill_byte,
+		(char *) elf->map_address + elf->start_offset + ehdr->e_shoff
+		- last_position);
+    }
+
+  /* That was the last part.  Clear the overall flag.  */
+  elf->flags &= ~ELF_F_DIRTY;
+
+  return 0;
+}
+
+
+/* Size of the buffer we use to generate the blocks of fill bytes.  */
+#define FILLBUFSIZE	4096
+
+/* If we have to convert the section buffer contents we have to use
+   temporary buffer.  Only buffers up to MAX_TMPBUF bytes are allocated
+   on the stack.  */
+#define MAX_TMPBUF	32768
+
+
+/* Helper function to write out fill bytes.  */
+static int
+fill (int fd, off_t pos, size_t len, char *fillbuf, size_t *filledp)
+{
+  size_t filled = *filledp;
+  size_t fill_len = MIN (len, FILLBUFSIZE);
+
+  if (unlikely (fill_len > filled) && filled < FILLBUFSIZE)
+    {
+      /* Initialize a few more bytes.  */
+      memset (fillbuf + filled, __libelf_fill_byte, fill_len - filled);
+      *filledp = filled = fill_len;
+    }
+
+  do
+    {
+      /* This many bytes we want to write in this round.  */
+      size_t n = MIN (filled, len);
+
+      if (unlikely ((size_t) pwrite (fd, fillbuf, n, pos) != n))
+	{
+	  __libelf_seterrno (ELF_E_WRITE_ERROR);
+	  return 1;
+	}
+
+      pos += n;
+      len -= n;
+    }
+  while (len > 0);
+
+  return 0;
+}
+
+
+int
+internal_function_def
+__elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
+{
+  char fillbuf[FILLBUFSIZE];
+  size_t filled = 0;
+  xfct_t fctp;
+
+  /* We need the ELF header several times.  */
+  ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
+
+  /* Write out the ELF header.  */
+  if ((elf->state.ELFW(elf,LIBELFBITS).ehdr_flags | elf->flags) & ELF_F_DIRTY)
+    {
+      ElfW2(LIBELFBITS,Ehdr) tmp_ehdr;
+      ElfW2(LIBELFBITS,Ehdr) *out_ehdr = ehdr;
+
+      /* If the type sizes should be different at some time we have to
+	 rewrite this code.  */
+      assert (sizeof (ElfW2(LIBELFBITS,Ehdr))
+	      == elf_typesize (LIBELFBITS, ELF_T_EHDR, 1));
+
+      if (unlikely (change_bo))
+	{
+	  /* Today there is only one version of the ELF header.  */
+#if EV_NUM != 2
+	  fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR]
+#endif
+
+	  /* Write the converted ELF header in a temporary buffer.  */
+	  (*fctp) (&tmp_ehdr, ehdr, sizeof (ElfW2(LIBELFBITS,Ehdr)), 1);
+
+	  /* This is the buffer we want to write.  */
+	  out_ehdr = &tmp_ehdr;
+	}
+
+      /* Write out the ELF header.  */
+      if (unlikely (pwrite (elf->fildes, out_ehdr,
+			    sizeof (ElfW2(LIBELFBITS,Ehdr)), 0)
+		    != sizeof (ElfW2(LIBELFBITS,Ehdr))))
+	{
+	  __libelf_seterrno (ELF_E_WRITE_ERROR);
+	  return 1;
+	}
+
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags &= ~ELF_F_DIRTY;
+    }
+
+  /* If the type sizes should be different at some time we have to
+     rewrite this code.  */
+  assert (sizeof (ElfW2(LIBELFBITS,Phdr))
+	  == elf_typesize (LIBELFBITS, ELF_T_PHDR, 1));
+
+  /* Write out the program header table.  */
+  if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL
+      && ((elf->state.ELFW(elf,LIBELFBITS).phdr_flags | elf->flags)
+	  & ELF_F_DIRTY))
+    {
+      ElfW2(LIBELFBITS,Phdr) *tmp_phdr = NULL;
+      ElfW2(LIBELFBITS,Phdr) *out_phdr = elf->state.ELFW(elf,LIBELFBITS).phdr;
+
+      /* Maybe the user wants a gap between the ELF header and the program
+	 header.  */
+      if (ehdr->e_phoff > ehdr->e_ehsize
+	  && unlikely (fill (elf->fildes, ehdr->e_ehsize,
+			     ehdr->e_phoff - ehdr->e_ehsize, fillbuf, &filled)
+		       != 0))
+	return 1;
+
+      if (unlikely (change_bo))
+	{
+	  /* Today there is only one version of the ELF header.  */
+#if EV_NUM != 2
+	  fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR]
+#endif
+
+	  /* Allocate sufficient memory.  */
+	  tmp_phdr = (ElfW2(LIBELFBITS,Phdr) *)
+	    malloc (sizeof (ElfW2(LIBELFBITS,Phdr)) * ehdr->e_phnum);
+	  if (tmp_phdr == NULL)
+	    {
+	      __libelf_seterrno (ELF_E_NOMEM);
+	      return 1;
+	    }
+
+	  /* Write the converted ELF header in a temporary buffer.  */
+	  (*fctp) (tmp_phdr, elf->state.ELFW(elf,LIBELFBITS).phdr,
+		   sizeof (ElfW2(LIBELFBITS,Phdr)) * ehdr->e_phnum, 1);
+
+	  /* This is the buffer we want to write.  */
+	  out_phdr = tmp_phdr;
+	}
+
+      /* Write out the ELF header.  */
+      if (unlikely ((size_t) pwrite (elf->fildes, out_phdr,
+				     sizeof (ElfW2(LIBELFBITS,Phdr))
+				     * ehdr->e_phnum, ehdr->e_phoff)
+		    != sizeof (ElfW2(LIBELFBITS,Phdr)) * ehdr->e_phnum))
+	{
+	  __libelf_seterrno (ELF_E_WRITE_ERROR);
+	  return 1;
+	}
+
+      /* This is a no-op we we have not allocated any memory.  */
+      free (tmp_phdr);
+
+      elf->state.ELFW(elf,LIBELFBITS).phdr_flags &= ~ELF_F_DIRTY;
+    }
+
+  /* From now on we have to keep track of the last position to eventually
+     fill the gaps with the prescribed fill byte.  */
+  off_t last_offset;
+  if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
+    last_offset = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
+  else
+    last_offset = (ehdr->e_phoff
+		   + sizeof (ElfW2(LIBELFBITS,Phdr)) * ehdr->e_phnum);
+
+  /* Write all the sections.  Well, only those which are modified.  */
+  if (shnum > 0)
+    {
+      off_t shdr_offset = elf->start_offset + ehdr->e_shoff;
+#if EV_NUM != 2
+      xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR];
+#else
+# undef shdr_fctp
+# define shdr_fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR]
+#endif
+
+      ElfW2(LIBELFBITS,Shdr) *shdr_data;
+      if (change_bo || elf->state.ELFW(elf,LIBELFBITS).shdr == NULL)
+	shdr_data = (ElfW2(LIBELFBITS,Shdr) *)
+	  alloca (shnum * sizeof (ElfW2(LIBELFBITS,Shdr)));
+      else
+	shdr_data = elf->state.ELFW(elf,LIBELFBITS).shdr;
+      int shdr_flags = elf->flags;
+
+      /* Get all sections into the array and sort them.  */
+      Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns;
+      Elf_Scn **scns = (Elf_Scn **) alloca (shnum * sizeof (Elf_Scn *));
+      sort_sections (scns, list);
+
+      for (size_t cnt = 0; cnt < shnum; ++cnt)
+	{
+	  Elf_Scn *scn = scns[cnt];
+
+	  ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS);
+
+	  off_t scn_start = elf->start_offset + shdr->sh_offset;
+	  Elf_Data_List *dl = &scn->data_list;
+
+	  if (shdr->sh_type != SHT_NOBITS && scn->data_list_rear != NULL
+	      && scn->index != 0)
+	    do
+	      {
+		if ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY)
+		  {
+		    char tmpbuf[MAX_TMPBUF];
+		    void *buf = dl->data.d.d_buf;
+
+		    if (scn_start + dl->data.d.d_off != last_offset)
+		      {
+			assert (last_offset < scn_start + dl->data.d.d_off);
+
+			if (unlikely (fill (elf->fildes, last_offset,
+					    (scn_start + dl->data.d.d_off)
+					    - last_offset, fillbuf,
+					    &filled) != 0))
+			  return 1;
+
+			last_offset = scn_start + dl->data.d.d_off;
+		      }
+
+		    if (unlikely (change_bo))
+		      {
+#if EV_NUM != 2
+			fctp = __elf_xfctstom[__libelf_version - 1][dl->data.d.d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type];
+#else
+# undef fctp
+			fctp = __elf_xfctstom[0][0][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type];
+#endif
+
+			buf = tmpbuf;
+			if (dl->data.d.d_size > MAX_TMPBUF)
+			  {
+			    buf = malloc (dl->data.d.d_size);
+			    if (buf == NULL)
+			      {
+				__libelf_seterrno (ELF_E_NOMEM);
+				return 1;
+			      }
+			  }
+
+			/* Do the real work.  */
+			(*fctp) (buf, dl->data.d.d_buf, dl->data.d.d_size, 1);
+		      }
+
+		    if (unlikely ((size_t) pwrite (elf->fildes, buf,
+						   dl->data.d.d_size,
+						   last_offset)
+				  != dl->data.d.d_size))
+		      {
+			if (buf != dl->data.d.d_buf && buf != tmpbuf)
+			  free (buf);
+
+			__libelf_seterrno (ELF_E_WRITE_ERROR);
+			return 1;
+		      }
+
+		    if (buf != dl->data.d.d_buf && buf != tmpbuf)
+		      free (buf);
+		  }
+
+		last_offset += dl->data.d.d_size;
+
+		dl->flags &= ~ELF_F_DIRTY;
+
+		dl = dl->next;
+	      }
+	    while (dl != NULL);
+	  else if (shdr->sh_type != SHT_NOBITS && scn->index != 0)
+	    last_offset = scn_start + shdr->sh_size;
+
+	  /* Collect the section header table information.  */
+	  if (unlikely (change_bo))
+	    (*shdr_fctp) (&shdr_data[scn->index],
+			  scn->shdr.ELFW(e,LIBELFBITS),
+			  sizeof (ElfW2(LIBELFBITS,Shdr)), 1);
+	  else if (elf->state.ELFW(elf,LIBELFBITS).shdr == NULL)
+	    memcpy (&shdr_data[scn->index], scn->shdr.ELFW(e,LIBELFBITS),
+		    sizeof (ElfW2(LIBELFBITS,Shdr)));
+
+	  shdr_flags |= scn->shdr_flags;
+	  scn->shdr_flags  &= ~ELF_F_DIRTY;
+	}
+
+      /* Fill the gap between last section and section header table if
+	 necessary.  */
+      if ((elf->flags & ELF_F_DIRTY) && last_offset < shdr_offset
+	  && unlikely (fill (elf->fildes, last_offset,
+			     shdr_offset - last_offset,
+			     fillbuf, &filled) != 0))
+	return 1;
+
+      /* Write out the section header table.  */
+      if (shdr_flags & ELF_F_DIRTY
+	  && unlikely ((size_t) pwrite (elf->fildes, shdr_data,
+					sizeof (ElfW2(LIBELFBITS,Shdr))
+					* shnum, shdr_offset)
+		       != sizeof (ElfW2(LIBELFBITS,Shdr)) * shnum))
+	{
+	  __libelf_seterrno (ELF_E_WRITE_ERROR);
+	  return 1;
+	}
+    }
+
+  /* That was the last part.  Clear the overall flag.  */
+  elf->flags &= ~ELF_F_DIRTY;
+
+  return 0;
+}
diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c
new file mode 100644
index 0000000..ed7242b
--- /dev/null
+++ b/libelf/elf32_updatenull.c
@@ -0,0 +1,384 @@
+/* Update data structures for changes.
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <endian.h>
+#include <libelf.h>
+#include <stdbool.h>
+#include <string.h>
+#include <sys/param.h>
+
+#include "libelfP.h"
+#include "elf-knowledge.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+
+static int
+ELFW(default_ehdr,LIBELFBITS) (Elf *elf, ElfW2(LIBELFBITS,Ehdr) *ehdr,
+			       size_t shnum, int *change_bop)
+{
+  /* Always write the magic bytes.  */
+  if (memcmp (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0)
+    {
+      memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG);
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
+    }
+
+  /* Always set the file class.  */
+  update_if_changed (ehdr->e_ident[EI_CLASS], ELFW(ELFCLASS,LIBELFBITS),
+		     elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
+
+  /* Set the data encoding if necessary.  */
+  if (unlikely (ehdr->e_ident[EI_DATA] == ELFDATANONE))
+    {
+      ehdr->e_ident[EI_DATA] =
+	BYTE_ORDER == BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB;
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
+    }
+  else if (unlikely (ehdr->e_ident[EI_DATA] >= ELFDATANUM))
+    {
+      __libelf_seterrno (ELF_E_DATA_ENCODING);
+      return 1;
+    }
+  else
+    *change_bop = ((BYTE_ORDER == LITTLE_ENDIAN
+		    && ehdr->e_ident[EI_DATA] != ELFDATA2LSB)
+		   || (BYTE_ORDER == BIG_ENDIAN
+		       && ehdr->e_ident[EI_DATA] != ELFDATA2MSB));
+
+  /* Unconditionally overwrite the ELF version.  */
+  update_if_changed (ehdr->e_ident[EI_VERSION], EV_CURRENT,
+		     elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
+
+  if (unlikely (ehdr->e_version == EV_NONE)
+      || unlikely (ehdr->e_version >= EV_NUM))
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
+      return 1;
+    }
+
+  if (unlikely (shnum >= SHN_LORESERVE))
+    {
+      update_if_changed (ehdr->e_shnum, 0,
+			 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
+    }
+  else
+    update_if_changed (ehdr->e_shnum, shnum,
+		       elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
+
+  if (unlikely (ehdr->e_ehsize != elf_typesize (LIBELFBITS, ELF_T_EHDR, 1)))
+    {
+      ehdr->e_ehsize = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
+    }
+
+  return 0;
+}
+
+
+off_t
+internal_function_def
+__elfw2(LIBELFBITS,updatenull) (Elf *elf, int *change_bop, size_t shnum)
+{
+  ElfW2(LIBELFBITS,Ehdr) *ehdr = INTUSE(elfw2(LIBELFBITS,getehdr)) (elf);
+  int changed = 0;
+  int ehdr_flags = 0;
+
+  /* Set the default values.  */
+  if (ELFW(default_ehdr,LIBELFBITS) (elf, ehdr, shnum, change_bop) != 0)
+    return -1;
+
+  /* At least the ELF header is there.  */
+  off_t size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
+
+  /* Set the program header position.  */
+  if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL
+      && (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN))
+    (void) INTUSE(elfw2(LIBELFBITS,getphdr)) (elf);
+  if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL)
+    {
+      /* Only executables or shared objects have a program header.  */
+      if (ehdr->e_type != ET_EXEC && unlikely (ehdr->e_type != ET_DYN))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_PHDR);
+	  return -1;
+	}
+
+      if (elf->flags & ELF_F_LAYOUT)
+	{
+	  /* The user is supposed to fill out e_phoff.  Use it and
+	     e_phnum to determine the maximum extend.  */
+	  size = MAX ((size_t) size,
+		      ehdr->e_phoff
+		      + elf_typesize (LIBELFBITS, ELF_T_PHDR, ehdr->e_phnum));
+	}
+      else
+	{
+	  update_if_changed (ehdr->e_phoff,
+			     elf_typesize (LIBELFBITS, ELF_T_EHDR, 1),
+			     ehdr_flags);
+
+	  /* We need no alignment here.  */
+	  size += elf_typesize (LIBELFBITS, ELF_T_PHDR, ehdr->e_phnum);
+	}
+    }
+
+  if (shnum > 0)
+    {
+      Elf_ScnList *list;
+      bool first = true;
+
+      assert (elf->state.ELFW(elf,LIBELFBITS).scns.cnt > 0);
+
+      if (shnum >= SHN_LORESERVE)
+	{
+	  /* We have to  fill in the number of sections in the header
+	     of the zeroth section.  */
+	  Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0];
+
+	  update_if_changed (scn0->shdr.ELFW(e,LIBELFBITS)->sh_size,
+			     shnum, scn0->shdr_flags);
+	}
+
+      /* Go over all sections and find out how large they are.  */
+      list = &elf->state.ELFW(elf,LIBELFBITS).scns;
+
+      /* Load the section headers if necessary.  This loads the
+	 headers for all sections.  */
+      if (list->data[1].shdr.ELFW(e,LIBELFBITS) == NULL)
+	(void) INTUSE(elfw2(LIBELFBITS,getshdr)) (&list->data[1]);
+
+      do
+	{
+	  for (size_t cnt = first == true; cnt < list->cnt; ++cnt)
+	    {
+	      Elf_Scn *scn = &list->data[cnt];
+	      ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS);
+	      off_t offset = 0;
+
+	      assert (shdr != NULL);
+	      ElfW2(LIBELFBITS,Word) sh_entsize = shdr->sh_entsize;
+	      ElfW2(LIBELFBITS,Word) sh_align = shdr->sh_addralign ?: 1;
+
+	      /* Set the sh_entsize value if we can reliably detect it.  */
+	      switch (shdr->sh_type)
+		{
+		case SHT_SYMTAB:
+		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1);
+		  break;
+		case SHT_RELA:
+		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_RELA, 1);
+		  break;
+		case SHT_GROUP:
+		  /* Only relocatable files can contain section groups.  */
+		  if (ehdr->e_type != ET_REL)
+		    {
+		      __libelf_seterrno (ELF_E_GROUP_NOT_REL);
+		      return -1;
+		    }
+		  /* FALLTHROUGH */
+		case SHT_SYMTAB_SHNDX:
+		  sh_entsize = elf_typesize (32, ELF_T_WORD, 1);
+		  break;
+		case SHT_HASH:
+		  sh_entsize = SH_ENTSIZE_HASH (ehdr);
+		  break;
+		case SHT_DYNAMIC:
+		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_DYN, 1);
+		  break;
+		case SHT_REL:
+		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_REL, 1);
+		  break;
+		case SHT_DYNSYM:
+		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1);
+		  break;
+		case SHT_SUNW_move:
+		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_MOVE, 1);
+		  break;
+		case SHT_SUNW_syminfo:
+		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYMINFO, 1);
+		  break;
+		default:
+		  break;
+		}
+
+	      /* If the section header contained the wrong entry size
+		 correct it and mark the header as modified.  */
+	      update_if_changed (shdr->sh_entsize, sh_entsize,
+				 scn->shdr_flags);
+
+	      if (scn->data_read == 0 && __libelf_set_rawdata (scn) != 0)
+		/* Something went wrong.  The error value is already set.  */
+		return -1;
+
+	      /* Iterate over all data blocks.  */
+	      if (list->data[cnt].data_list_rear != NULL)
+		{
+		  Elf_Data_List *dl = &scn->data_list;
+
+		  while (dl != NULL)
+		    {
+		      Elf_Data *data = &dl->data.d;
+		      if (dl == &scn->data_list && data->d_buf == NULL
+			  && scn->rawdata.d.d_buf != NULL)
+			data = &scn->rawdata.d;
+
+		      if (unlikely (data->d_version == EV_NONE)
+			  || unlikely (data->d_version >= EV_NUM))
+			{
+			  __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
+			  return -1;
+			}
+
+		      if (unlikely (! powerof2 (data->d_align)))
+			{
+			  __libelf_seterrno (ELF_E_INVALID_ALIGN);
+			  return -1;
+			}
+
+		      sh_align = MAX (sh_align, data->d_align);
+
+		      if (elf->flags & ELF_F_LAYOUT)
+			{
+			  /* The user specified the offset and the size.
+			     All we have to do is check whether this block
+			     fits in the size specified for the section.  */
+			  if (unlikely ((GElf_Word) (data->d_off
+						     + data->d_size)
+					> shdr->sh_size))
+			    {
+			      __libelf_seterrno (ELF_E_SECTION_TOO_SMALL);
+			      return -1;
+			    }
+			}
+		      else
+			{
+			  /* Determine the padding.  */
+			  offset = ((offset + data->d_align - 1)
+				    & ~(data->d_align - 1));
+
+			  update_if_changed (data->d_off, offset, changed);
+
+			  offset += data->d_size;
+			}
+
+		      /* Next data block.  */
+		      dl = dl->next;
+		    }
+		}
+	      else
+		/* Get the size of the section from the raw data.  If
+		   none is available the value is zero.  */
+		offset += scn->rawdata.d.d_size;
+
+	      if (elf->flags & ELF_F_LAYOUT)
+		{
+		  size = MAX ((GElf_Word) size,
+			      shdr->sh_offset
+			      + (shdr->sh_type != SHT_NOBITS
+				 ? shdr->sh_size : 0));
+
+		  /* The alignment must be a power of two.  This is a
+		     requirement from the ELF specification.  Additionally
+		     we test for the alignment of the section being large
+		     enough for the largest alignment required by a data
+		     block.  */
+		  if (unlikely (! powerof2 (shdr->sh_addralign))
+		      || unlikely (shdr->sh_addralign < sh_align))
+		    {
+		      __libelf_seterrno (ELF_E_INVALID_ALIGN);
+		      return -1;
+		    }
+		}
+	      else
+		{
+		  /* How much alignment do we need for this section.  */
+		  update_if_changed (shdr->sh_addralign, sh_align,
+				     scn->shdr_flags);
+
+		  size = (size + sh_align - 1) & ~(sh_align - 1);
+		  update_if_changed (shdr->sh_offset, (GElf_Word) size,
+				     changed);
+
+		  /* See whether the section size is correct.  */
+		  update_if_changed (shdr->sh_size, (GElf_Word) offset,
+				     changed);
+
+		  if (shdr->sh_type != SHT_NOBITS)
+		    size += offset;
+
+		  scn->flags |= changed;
+		}
+
+	      /* Check that the section size is actually a multiple of
+		 the entry size.  */
+	      if (shdr->sh_entsize != 0
+		  && unlikely (shdr->sh_size % shdr->sh_entsize != 0)
+		  && (elf->flags & ELF_F_PERMISSIVE) == 0)
+		{
+		  __libelf_seterrno (ELF_E_INVALID_SHENTSIZE);
+		  return -1;
+		}
+	    }
+
+	  assert (list->next == NULL || list->cnt == list->max);
+
+	  first = false;
+	}
+      while ((list = list->next) != NULL);
+
+      /* Store section information.  */
+      if (elf->flags & ELF_F_LAYOUT)
+	{
+	  /* The user is supposed to fill out e_phoff.  Use it and
+	     e_phnum to determine the maximum extend.  */
+	  size = MAX ((GElf_Word) size,
+		      (ehdr->e_shoff
+		       + (elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum))));
+	}
+      else
+	{
+	  /* Align for section header table.
+
+	     Yes, we use `sizeof' and not `__alignof__' since we do not
+	     want to be surprised by architectures with less strict
+	     alignment rules.  */
+#define SHDR_ALIGN sizeof (ElfW2(LIBELFBITS,Off))
+	  size = (size + SHDR_ALIGN - 1) & ~(SHDR_ALIGN - 1);
+
+	  update_if_changed (ehdr->e_shoff, (GElf_Word) size, elf->flags);
+	  update_if_changed (ehdr->e_shentsize,
+			     elf_typesize (LIBELFBITS, ELF_T_SHDR, 1),
+			     ehdr_flags);
+
+	  /* Account for the section header size.  */
+	  size += elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum);
+	}
+    }
+
+  elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ehdr_flags;
+
+  return size;
+}
diff --git a/libelf/elf32_xlatetof.c b/libelf/elf32_xlatetof.c
new file mode 100644
index 0000000..46b6588
--- /dev/null
+++ b/libelf/elf32_xlatetof.c
@@ -0,0 +1,111 @@
+/* Convert from memory to file representation.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <endian.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS	32
+#endif
+
+
+Elf_Data *
+elfw2(LIBELFBITS, xlatetof) (dest, src, encode)
+     Elf_Data *dest;
+     const Elf_Data *src;
+     unsigned int encode;
+{
+  /* First test whether the input data is really suitable for this
+     type.  This means, whether there is an integer number of records.
+     Note that for this implementation the memory and file size of the
+     data types are identical.  */
+#if EV_NUM != 2
+  size_t recsize = __libelf_type_sizes[src->d_version - 1][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
+#else
+  size_t recsize = __libelf_type_sizes[0][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
+#endif
+
+  if (src->d_size % recsize != 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_DATA);
+      return NULL;
+    }
+
+  /* Next see whether the converted data fits in the output buffer.  */
+  if (src->d_size > dest->d_size)
+    {
+      __libelf_seterrno (ELF_E_DEST_SIZE);
+      return NULL;
+    }
+
+  /* Test the encode parameter.  */
+  if (encode != ELFDATA2LSB && encode != ELFDATA2MSB)
+    {
+      __libelf_seterrno (ELF_E_INVALID_ENCODING);
+      return NULL;
+    }
+
+  /* Determine the translation function to use.
+
+     At this point we make an assumption which is valid for all
+     existing implementations so far: the memory and file sizes are
+     the same.  This has very important consequences:
+     a) The requirement that the source and destination buffer can
+	overlap can easily be fulfilled.
+     b) We need only one function to convert from and memory to file
+	and vice versa since the function only has to copy and/or
+	change the byte order.
+  */
+  if ((__BYTE_ORDER == __LITTLE_ENDIAN && encode == ELFDATA2LSB)
+      || (__BYTE_ORDER == __BIG_ENDIAN && encode == ELFDATA2MSB))
+    {
+      /* We simply have to copy since the byte order is the same.  */
+      if (src->d_buf != dest->d_buf)
+	memmove (dest->d_buf, src->d_buf, src->d_size);
+    }
+  else
+    {
+      xfct_t fctp;
+
+      /* Get a pointer to the transformation functions.  The `#ifdef' is
+	 a small optimization since we don't anticipate another ELF
+	 version and so would waste "precious" code.  */
+#if EV_NUM != 2
+      fctp = __elf_xfctstom[dest->d_version - 1][src->d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
+#else
+      fctp = __elf_xfctstom[0][0][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
+#endif
+
+      /* Do the real work.  */
+      (*fctp) (dest->d_buf, src->d_buf, src->d_size, 1);
+    }
+
+  /* Now set the real destination type and length since the operation was
+     successful.  */
+  dest->d_type = src->d_type;
+  dest->d_size = src->d_size;
+
+  return dest;
+}
+INTDEF(elfw2(LIBELFBITS, xlatetof))
diff --git a/libelf/elf32_xlatetom.c b/libelf/elf32_xlatetom.c
new file mode 100644
index 0000000..1b8c65c
--- /dev/null
+++ b/libelf/elf32_xlatetom.c
@@ -0,0 +1,112 @@
+/* Convert from file to memory representation.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <endian.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS	32
+#endif
+
+
+Elf_Data *
+elfw2(LIBELFBITS, xlatetom) (dest, src, encode)
+     Elf_Data *dest;
+     const Elf_Data *src;
+     unsigned int encode;
+{
+  /* First test whether the input data is really suitable for this
+     type.  This means, whether there is an integer number of records.
+     Note that for this implementation the memory and file size of the
+     data types are identical.  */
+#if EV_NUM != 2
+  size_t recsize = __libelf_type_sizes[src->d_version - 1][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
+#else
+  size_t recsize = __libelf_type_sizes[0][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
+#endif
+
+
+  if (src->d_size % recsize != 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_DATA);
+      return NULL;
+    }
+
+  /* Next see whether the converted data fits in the output buffer.  */
+  if (src->d_size > dest->d_size)
+    {
+      __libelf_seterrno (ELF_E_DEST_SIZE);
+      return NULL;
+    }
+
+  /* Test the encode parameter.  */
+  if (encode != ELFDATA2LSB && encode != ELFDATA2MSB)
+    {
+      __libelf_seterrno (ELF_E_INVALID_ENCODING);
+      return NULL;
+    }
+
+  /* Determine the translation function to use.
+
+     At this point we make an assumption which is valid for all
+     existing implementations so far: the memory and file sizes are
+     the same.  This has very important consequences:
+     a) The requirement that the source and destination buffer can
+	overlap can easily be fulfilled.
+     b) We need only one function to convert from and memory to file
+	and vice versa since the function only has to copy and/or
+	change the byte order.
+  */
+  if ((BYTE_ORDER == LITTLE_ENDIAN && encode == ELFDATA2LSB)
+      || (BYTE_ORDER == BIG_ENDIAN && encode == ELFDATA2MSB))
+    {
+      /* We simply have to copy since the byte order is the same.  */
+      if (src->d_buf != dest->d_buf)
+	memmove (dest->d_buf, src->d_buf, src->d_size);
+    }
+  else
+    {
+      xfct_t fctp;
+
+      /* Get a pointer to the transformation functions.  The `#ifdef' is
+	 a small optimization since we don't anticipate another ELF
+	 version and so would waste "precious" code.  */
+#if EV_NUM != 2
+      fctp = __elf_xfctstom[src->d_version - 1][dest->d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
+#else
+      fctp = __elf_xfctstom[0][0][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
+#endif
+
+      /* Do the real work.  */
+      (*fctp) (dest->d_buf, src->d_buf, src->d_size, 0);
+    }
+
+  /* Now set the real destination type and length since the operation was
+     successful.  */
+  dest->d_type = src->d_type;
+  dest->d_size = src->d_size;
+
+  return dest;
+}
+INTDEF(elfw2(LIBELFBITS, xlatetom))
diff --git a/libelf/elf64_checksum.c b/libelf/elf64_checksum.c
new file mode 100644
index 0000000..bdb9210
--- /dev/null
+++ b/libelf/elf64_checksum.c
@@ -0,0 +1,19 @@
+/* Compute simple checksum from permanent parts of the ELF file.
+   Copyright (C) 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define LIBELFBITS 64
+#include "elf32_checksum.c"
diff --git a/libelf/elf64_fsize.c b/libelf/elf64_fsize.c
new file mode 100644
index 0000000..0b1f414
--- /dev/null
+++ b/libelf/elf64_fsize.c
@@ -0,0 +1,19 @@
+/* Return the size of an object file type.
+   Copyright (C) 1998, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define LIBELFBITS 64
+#include "elf32_fsize.c"
diff --git a/libelf/elf64_getehdr.c b/libelf/elf64_getehdr.c
new file mode 100644
index 0000000..89a69ff
--- /dev/null
+++ b/libelf/elf64_getehdr.c
@@ -0,0 +1,19 @@
+/* Return program header table.
+   Copyright (C) 1998, 1999, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define LIBELFBITS 64
+#include "elf32_getehdr.c"
diff --git a/libelf/elf64_getphdr.c b/libelf/elf64_getphdr.c
new file mode 100644
index 0000000..d06d7c1
--- /dev/null
+++ b/libelf/elf64_getphdr.c
@@ -0,0 +1,19 @@
+/* Return program header table.
+   Copyright (C) 1998, 1999, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define LIBELFBITS 64
+#include "elf32_getphdr.c"
diff --git a/libelf/elf64_getshdr.c b/libelf/elf64_getshdr.c
new file mode 100644
index 0000000..1a5da57
--- /dev/null
+++ b/libelf/elf64_getshdr.c
@@ -0,0 +1,19 @@
+/* Return section header.
+   Copyright (C) 1998, 1999, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define LIBELFBITS 64
+#include "elf32_getshdr.c"
diff --git a/libelf/elf64_newehdr.c b/libelf/elf64_newehdr.c
new file mode 100644
index 0000000..aba6e63
--- /dev/null
+++ b/libelf/elf64_newehdr.c
@@ -0,0 +1,19 @@
+/* Create new program header table.
+   Copyright (C) 1999, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define LIBELFBITS 64
+#include "elf32_newehdr.c"
diff --git a/libelf/elf64_newphdr.c b/libelf/elf64_newphdr.c
new file mode 100644
index 0000000..90ff463
--- /dev/null
+++ b/libelf/elf64_newphdr.c
@@ -0,0 +1,19 @@
+/* Create new program header table.
+   Copyright (C) 1999, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define LIBELFBITS 64
+#include "elf32_newphdr.c"
diff --git a/libelf/elf64_updatefile.c b/libelf/elf64_updatefile.c
new file mode 100644
index 0000000..6b604f1
--- /dev/null
+++ b/libelf/elf64_updatefile.c
@@ -0,0 +1,18 @@
+/* Copyright (C) 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define LIBELFBITS 64
+#include "elf32_updatefile.c"
diff --git a/libelf/elf64_updatenull.c b/libelf/elf64_updatenull.c
new file mode 100644
index 0000000..ff1f070
--- /dev/null
+++ b/libelf/elf64_updatenull.c
@@ -0,0 +1,18 @@
+/* Copyright (C) 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define LIBELFBITS 64
+#include "elf32_updatenull.c"
diff --git a/libelf/elf64_xlatetof.c b/libelf/elf64_xlatetof.c
new file mode 100644
index 0000000..3440bbc
--- /dev/null
+++ b/libelf/elf64_xlatetof.c
@@ -0,0 +1,19 @@
+/* Convert from memory to file representation.
+   Copyright (C) 1998, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define LIBELFBITS 64
+#include "elf32_xlatetof.c"
diff --git a/libelf/elf64_xlatetom.c b/libelf/elf64_xlatetom.c
new file mode 100644
index 0000000..773f04e
--- /dev/null
+++ b/libelf/elf64_xlatetom.c
@@ -0,0 +1,19 @@
+/* Convert from file to memory representation.
+   Copyright (C) 1998, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define LIBELFBITS 64
+#include "elf32_xlatetom.c"
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
new file mode 100644
index 0000000..404cbe8
--- /dev/null
+++ b/libelf/elf_begin.c
@@ -0,0 +1,1073 @@
+/* Create descriptor for processing file.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include "libelfP.h"
+#include "common.h"
+
+
+/* Create descriptor for archive in memory.  */
+static inline Elf *
+file_read_ar (int fildes, void *map_address, off_t offset, size_t maxsize,
+	      Elf_Cmd cmd, Elf *parent)
+{
+  Elf *elf;
+
+  /* Create a descriptor.  */
+  elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
+                      ELF_K_AR, 0);
+  if (elf != NULL)
+    {
+      /* We don't read all the symbol tables in advance.  All this will
+	 happen on demand.  */
+      elf->state.ar.offset = offset + SARMAG;
+
+      elf->state.ar.elf_ar_hdr.ar_rawname = elf->state.ar.raw_name;
+    }
+
+  return elf;
+}
+
+
+static size_t
+get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
+	   size_t maxsize)
+{
+  size_t result;
+  union
+  {
+    Elf32_Ehdr *e32;
+    Elf64_Ehdr *e64;
+    void *p;
+  } ehdr;
+  bool is32 = e_ident[EI_CLASS] == ELFCLASS32;
+
+  /* Make the ELF header available.  */
+  if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
+      && (ALLOW_UNALIGNED
+	  || (((size_t) ((char *) map_address + offset))
+	      & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr))
+		 - 1)) == 0))
+    ehdr.p = (char *) map_address + offset;
+  else
+    {
+      /* We have to read the data from the file.  */
+      size_t len = is32 ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr);
+
+      ehdr.p = alloca (len);
+      /* Fill it.  */
+      if ((size_t) pread (fildes, ehdr.p, len, offset) != len)
+	/* Failed reading.  */
+	return (size_t) -1l;
+
+      if (e_ident[EI_DATA] != MY_ELFDATA)
+	{
+	  if (is32)
+	    {
+	      CONVERT (ehdr.e32->e_shnum);
+	      CONVERT (ehdr.e32->e_shoff);
+	    }
+	  else
+	    {
+	      CONVERT (ehdr.e64->e_shnum);
+	      CONVERT (ehdr.e64->e_shoff);
+	    }
+	}
+    }
+
+  if (is32)
+    {
+      /* Get the number of sections from the ELF header.  */
+      result = ehdr.e32->e_shnum;
+
+      if (unlikely (result == 0) && ehdr.e32->e_shoff != 0)
+	{
+	  if (offset + ehdr.e32->e_shoff + sizeof (Elf32_Shdr) > maxsize)
+	    /* Cannot read the first section header.  */
+	    return (size_t) -1l;
+
+	  if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
+	      && (ALLOW_UNALIGNED
+		  || (((size_t) ((char *) map_address + offset))
+		      & (__alignof__ (Elf32_Ehdr) - 1)) == 0))
+	    /* We can directly access the memory.  */
+	    result = ((Elf32_Shdr *) ((char *) map_address
+				      + ehdr.e32->e_shoff
+				      + offset))->sh_size;
+	  else
+	    {
+	      Elf32_Word size;
+
+	      if (pread (fildes, &size, sizeof (Elf32_Word),
+			 offset + ehdr.e32->e_shoff
+			 + offsetof (Elf32_Shdr, sh_size))
+		  != sizeof (Elf32_Word))
+		return (size_t) -1l;
+
+	      if (e_ident[EI_DATA] != MY_ELFDATA)
+		CONVERT (size);
+
+	      result = size;
+	    }
+	}
+    }
+  else
+    {
+      /* Get the number of sections from the ELF header.  */
+      result = ehdr.e64->e_shnum;
+
+      if (unlikely (result == 0) && ehdr.e64->e_shoff != 0)
+	{
+	  if (offset + ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize)
+	    /* Cannot read the first section header.  */
+	    return (size_t) -1l;
+
+	  if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
+	      && (ALLOW_UNALIGNED
+		  || (((size_t) ((char *) map_address + offset))
+		      & (__alignof__ (Elf64_Ehdr) - 1)) == 0))
+	    /* We can directly access the memory.  */
+	    result = ((Elf64_Shdr *) ((char *) map_address
+				      + ehdr.e64->e_shoff
+				      + offset))->sh_size;
+	  else
+	    {
+	      Elf64_Word size;
+
+	      if (pread (fildes, &size, sizeof (Elf64_Word),
+			 offset + ehdr.e64->e_shoff
+			 + offsetof (Elf64_Shdr, sh_size))
+		  != sizeof (Elf64_Word))
+		return (size_t) -1l;
+
+	      if (e_ident[EI_DATA] != MY_ELFDATA)
+		CONVERT (size);
+
+	      result = size;
+	    }
+	}
+    }
+
+  return result;
+}
+
+
+/* Create descriptor for ELF file in memory.  */
+static Elf *
+file_read_elf (int fildes, void *map_address, off_t offset, size_t maxsize,
+	       Elf_Cmd cmd, Elf *parent)
+{
+  /* We only read the ELF header now.  */
+  unsigned char *e_ident;
+  size_t scncnt;
+  Elf *elf;
+
+  if (map_address != NULL)
+    /* It's right at the beginning of the file.  No word access
+       required, just bytes.  */
+    e_ident = (unsigned char *) map_address + offset;
+  else
+    {
+      e_ident = (unsigned char *) alloca (EI_NIDENT);
+
+      if (pread (fildes, e_ident, EI_NIDENT, offset) != EI_NIDENT)
+	{
+	  __libelf_seterrno (ELF_E_READ_ERROR);
+	  return NULL;
+	}
+    }
+
+  /* Verify the binary is of the class we can handle.  */
+  if ((e_ident[EI_CLASS] != ELFCLASS32
+       && e_ident[EI_CLASS] != ELFCLASS64)
+      /* We also can only handle two encodings.  */
+      || (e_ident[EI_DATA] != ELFDATA2LSB
+	  && e_ident[EI_DATA] != ELFDATA2MSB))
+    {
+      /* Cannot handle this.  */
+      __libelf_seterrno (ELF_E_INVALID_FILE);
+      return NULL;
+    }
+
+  /* Determine the number of sections.  */
+  scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize);
+  if (scncnt == (size_t) -1l)
+    /* Could not determine the number of sections.  */
+    return NULL;
+
+  /* We can now allocate the memory.  */
+  elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
+		      ELF_K_ELF, scncnt * sizeof (Elf_Scn));
+  if (elf == NULL)
+    /* Not enough memory.  */
+    return NULL;
+
+  /* Some more or less arbitrary value.  */
+  elf->state.elf.scnincr = 10;
+
+  if (e_ident[EI_CLASS] == ELFCLASS32)
+    {
+      /* This pointer might not be directly usable if the alignment is
+	 not sufficient for the architecture.  */
+      Elf32_Ehdr *ehdr = (Elf32_Ehdr *) ((char *) map_address + offset);
+
+      assert ((unsigned int) scncnt == scncnt);
+      elf->state.elf32.scns.cnt = elf->state.elf32.scns.max = scncnt;
+
+      /* This is a 32-bit binary.  */
+      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
+	  && (ALLOW_UNALIGNED
+	      || ((((uintptr_t) ehdr) & (__alignof__ (Elf32_Ehdr) - 1)) == 0
+		  && ((uintptr_t) ((char *) ehdr + ehdr->e_shoff)
+		      & (__alignof__ (Elf32_Shdr) - 1)) == 0
+		  && ((uintptr_t) ((char *) ehdr + ehdr->e_phoff)
+		      & (__alignof__ (Elf32_Phdr) - 1)) == 0)))
+	{
+	  /* We can use the mmapped memory.  */
+	  elf->state.elf32.ehdr =
+	    (Elf32_Ehdr *) ((char *) map_address + offset);
+	  elf->state.elf32.shdr =
+	    (Elf32_Shdr *) ((char *) map_address + offset
+			    + elf->state.elf32.ehdr->e_shoff);
+	  if (elf->state.elf32.ehdr->e_phnum)
+	    /* Assign a value only if there really is a program
+	       header.  Otherwise the value remains NULL.  */
+	    elf->state.elf32.phdr
+	      = (Elf32_Phdr *) ((char *) map_address + offset
+				+ elf->state.elf32.ehdr->e_phoff);
+
+	  for (size_t cnt = 0; cnt < scncnt; ++cnt)
+	    {
+	      elf->state.elf32.scns.data[cnt].index = cnt;
+	      elf->state.elf32.scns.data[cnt].elf = elf;
+	      elf->state.elf32.scns.data[cnt].shdr.e32 =
+		&elf->state.elf32.shdr[cnt];
+	      elf->state.elf32.scns.data[cnt].rawdata_base =
+		elf->state.elf32.scns.data[cnt].data_base =
+		((char *) map_address + offset
+		 + elf->state.elf32.shdr[cnt].sh_offset);
+	      elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
+	    }
+	}
+      else
+	{
+	  /* Read the data.  */
+	  if (pread (elf->fildes, &elf->state.elf32.ehdr_mem,
+		     sizeof (Elf32_Ehdr), offset) != sizeof (Elf32_Ehdr))
+	    {
+	      /* We must be able to read the ELF header.  */
+	      __libelf_seterrno (ELF_E_INVALID_FILE);
+	      return NULL;
+	    }
+
+	  if (e_ident[EI_DATA] != MY_ELFDATA)
+	    {
+	      CONVERT (elf->state.elf32.ehdr_mem.e_type);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_machine);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_version);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_entry);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_phoff);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_shoff);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_flags);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_ehsize);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_phentsize);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_phnum);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_shentsize);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_shnum);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_shstrndx);
+	    }
+
+	  elf->state.elf32.ehdr = &elf->state.elf32.ehdr_mem;
+
+	  for (size_t cnt = 0; cnt < scncnt; ++cnt)
+	    {
+	      elf->state.elf32.scns.data[cnt].index = cnt;
+	      elf->state.elf32.scns.data[cnt].elf = elf;
+	      elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
+	    }
+	}
+
+      /* So far only one block with sections.  */
+      elf->state.elf32.scns_last = &elf->state.elf32.scns;
+    }
+  else
+    {
+      /* This pointer might not be directly usable if the alignment is
+	 not sufficient for the architecture.  */
+      Elf64_Ehdr *ehdr = (Elf64_Ehdr *) ((char *) map_address + offset);
+
+      assert ((unsigned int) scncnt == scncnt);
+      elf->state.elf64.scns.cnt = elf->state.elf64.scns.max = scncnt;
+
+      /* This is a 64-bit binary.  */
+      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
+	  && (ALLOW_UNALIGNED
+	      || ((((uintptr_t) ehdr) & (__alignof__ (Elf64_Ehdr) - 1)) == 0
+		  && ((uintptr_t) ((char *) ehdr + ehdr->e_shoff)
+		      & (__alignof__ (Elf64_Shdr) - 1)) == 0
+		  && ((uintptr_t) ((char *) ehdr + ehdr->e_phoff)
+		      & (__alignof__ (Elf64_Phdr) - 1)) == 0)))
+	{
+	  /* We can use the mmapped memory.  */
+	  elf->state.elf64.ehdr =
+	    (Elf64_Ehdr *) ((char *) map_address + offset);
+	  elf->state.elf64.shdr =
+	    (Elf64_Shdr *) ((char *) map_address + offset
+			    + elf->state.elf64.ehdr->e_shoff);
+	  if (elf->state.elf64.ehdr->e_phnum)
+	    /* Assign a value only if there really is a program
+	       header.  Otherwise the value remains NULL.  */
+	    elf->state.elf64.phdr
+	      = (Elf64_Phdr *) ((char *) map_address + offset
+				+ elf->state.elf64.ehdr->e_phoff);
+
+	  for (size_t cnt = 0; cnt < scncnt; ++cnt)
+	    {
+	      elf->state.elf64.scns.data[cnt].index = cnt;
+	      elf->state.elf64.scns.data[cnt].elf = elf;
+	      elf->state.elf64.scns.data[cnt].shdr.e64 =
+		&elf->state.elf64.shdr[cnt];
+	      elf->state.elf64.scns.data[cnt].rawdata_base =
+		elf->state.elf64.scns.data[cnt].data_base =
+		((char *) map_address + offset
+		 + elf->state.elf64.shdr[cnt].sh_offset);
+	      elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
+	    }
+	}
+      else
+	{
+	  /* Read the data.  */
+	  if (pread (elf->fildes, &elf->state.elf64.ehdr_mem,
+		     sizeof (Elf64_Ehdr), offset) != sizeof (Elf64_Ehdr))
+	    {
+	      /* We must be able to read the ELF header.  */
+	      __libelf_seterrno (ELF_E_INVALID_FILE);
+	      return NULL;
+	    }
+
+	  if (e_ident[EI_DATA] != MY_ELFDATA)
+	    {
+	      CONVERT (elf->state.elf64.ehdr_mem.e_type);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_machine);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_version);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_entry);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_phoff);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_shoff);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_flags);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_ehsize);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_phentsize);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_phnum);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_shentsize);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_shnum);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_shstrndx);
+	    }
+
+	  elf->state.elf64.ehdr = &elf->state.elf64.ehdr_mem;
+
+	  for (size_t cnt = 0; cnt < scncnt; ++cnt)
+	    {
+	      elf->state.elf64.scns.data[cnt].index = cnt;
+	      elf->state.elf64.scns.data[cnt].elf = elf;
+	      elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
+	    }
+	}
+
+      /* So far only one block with sections.  */
+      elf->state.elf64.scns_last = &elf->state.elf64.scns;
+    }
+
+  /* Make the class easily available.  */
+  elf->class = e_ident[EI_CLASS];
+
+  return elf;
+}
+
+
+Elf *
+internal_function_def
+__libelf_read_mmaped_file (int fildes, void *map_address,  off_t offset,
+			   size_t maxsize, Elf_Cmd cmd, Elf *parent)
+{
+  /* We have to find out what kind of file this is.  We handle ELF
+     files and archives.  To find out what we have we must look at the
+     header.  The header for an ELF file is EI_NIDENT bytes in size,
+     the header for an archive file SARMAG bytes long.  */
+  Elf_Kind kind;
+
+  /* See what kind of object we have here.  */
+  kind = determine_kind (map_address + offset, maxsize);
+
+  switch (kind)
+    {
+    case ELF_K_ELF:
+      return file_read_elf (fildes, map_address, offset, maxsize, cmd, parent);
+
+    case ELF_K_AR:
+      return file_read_ar (fildes, map_address, offset, maxsize, cmd, parent);
+
+    default:
+      break;
+    }
+
+  /* This case is easy.  Since we cannot do anything with this file
+     create a dummy descriptor.  */
+  return allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
+		       ELF_K_NONE, 0);
+}
+
+
+static Elf *
+read_unmmaped_file (int fildes, off_t offset, size_t maxsize, Elf_Cmd cmd,
+		    Elf *parent)
+{
+  /* We have to find out what kind of file this is.  We handle ELF
+     files and archives.  To find out what we have we must read the
+     header.  The header for an ELF file is EI_NIDENT bytes in size,
+     the header for an archive file SARMAG bytes long.  Read the
+     maximum of these numbers.
+
+     XXX We have to change this for the extended `ar' format some day.  */
+  unsigned char header[MAX (EI_NIDENT, SARMAG)];
+  ssize_t nread;
+  Elf_Kind kind;
+
+  /* Read the head of the file.  */
+  nread = pread (fildes, header, MIN (MAX (EI_NIDENT, SARMAG), maxsize),
+		 offset);
+  if (nread == -1)
+    /* We cannot even read the head of the file.  Maybe FILDES is associated
+       with an unseekable device.  This is nothing we can handle.  */
+    return NULL;
+
+  /* See what kind of object we have here.  */
+  kind = determine_kind (header, nread);
+
+  switch (kind)
+    {
+    case ELF_K_AR:
+      return file_read_ar (fildes, NULL, offset, maxsize, cmd, parent);
+
+    case ELF_K_ELF:
+      /* Make sure at least the ELF header is contained in the file.  */
+      if (maxsize >= (header[EI_CLASS] == ELFCLASS32
+		      ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)))
+	return file_read_elf (fildes, NULL, offset, maxsize, cmd, parent);
+      /* FALLTHROUGH */
+
+    default:
+      break;
+    }
+
+  /* This case is easy.  Since we cannot do anything with this file
+     create a dummy descriptor.  */
+  return allocate_elf (fildes, NULL, offset, maxsize, cmd, parent,
+		       ELF_K_NONE, 0);
+}
+
+
+/* Open a file for reading.  If possible we will try to mmap() the file.  */
+static struct Elf *
+read_file (int fildes, off_t offset, size_t maxsize,
+	   Elf_Cmd cmd, Elf *parent)
+{
+  void *map_address = NULL;
+  int use_mmap = (cmd == ELF_C_READ_MMAP || cmd == ELF_C_RDWR_MMAP
+		  || cmd == ELF_C_WRITE_MMAP
+		  || cmd == ELF_C_READ_MMAP_PRIVATE);
+
+#if _MUDFLAP
+  /* Mudflap doesn't grok that our mmap'd data is ok.  */
+  use_mmap = 0;
+#endif
+
+  if (use_mmap)
+    {
+      if (parent == NULL)
+	{
+	  if (maxsize == ~((size_t) 0))
+	    {
+	      /* We don't know in the moment how large the file is.
+		 Determine it now.  */
+	      struct stat st;
+
+	      if (fstat (fildes, &st) == 0
+		  && (sizeof (size_t) >= sizeof (st.st_size)
+		      || st.st_size <= ~((size_t) 0)))
+		maxsize = (size_t) st.st_size;
+	    }
+
+	  /* We try to map the file ourself.  */
+	  map_address = mmap (NULL, maxsize, (cmd == ELF_C_READ_MMAP
+					      ? PROT_READ
+					      : PROT_READ|PROT_WRITE),
+			      cmd == ELF_C_READ_MMAP_PRIVATE
+			      ? MAP_PRIVATE : MAP_SHARED,
+			      fildes, offset);
+
+	  if (map_address == MAP_FAILED)
+	    map_address = NULL;
+	}
+      else
+	{
+	  /* The parent is already loaded.  Use it.  */
+	  assert (maxsize != ~((size_t) 0));
+
+	  map_address = parent->map_address;
+	}
+    }
+
+  /* If we have the file in memory optimize the access.  */
+  if (map_address != NULL)
+    {
+      struct Elf *result;
+
+      result = __libelf_read_mmaped_file (fildes, map_address, offset, maxsize,
+					  cmd, parent);
+
+      /* If something went wrong during the initialization unmap the
+	 memory if we mmaped here.  */
+      if (result == NULL
+	  && (parent == NULL
+	      || parent->map_address != map_address))
+	munmap (map_address, maxsize);
+      else if (parent == NULL)
+	/* Remember that we mmap()ed the memory.  */
+	result->flags |= ELF_F_MMAPPED;
+
+      return result;
+    }
+
+  /* Otherwise we have to do it the hard way.  We read as much as necessary
+     from the file whenever we need information which is not available.  */
+  return read_unmmaped_file (fildes, offset, maxsize, cmd, parent);
+}
+
+
+/* Find the entry with the long names for the content of this archive.  */
+static const char *
+read_long_names (Elf *elf)
+{
+  off_t offset = SARMAG;	/* This is the first entry.  */
+  struct ar_hdr hdrm;
+  struct ar_hdr *hdr;
+  char *newp;
+  size_t len;
+
+  while (1)
+    {
+      if (elf->map_address != NULL)
+	{
+	  if (offset + sizeof (struct ar_hdr) > elf->maximum_size)
+	    return NULL;
+
+	  /* The data is mapped.  */
+	  hdr = (struct ar_hdr *) (elf->map_address + offset);
+	}
+      else
+	{
+	  /* Read the header from the file.  */
+	  if (pread (elf->fildes, &hdrm, sizeof (hdrm),
+		     elf->start_offset + offset) != sizeof (hdrm))
+	    return NULL;
+
+	  hdr = &hdrm;
+	}
+
+      len = atol (hdr->ar_size);
+
+      if (memcmp (hdr->ar_name, "//              ", 16) == 0)
+	break;
+
+      offset += sizeof (struct ar_hdr) + ((len + 1) & ~1l);
+    }
+
+  /* Due to the stupid format of the long name table entry (which are not
+     NUL terminted) we have to provide an appropriate representation anyhow.
+     Therefore we always make a copy which has the appropriate form.  */
+  newp = (char *) malloc (len);
+  if (newp != NULL)
+    {
+      char *runp;
+
+      if (elf->map_address != NULL)
+	/* Simply copy it over.  */
+	elf->state.ar.long_names = (char *) memcpy (newp,
+						    elf->map_address + offset
+						    + sizeof (struct ar_hdr),
+						    len);
+      else
+	{
+	  if ((size_t) pread (elf->fildes, newp, len,
+			      elf->start_offset + offset
+			      + sizeof (struct ar_hdr))
+	      != len)
+	    {
+	      /* We were not able to read all data.  */
+	      free (newp);
+	      elf->state.ar.long_names = NULL;
+	      return NULL;
+	    }
+	  elf->state.ar.long_names = newp;
+	}
+
+      elf->state.ar.long_names_len = len;
+
+      /* Now NUL-terminate the strings.  */
+      runp = newp;
+      while (1)
+        {
+	  runp = (char *) memchr (runp, '/', newp + len - runp);
+	  if (runp == NULL)
+	    /* This was the last entry.  */
+	    break;
+
+	  /* NUL-terminate the string.  */
+	  *runp = '\0';
+
+	  /* Skip the NUL bzte and the \012.  */
+	  runp += 2;
+
+	  /* A sanity check.  Somebody might have generated invalid
+	     archive.  */
+	  if (runp >= newp + len)
+	    break;
+	}
+    }
+
+  return newp;
+}
+
+
+/* Read the next archive header.  */
+int
+internal_function_def
+__libelf_next_arhdr (elf)
+     Elf *elf;
+{
+  struct ar_hdr *ar_hdr;
+  Elf_Arhdr *elf_ar_hdr;
+
+  if (elf->map_address != NULL)
+    {
+      /* See whether this entry is in the file.  */
+      if (elf->state.ar.offset + sizeof (struct ar_hdr)
+	  > elf->start_offset + elf->maximum_size)
+	{
+	  /* This record is not anymore in the file.  */
+	  __libelf_seterrno (ELF_E_RANGE);
+	  return -1;
+	}
+      ar_hdr = (struct ar_hdr *) (elf->map_address + elf->state.ar.offset);
+    }
+  else
+    {
+      ar_hdr = &elf->state.ar.ar_hdr;
+
+      if (pread (elf->fildes, ar_hdr, sizeof (struct ar_hdr),
+		 elf->state.ar.offset)
+	  != sizeof (struct ar_hdr))
+	{
+	  /* Something went wrong while reading the file.  */
+	  __libelf_seterrno (ELF_E_RANGE);
+	  return -1;
+	}
+    }
+
+  /* One little consistency check.  */
+  if (memcmp (ar_hdr->ar_fmag, ARFMAG, 2) != 0)
+    {
+      /* This is no valid archive.  */
+      __libelf_seterrno (ELF_E_ARCHIVE_FMAG);
+      return -1;
+    }
+
+  /* Copy the raw name over to a NUL terminated buffer.  */
+  *((char *) __mempcpy (elf->state.ar.raw_name, ar_hdr->ar_name, 16)) = '\0';
+
+  elf_ar_hdr = &elf->state.ar.elf_ar_hdr;
+
+  /* Now convert the `struct ar_hdr' into `Elf_Arhdr'.
+     Determine whether this is a special entry.  */
+  if (ar_hdr->ar_name[0] == '/')
+    {
+      if (ar_hdr->ar_name[1] == ' '
+	  && memcmp (ar_hdr->ar_name, "/               ", 16) == 0)
+	/* This is the index.  */
+	elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/", 2);
+      else if (ar_hdr->ar_name[1] == '/'
+	       && memcmp (ar_hdr->ar_name, "//              ", 16) == 0)
+	/* This is the array with the long names.  */
+	elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "//", 3);
+      else if (isdigit (ar_hdr->ar_name[1]))
+	{
+	  size_t offset;
+
+	  /* This is a long name.  First we have to read the long name
+	     table, if this hasn't happened already.  */
+	  if (elf->state.ar.long_names == NULL
+	      && read_long_names (elf) == NULL)
+	    {
+	      /* No long name table although it is reference.  The archive is
+		 broken.  */
+	      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
+	      return -1;
+	    }
+
+	  offset = atol (ar_hdr->ar_name + 1);
+	  if (offset >= elf->state.ar.long_names_len)
+	    {
+	      /* The index in the long name table is larger than the table.  */
+	      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
+	      return -1;
+	    }
+	  elf_ar_hdr->ar_name = elf->state.ar.long_names + offset;
+	}
+      else
+	{
+	  /* This is none of the known special entries.  */
+	  __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
+	  return -1;
+	}
+    }
+  else
+    {
+      char *endp;
+
+      /* It is a normal entry.  Copy over the name.  */
+      endp = (char *) memccpy (elf->state.ar.ar_name, ar_hdr->ar_name,
+			       '/', 16);
+      if (endp != NULL)
+	endp[-1] = '\0';
+      else
+	elf->state.ar.raw_name[16] = '\0';
+
+      elf_ar_hdr->ar_name = elf->state.ar.ar_name;
+    }
+
+  /* Since there are no specialized functions to convert ASCII to
+     time_t, uid_t, gid_t, mode_t, and off_t we use either atol or
+     atoll depending on the size of the types.  We are also prepared
+     for the case where the whole field in the `struct ar_hdr' is
+     filled in which case we cannot simply use atol/l but instead have
+     to create a temporary copy.  */
+  if (ar_hdr->ar_date[sizeof (ar_hdr->ar_date) - 1] == ' ')
+    {
+      if (ar_hdr->ar_date[0] == ' ')
+	elf_ar_hdr->ar_date = 0;
+      else
+	elf_ar_hdr->ar_date = (sizeof (time_t) <= sizeof (long int)
+			       ? (time_t) atol (ar_hdr->ar_date)
+			       : (time_t) atoll (ar_hdr->ar_date));
+    }
+  else
+    {
+      char buf[sizeof (ar_hdr->ar_date) + 1];
+      *((char *) __mempcpy (buf, ar_hdr->ar_date, sizeof (ar_hdr->ar_date)))
+	= '\0';
+      elf_ar_hdr->ar_date = (sizeof (time_t) <= sizeof (long int)
+			     ? (time_t) atol (ar_hdr->ar_date)
+			     : (time_t) atoll (ar_hdr->ar_date));
+    }
+
+  if (ar_hdr->ar_uid[sizeof (ar_hdr->ar_uid) - 1] == ' ')
+    {
+      if (ar_hdr->ar_uid[0] == ' ')
+	elf_ar_hdr->ar_uid = 0;
+      else
+	elf_ar_hdr->ar_uid = (sizeof (uid_t) <= sizeof (long int)
+			      ? (uid_t) atol (ar_hdr->ar_uid)
+			      : (uid_t) atoll (ar_hdr->ar_uid));
+    }
+  else
+    {
+      char buf[sizeof (ar_hdr->ar_uid) + 1];
+      *((char *) __mempcpy (buf, ar_hdr->ar_uid, sizeof (ar_hdr->ar_uid)))
+	= '\0';
+      elf_ar_hdr->ar_uid = (sizeof (uid_t) <= sizeof (long int)
+			     ? (uid_t) atol (ar_hdr->ar_uid)
+			     : (uid_t) atoll (ar_hdr->ar_uid));
+    }
+
+  if (ar_hdr->ar_gid[sizeof (ar_hdr->ar_gid) - 1] == ' ')
+    {
+      if (ar_hdr->ar_gid[0] == ' ')
+	elf_ar_hdr->ar_gid = 0;
+      else
+	elf_ar_hdr->ar_gid = (sizeof (gid_t) <= sizeof (long int)
+			      ? (gid_t) atol (ar_hdr->ar_gid)
+			      : (gid_t) atoll (ar_hdr->ar_gid));
+    }
+  else
+    {
+      char buf[sizeof (ar_hdr->ar_gid) + 1];
+      *((char *) __mempcpy (buf, ar_hdr->ar_gid, sizeof (ar_hdr->ar_gid)))
+	= '\0';
+      elf_ar_hdr->ar_gid = (sizeof (gid_t) <= sizeof (long int)
+			     ? (gid_t) atol (ar_hdr->ar_gid)
+			     : (gid_t) atoll (ar_hdr->ar_gid));
+    }
+
+  if (ar_hdr->ar_mode[sizeof (ar_hdr->ar_mode) - 1] == ' ')
+    {
+      if (ar_hdr->ar_mode[0] == ' ')
+	elf_ar_hdr->ar_mode = 0;
+      else
+	elf_ar_hdr->ar_mode = (sizeof (mode_t) <= sizeof (long int)
+			       ? (mode_t) strtol (ar_hdr->ar_mode, NULL, 8)
+			       : (mode_t) strtoll (ar_hdr->ar_mode, NULL, 8));
+    }
+  else
+    {
+      char buf[sizeof (ar_hdr->ar_mode) + 1];
+      *((char *) __mempcpy (buf, ar_hdr->ar_mode, sizeof (ar_hdr->ar_mode)))
+	= '\0';
+      elf_ar_hdr->ar_mode = (sizeof (mode_t) <= sizeof (long int)
+			     ? (mode_t) strtol (ar_hdr->ar_mode, NULL, 8)
+			     : (mode_t) strtoll (ar_hdr->ar_mode, NULL, 8));
+    }
+
+  if (ar_hdr->ar_size[sizeof (ar_hdr->ar_size) - 1] == ' ')
+    {
+      if (ar_hdr->ar_size[0] == ' ')
+	/* Something is really wrong.  We cannot live without a size for
+	   the member since it will not be possible to find the next
+	   archive member.  */
+	{
+	  __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
+	  return -1;
+	}
+      else
+	elf_ar_hdr->ar_size = (sizeof (time_t) == sizeof (long int)
+			       ? (off_t) atol (ar_hdr->ar_size)
+			       : (off_t) atoll (ar_hdr->ar_size));
+    }
+  else
+    {
+      char buf[sizeof (ar_hdr->ar_size) + 1];
+      *((char *) __mempcpy (buf, ar_hdr->ar_size, sizeof (ar_hdr->ar_size)))
+	= '\0';
+      elf_ar_hdr->ar_size = (sizeof (time_t) == sizeof (long int)
+			     ? (off_t) atol (ar_hdr->ar_size)
+			     : (off_t) atoll (ar_hdr->ar_size));
+    }
+
+  return 0;
+}
+
+
+/* We were asked to return a clone of an existing descriptor.  This
+   function must be called with the lock on the parent descriptor
+   being held. */
+static Elf *
+dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
+{
+  struct Elf *result;
+
+  if (fildes == -1)
+    /* Allow the user to pass -1 as the file descriptor for the new file.  */
+    fildes = ref->fildes;
+  /* The file descriptor better should be the same.  If it was disconnected
+     already (using `elf_cntl') we do not test it.  */
+  else if (ref->fildes != -1 && fildes != ref->fildes)
+    {
+      __libelf_seterrno (ELF_E_FD_MISMATCH);
+      return NULL;
+    }
+
+  /* The mode must allow reading.  I.e., a descriptor creating with a
+     command different then ELF_C_READ, ELF_C_WRITE and ELF_C_RDWR is
+     not allowed.  */
+  if (ref->cmd != ELF_C_READ && ref->cmd != ELF_C_READ_MMAP
+      && ref->cmd != ELF_C_WRITE && ref->cmd != ELF_C_WRITE_MMAP
+      && ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
+      && ref->cmd != ELF_C_READ_MMAP_PRIVATE)
+    {
+      __libelf_seterrno (ELF_E_INVALID_OP);
+      return NULL;
+    }
+
+  /* Now it is time to distinguish between reading normal files and
+     archives.  Normal files can easily be handled be incrementing the
+     reference counter and return the same descriptor.  */
+  if (ref->kind != ELF_K_AR)
+    {
+      ++ref->ref_count;
+      return ref;
+    }
+
+  /* This is an archive.  We must create a descriptor for the archive
+     member the internal pointer of the archive file desriptor is
+     pointing to.  First read the header of the next member if this
+     has not happened already.  */
+  if (ref->state.ar.elf_ar_hdr.ar_name == NULL
+      && __libelf_next_arhdr (ref) != 0)
+    /* Something went wrong.  Maybe there is no member left.  */
+    return NULL;
+
+  /* We have all the information we need about the next archive member.
+     Now create a descriptor for it.  */
+  result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr),
+		      ref->state.ar.elf_ar_hdr.ar_size, cmd, ref);
+
+  /* Enlist this new descriptor in the list of children.  */
+  if (result != NULL)
+    {
+      result->next = ref->state.ar.children;
+      ref->state.ar.children = result;
+    }
+
+  return result;
+}
+
+
+/* Return desriptor for empty file ready for writing.  */
+static struct Elf *
+write_file (int fd, Elf_Cmd cmd)
+{
+  /* We simply create an empty `Elf' structure.  */
+#define NSCNSALLOC	10
+  Elf *result = allocate_elf (fd, NULL, 0, 0, cmd, NULL, ELF_K_ELF,
+			      NSCNSALLOC * sizeof (Elf_Scn));
+
+  if (result != NULL)
+    {
+      /* We have to write to the file in any case.  */
+      result->flags = ELF_F_DIRTY;
+
+      /* Some more or less arbitrary value.  */
+      result->state.elf.scnincr = NSCNSALLOC;
+
+      /* We have allocated room for some sections.  */
+      assert (offsetof (struct Elf, state.elf32.scns)
+	      == offsetof (struct Elf, state.elf64.scns));
+      result->state.elf.scns_last = &result->state.elf32.scns;
+      result->state.elf32.scns.max = NSCNSALLOC;
+    }
+
+  return result;
+}
+
+
+/* Return a descriptor for the file belonging to FILDES.  */
+Elf *
+elf_begin (fildes, cmd, ref)
+     int fildes;
+     Elf_Cmd cmd;
+     Elf *ref;
+{
+  Elf *retval;
+
+  if (! __libelf_version_initialized)
+    {
+      /* Version wasn't set so far.  */
+      __libelf_seterrno (ELF_E_NO_VERSION);
+      return NULL;
+    }
+
+  if (ref != NULL)
+    /* Make sure the descriptor is not suddenly going away.  */
+    rwlock_rdlock (ref->lock);
+  else if (fcntl (fildes, F_GETFL) == -1 && errno == EBADF)
+    {
+      /* We cannot do anything productive without a file descriptor.  */
+      __libelf_seterrno (ELF_E_INVALID_FILE);
+      return NULL;
+    }
+
+  switch (cmd)
+    {
+    case ELF_C_NULL:
+      /* We simply return a NULL pointer.  */
+      retval = NULL;
+      break;
+
+    case ELF_C_READ_MMAP_PRIVATE:
+      /* If we have a reference it must also be opened this way.  */
+      if (ref != NULL && ref->cmd != ELF_C_READ_MMAP_PRIVATE)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_CMD);
+	  retval = NULL;
+	  break;
+	}
+      /* FALLTHROUGH */
+
+    case ELF_C_READ:
+    case ELF_C_READ_MMAP:
+      if (ref != NULL)
+	/* Duplicate the descriptor.  */
+	retval = dup_elf (fildes, cmd, ref);
+      else
+	/* Create descriptor for existing file.  */
+	retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
+      break;
+
+    case ELF_C_RDWR:
+    case ELF_C_RDWR_MMAP:
+      /* If we have a REF object it must also be opened using this
+	 command.  */
+      if (ref != NULL)
+	{
+	  if (ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
+	      && ref->cmd != ELF_C_WRITE && ref->cmd != ELF_C_WRITE_MMAP)
+	    {
+	      /* This is not ok.  REF must also be opened for writing.  */
+	      __libelf_seterrno (ELF_E_INVALID_CMD);
+	      retval = NULL;
+	    }
+	  else
+	    /* Duplicate this descriptor.  */
+	    retval = dup_elf (fildes, cmd, ref);
+	}
+      else
+	/* Create descriptor for existing file.  */
+	retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
+      break;
+
+    case ELF_C_WRITE:
+    case ELF_C_WRITE_MMAP:
+      /* We ignore REF and prepare a descriptor to write a new file.  */
+      retval = write_file (fildes, cmd);
+      break;
+
+    default:
+      __libelf_seterrno (ELF_E_INVALID_CMD);
+      retval = NULL;
+      break;
+    }
+
+  /* Release the lock.  */
+  if (ref != NULL)
+    rwlock_unlock (ref->lock);
+
+  return retval;
+}
+INTDEF(elf_begin)
diff --git a/libelf/elf_clone.c b/libelf/elf_clone.c
new file mode 100644
index 0000000..516d2ae
--- /dev/null
+++ b/libelf/elf_clone.c
@@ -0,0 +1,69 @@
+/* Create clone of a given descriptor.
+   Copyright (C) 2003, 2004 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+#include "libelfP.h"
+#include "common.h"
+
+
+Elf *
+elf_clone (Elf *elf, Elf_Cmd cmd)
+{
+  Elf *retval = NULL;
+
+  if (elf == NULL)
+    /* Some earlier mistake.  */
+    return NULL;
+
+  /* Make sure the descriptor is not suddenly going away.  */
+  rwlock_rdlock (elf->lock);
+
+  if (cmd != ELF_C_EMPTY)
+    // XXX TODO handle ELF_C_READ/WRITE etc
+    goto out;
+
+  retval = allocate_elf (elf->fildes, elf->map_address, elf->start_offset,
+			 elf->maximum_size, elf->cmd, elf->parent, elf->kind,
+			 elf->state.elf32.scns.max * sizeof (Elf_Scn));
+  if (retval != NULL)
+    {
+      /* We have to write to the file in any case.  */
+      retval->flags = ELF_F_DIRTY;
+
+      /* Some more or less arbitrary value.  */
+      retval->state.elf.scnincr = 10;
+
+      /* We have allocated room for some sections.  */
+      assert (offsetof (struct Elf, state.elf32.scns)
+	      == offsetof (struct Elf, state.elf64.scns));
+      retval->state.elf.scns_last = &retval->state.elf32.scns;
+      retval->state.elf32.scns.max = elf->state.elf32.scns.max;
+
+      retval->class = elf->class;
+    }
+
+  /* Release the lock.  */
+ out:
+  rwlock_unlock (elf->lock);
+
+  return retval;
+}
diff --git a/libelf/elf_cntl.c b/libelf/elf_cntl.c
new file mode 100644
index 0000000..eea0f36
--- /dev/null
+++ b/libelf/elf_cntl.c
@@ -0,0 +1,71 @@
+/* Control an ELF file desrciptor.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <unistd.h>
+
+#include "libelfP.h"
+
+
+int
+elf_cntl (elf, cmd)
+     Elf *elf;
+     Elf_Cmd cmd;
+{
+  int result = 0;
+
+  if (elf == NULL)
+    return -1;
+
+  if (elf->fildes == -1)
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return -1;
+    }
+
+  rwlock_wrlock (elf->lock);
+
+  switch (cmd)
+    {
+    case ELF_C_FDREAD:
+      /* If not all of the file is in the memory read it now.  */
+      if (elf->map_address == NULL && __libelf_readall (elf) == NULL)
+	{
+	  /* We were not able to read everything.  */
+	  result = -1;
+	  break;
+	}
+      /* FALLTHROUGH */
+
+    case ELF_C_FDDONE:
+      /* Mark the file descriptor as not usable.  */
+      elf->fildes = -1;
+      break;
+
+    default:
+      __libelf_seterrno (ELF_E_INVALID_CMD);
+      result = -1;
+      break;
+    }
+
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/libelf/elf_end.c b/libelf/elf_end.c
new file mode 100644
index 0000000..33626f0
--- /dev/null
+++ b/libelf/elf_end.c
@@ -0,0 +1,203 @@
+/* Free resources associated with Elf descriptor.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+
+#include "libelfP.h"
+
+
+int
+elf_end (elf)
+     Elf *elf;
+{
+  Elf *parent;
+
+  if (elf == NULL)
+    /* This is allowed and is a no-op.  */
+    return 0;
+
+  /* Make sure we are alone.  */
+  rwlock_wrlock (elf->lock);
+
+  if (elf->ref_count != 0 && --elf->ref_count != 0)
+    {
+      /* Not yet the last activation.  */
+      int result = elf->ref_count;
+      rwlock_unlock (elf->lock);
+      return result;
+    }
+
+  if (elf->kind == ELF_K_AR)
+    {
+      /* We cannot remove the descriptor now since we still have some
+	 descriptors which depend on it.  But we can free the archive
+	 symbol table since this is only available via the archive ELF
+	 descriptor.  The long name table cannot be freed yet since
+	 the archive headers for the ELF files in the archive point
+	 into this array.  */
+      free (elf->state.ar.ar_sym);
+      elf->state.ar.ar_sym = NULL;
+
+      if (elf->state.ar.children != NULL)
+	return 0;
+    }
+
+  /* Remove this structure from the children list.  */
+  parent = elf->parent;
+  if (parent != NULL)
+    {
+      /* This is tricky.  Lock must be acquire from the father to
+	 the child but here we already have the child lock.  We
+	 solve this problem by giving free the child lock.  The
+	 state of REF_COUNT==0 is handled all over the library, so
+	 this should be ok.  */
+      rwlock_unlock (elf->lock);
+      rwlock_rdlock (parent->lock);
+      rwlock_wrlock (elf->lock);
+
+      if (parent->state.ar.children == elf)
+	parent->state.ar.children = elf->next;
+      else
+	{
+	  struct Elf *child = parent->state.ar.children;
+
+	  while (child->next != elf)
+	    child = child->next;
+
+	  child->next = elf->next;
+	}
+
+      rwlock_unlock (parent->lock);
+    }
+
+  /* This was the last activation.  Free all resources.  */
+  switch (elf->kind)
+    {
+    case ELF_K_AR:
+      if (elf->state.ar.long_names != NULL)
+	free (elf->state.ar.long_names);
+      break;
+
+    case ELF_K_ELF:
+      {
+	Elf_ScnList *list = (elf->class == ELFCLASS32
+			     || (offsetof (struct Elf, state.elf32.scns)
+				 == offsetof (struct Elf, state.elf64.scns))
+			     ? &elf->state.elf32.scns
+			     : &elf->state.elf64.scns);
+
+	do
+	  {
+	    /* Free all separately allocated section headers.  */
+	    size_t cnt = list->max;
+
+	    while (cnt-- > 0)
+	      {
+		/* These pointers can be NULL; it's safe to use
+		   'free' since it will check for this.  */
+		Elf_Scn *scn = &list->data[cnt];
+		Elf_Data_List *runp;
+
+		if ((scn->shdr_flags & ELF_F_MALLOCED) != 0)
+		  /* It doesn't matter which pointer.  */
+		  free (scn->shdr.e32);
+
+		/* If the file has the same byte order and the
+		   architecture doesn't require overly stringent
+		   alignment the raw data buffer is the same as the
+		   one used for presenting to the caller.  */
+		if (scn->data_base != scn->rawdata_base)
+		  free (scn->data_base);
+
+		/* The section data is allocated if we couldn't mmap
+		   the file.  */
+		if (elf->map_address == NULL)
+		  free (scn->rawdata_base);
+
+		/* Free the list of data buffers for the section.
+		   We don't free the buffers themselves since this
+		   is the users job.  */
+		runp = scn->data_list.next;
+		while (runp != NULL)
+		  {
+		    Elf_Data_List *oldp = runp;
+		    runp = runp->next;
+		    if ((oldp->flags & ELF_F_MALLOCED) != 0)
+		      free (oldp);
+		  }
+	      }
+
+	    /* Free the memory for the array.  */
+	    Elf_ScnList *oldp = list;
+	    list = list->next;
+	    assert (list == NULL || oldp->cnt == oldp->max);
+	    if (oldp != (elf->class == ELFCLASS32
+			 || (offsetof (struct Elf, state.elf32.scns)
+			     == offsetof (struct Elf, state.elf64.scns))
+			 ? &elf->state.elf32.scns
+			 : &elf->state.elf64.scns))
+	      free (oldp);
+	  }
+	while (list != NULL);
+      }
+
+      /* Free the section header.  */
+      if (elf->state.elf.shdr_malloced  != 0)
+	free (elf->class == ELFCLASS32
+	      || (offsetof (struct Elf, state.elf32.shdr)
+		  == offsetof (struct Elf, state.elf64.shdr))
+	      ? (void *) elf->state.elf32.shdr
+	      : (void *) elf->state.elf64.shdr);
+
+      /* Free the program header.  */
+      if ((elf->state.elf.phdr_flags & ELF_F_MALLOCED) != 0)
+	free (elf->class == ELFCLASS32
+	      || (offsetof (struct Elf, state.elf32.phdr)
+		  == offsetof (struct Elf, state.elf64.phdr))
+	      ? (void *) elf->state.elf32.phdr
+	      : (void *) elf->state.elf64.phdr);
+      break;
+
+    default:
+      break;
+    }
+
+  if (elf->map_address != NULL && parent == NULL)
+    {
+      /* The file was read or mapped for this descriptor.  */
+      if ((elf->flags & ELF_F_MALLOCED) != 0)
+	free (elf->map_address);
+      else if ((elf->flags & ELF_F_MMAPPED) != 0)
+	munmap (elf->map_address, elf->maximum_size);
+    }
+
+  rwlock_fini (elf->lock);
+
+  /* Finally the descriptor itself.  */
+  free (elf);
+
+  return (parent != NULL && parent->ref_count == 0
+	  ? INTUSE(elf_end) (parent) : 0);
+}
+INTDEF(elf_end)
diff --git a/libelf/elf_error.c b/libelf/elf_error.c
new file mode 100644
index 0000000..168ce11
--- /dev/null
+++ b/libelf/elf_error.c
@@ -0,0 +1,366 @@
+/* Error handling in libelf.
+   Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libintl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+#ifdef USE_TLS
+/* The error number.  */
+static __thread int global_error;
+#else
+/* This is the key for the thread specific memory.  */
+static tls_key_t key;
+
+/* The error number.  Used in non-threaded programs.  */
+static int global_error;
+static bool threaded;
+/* We need to initialize the thread-specific data.  */
+once_define (static, once);
+
+/* The initialization and destruction functions.  */
+static void init (void);
+static void free_key_mem (void *mem);
+#endif	/* TLS */
+
+
+int
+elf_errno (void)
+{
+  int result;
+
+#ifndef USE_TLS
+  /* If we have not yet initialized the buffer do it now.  */
+  once_execute (once, init);
+
+  if (threaded)
+    {
+    /* We do not allocate memory for the data.  It is only a word.
+       We can store it in place of the pointer.  */
+      result = (intptr_t) getspecific (key);
+
+      setspecific (key, (void *) (intptr_t) ELF_E_NOERROR);
+      return result;
+    }
+#endif	/* TLS */
+
+  result = global_error;
+  global_error = ELF_E_NOERROR;
+  return result;
+}
+
+
+/* Return the appropriate message for the error.  */
+static const char msgstr[] =
+{
+#define ELF_E_NOERROR_IDX 0
+  N_("no error")
+  "\0"
+#define ELF_E_UNKNOWN_ERROR_IDX (ELF_E_NOERROR_IDX + sizeof "no error")
+  N_("unknown error")
+  "\0"
+#define ELF_E_UNKNOWN_VERSION_IDX \
+  (ELF_E_UNKNOWN_ERROR_IDX + sizeof "unknown error")
+  N_("unknown version")
+  "\0"
+#define ELF_E_UNKNOWN_TYPE_IDX \
+  (ELF_E_UNKNOWN_VERSION_IDX + sizeof "unknown version")
+  N_("unknown type")
+  "\0"
+#define ELF_E_INVALID_HANDLE_IDX \
+  (ELF_E_UNKNOWN_TYPE_IDX + sizeof "unknown type")
+  N_("invalid `Elf' handle")
+  "\0"
+#define ELF_E_SOURCE_SIZE_IDX \
+  (ELF_E_INVALID_HANDLE_IDX + sizeof "invalid `Elf' handle")
+  N_("invalid size of source operand")
+  "\0"
+#define ELF_E_DEST_SIZE_IDX \
+  (ELF_E_SOURCE_SIZE_IDX + sizeof "invalid size of source operand")
+  N_("invalid size of destination operand")
+  "\0"
+#define ELF_E_INVALID_ENCODING_IDX \
+  (ELF_E_DEST_SIZE_IDX + sizeof "invalid size of destination operand")
+  N_("invalid encoding")
+  "\0"
+#define ELF_E_NOMEM_IDX \
+  (ELF_E_INVALID_ENCODING_IDX + sizeof "invalid encoding")
+  N_("out of memory")
+  "\0"
+#define ELF_E_INVALID_FILE_IDX \
+  (ELF_E_NOMEM_IDX + sizeof "out of memory")
+  N_("invalid file descriptor")
+  "\0"
+#define ELF_E_INVALID_OP_IDX \
+  (ELF_E_INVALID_FILE_IDX + sizeof "invalid file descriptor")
+  N_("invalid operation")
+  "\0"
+#define ELF_E_NO_VERSION_IDX \
+  (ELF_E_INVALID_OP_IDX + sizeof "invalid operation")
+  N_("ELF version not set")
+  "\0"
+#define ELF_E_INVALID_CMD_IDX \
+  (ELF_E_NO_VERSION_IDX + sizeof "ELF version not set")
+  N_("invalid command")
+  "\0"
+#define ELF_E_RANGE_IDX \
+  (ELF_E_INVALID_CMD_IDX + sizeof "invalid command")
+  N_("offset out of range")
+  "\0"
+#define ELF_E_ARCHIVE_FMAG_IDX \
+  (ELF_E_RANGE_IDX + sizeof "offset out of range")
+  N_("invalid fmag field in archive header")
+  "\0"
+#define ELF_E_INVALID_ARCHIVE_IDX \
+  (ELF_E_ARCHIVE_FMAG_IDX + sizeof "invalid fmag field in archive header")
+  N_("invalid archive file")
+  "\0"
+#define ELF_E_NO_ARCHIVE_IDX \
+  (ELF_E_INVALID_ARCHIVE_IDX + sizeof "invalid archive file")
+  N_("descriptor is not for an archive")
+  "\0"
+#define ELF_E_NO_INDEX_IDX \
+  (ELF_E_NO_ARCHIVE_IDX + sizeof "descriptor is not for an archive")
+  N_("no index available")
+  "\0"
+#define ELF_E_READ_ERROR_IDX \
+  (ELF_E_NO_INDEX_IDX + sizeof "no index available")
+  N_("cannot read data from file")
+  "\0"
+#define ELF_E_WRITE_ERROR_IDX \
+  (ELF_E_READ_ERROR_IDX + sizeof "cannot read data from file")
+  N_("cannot write data to file")
+  "\0"
+#define ELF_E_INVALID_CLASS_IDX \
+  (ELF_E_WRITE_ERROR_IDX + sizeof "cannot write data to file")
+  N_("invalid binary class")
+  "\0"
+#define ELF_E_INVALID_INDEX_IDX \
+  (ELF_E_INVALID_CLASS_IDX + sizeof "invalid binary class")
+  N_("invalid section index")
+  "\0"
+#define ELF_E_INVALID_OPERAND_IDX \
+  (ELF_E_INVALID_INDEX_IDX + sizeof "invalid section index")
+  N_("invalid operand")
+  "\0"
+#define ELF_E_INVALID_SECTION_IDX \
+  (ELF_E_INVALID_OPERAND_IDX + sizeof "invalid operand")
+  N_("invalid section")
+  "\0"
+#define ELF_E_INVALID_COMMAND_IDX \
+  (ELF_E_INVALID_SECTION_IDX + sizeof "invalid section")
+  N_("invalid command")
+  "\0"
+#define ELF_E_WRONG_ORDER_EHDR_IDX \
+  (ELF_E_INVALID_COMMAND_IDX + sizeof "invalid command")
+  N_("executable header not created first")
+  "\0"
+#define ELF_E_FD_DISABLED_IDX \
+  (ELF_E_WRONG_ORDER_EHDR_IDX + sizeof "executable header not created first")
+  N_("file descriptor disabled")
+  "\0"
+#define ELF_E_FD_MISMATCH_IDX \
+  (ELF_E_FD_DISABLED_IDX + sizeof "file descriptor disabled")
+  N_("archive/member fildes mismatch")
+  "\0"
+#define ELF_E_OFFSET_RANGE_IDX \
+  (ELF_E_FD_MISMATCH_IDX + sizeof "archive/member fildes mismatch")
+  N_("offset out of range")
+  "\0"
+#define ELF_E_NOT_NUL_SECTION_IDX \
+  (ELF_E_OFFSET_RANGE_IDX + sizeof "offset out of range")
+  N_("cannot manipulate null section")
+  "\0"
+#define ELF_E_DATA_MISMATCH_IDX \
+  (ELF_E_NOT_NUL_SECTION_IDX + sizeof "cannot manipulate null section")
+  N_("data/scn mismatch")
+  "\0"
+#define ELF_E_INVALID_SECTION_HEADER_IDX \
+  (ELF_E_DATA_MISMATCH_IDX + sizeof "data/scn mismatch")
+  N_("invalid section header")
+  "\0"
+#define ELF_E_INVALID_DATA_IDX \
+  (ELF_E_INVALID_SECTION_HEADER_IDX + sizeof "invalid section header")
+  N_("invalid data")
+  "\0"
+#define ELF_E_DATA_ENCODING_IDX \
+  (ELF_E_INVALID_DATA_IDX + sizeof "invalid data")
+  N_("unknown data encoding")
+  "\0"
+#define ELF_E_SECTION_TOO_SMALL_IDX \
+  (ELF_E_DATA_ENCODING_IDX + sizeof "unknown data encoding")
+  N_("section `sh_size' too small for data")
+  "\0"
+#define ELF_E_INVALID_ALIGN_IDX \
+  (ELF_E_SECTION_TOO_SMALL_IDX + sizeof "section `sh_size' too small for data")
+  N_("invalid section alignment")
+  "\0"
+#define ELF_E_INVALID_SHENTSIZE_IDX \
+  (ELF_E_INVALID_ALIGN_IDX + sizeof "invalid section alignment")
+  N_("invalid section entry size")
+  "\0"
+#define ELF_E_UPDATE_RO_IDX \
+  (ELF_E_INVALID_SHENTSIZE_IDX + sizeof "invalid section entry size")
+  N_("update() for write on read-only file")
+  "\0"
+#define ELF_E_NOFILE_IDX \
+  (ELF_E_UPDATE_RO_IDX + sizeof "update() for write on read-only file")
+  N_("no such file")
+  "\0"
+#define ELF_E_GROUP_NOT_REL_IDX \
+  (ELF_E_NOFILE_IDX + sizeof "no such file")
+  N_("only relocatable files can contain section groups")
+  "\0"
+#define ELF_E_INVALID_PHDR_IDX \
+  (ELF_E_GROUP_NOT_REL_IDX \
+   + sizeof "only relocatable files can contain section groups")
+  N_("program header only allowed in executables and shared objects")
+  "\0"
+#define ELF_E_NO_PHDR_IDX \
+  (ELF_E_INVALID_PHDR_IDX \
+   + sizeof "program header only allowed in executables and shared objects")
+  N_("file has no program header")
+};
+
+
+static const uint_fast16_t msgidx[ELF_E_NUM] =
+{
+  [ELF_E_NOERROR] = ELF_E_NOERROR_IDX,
+  [ELF_E_UNKNOWN_ERROR] = ELF_E_UNKNOWN_ERROR_IDX,
+  [ELF_E_UNKNOWN_VERSION] = ELF_E_UNKNOWN_VERSION_IDX,
+  [ELF_E_UNKNOWN_TYPE] = ELF_E_UNKNOWN_TYPE_IDX,
+  [ELF_E_INVALID_HANDLE] = ELF_E_INVALID_HANDLE_IDX,
+  [ELF_E_SOURCE_SIZE] = ELF_E_SOURCE_SIZE_IDX,
+  [ELF_E_DEST_SIZE] = ELF_E_DEST_SIZE_IDX,
+  [ELF_E_INVALID_ENCODING] = ELF_E_INVALID_ENCODING_IDX,
+  [ELF_E_NOMEM] = ELF_E_NOMEM_IDX,
+  [ELF_E_INVALID_FILE] = ELF_E_INVALID_FILE_IDX,
+  [ELF_E_INVALID_OP] = ELF_E_INVALID_OP_IDX,
+  [ELF_E_NO_VERSION] = ELF_E_NO_VERSION_IDX,
+  [ELF_E_INVALID_CMD] = ELF_E_INVALID_CMD_IDX,
+  [ELF_E_RANGE] = ELF_E_RANGE_IDX,
+  [ELF_E_ARCHIVE_FMAG] = ELF_E_ARCHIVE_FMAG_IDX,
+  [ELF_E_INVALID_ARCHIVE] = ELF_E_INVALID_ARCHIVE_IDX,
+  [ELF_E_NO_ARCHIVE] = ELF_E_NO_ARCHIVE_IDX,
+  [ELF_E_NO_INDEX] = ELF_E_NO_INDEX_IDX,
+  [ELF_E_READ_ERROR] = ELF_E_READ_ERROR_IDX,
+  [ELF_E_WRITE_ERROR] = ELF_E_WRITE_ERROR_IDX,
+  [ELF_E_INVALID_CLASS] = ELF_E_INVALID_CLASS_IDX,
+  [ELF_E_INVALID_INDEX] = ELF_E_INVALID_INDEX_IDX,
+  [ELF_E_INVALID_OPERAND] = ELF_E_INVALID_OPERAND_IDX,
+  [ELF_E_INVALID_SECTION] = ELF_E_INVALID_SECTION_IDX,
+  [ELF_E_INVALID_COMMAND] = ELF_E_INVALID_COMMAND_IDX,
+  [ELF_E_WRONG_ORDER_EHDR] = ELF_E_WRONG_ORDER_EHDR_IDX,
+  [ELF_E_FD_DISABLED] = ELF_E_FD_DISABLED_IDX,
+  [ELF_E_FD_MISMATCH] = ELF_E_FD_MISMATCH_IDX,
+  [ELF_E_OFFSET_RANGE] = ELF_E_OFFSET_RANGE_IDX,
+  [ELF_E_NOT_NUL_SECTION] = ELF_E_NOT_NUL_SECTION_IDX,
+  [ELF_E_DATA_MISMATCH] = ELF_E_DATA_MISMATCH_IDX,
+  [ELF_E_INVALID_SECTION_HEADER] = ELF_E_INVALID_SECTION_HEADER_IDX,
+  [ELF_E_INVALID_DATA] = ELF_E_INVALID_DATA_IDX,
+  [ELF_E_DATA_ENCODING] = ELF_E_DATA_ENCODING_IDX,
+  [ELF_E_SECTION_TOO_SMALL] = ELF_E_SECTION_TOO_SMALL_IDX,
+  [ELF_E_INVALID_ALIGN] = ELF_E_INVALID_ALIGN_IDX,
+  [ELF_E_INVALID_SHENTSIZE] = ELF_E_INVALID_SHENTSIZE_IDX,
+  [ELF_E_UPDATE_RO] = ELF_E_UPDATE_RO_IDX,
+  [ELF_E_NOFILE] = ELF_E_NOFILE_IDX,
+  [ELF_E_GROUP_NOT_REL] = ELF_E_GROUP_NOT_REL_IDX,
+  [ELF_E_INVALID_PHDR] = ELF_E_INVALID_PHDR_IDX,
+  [ELF_E_NO_PHDR] = ELF_E_NO_PHDR_IDX
+};
+#define nmsgidx ((int) (sizeof (msgidx) / sizeof (msgidx[0])))
+
+
+void
+__libelf_seterrno (value)
+     int value;
+{
+#ifndef USE_TLS
+  /* If we have not yet initialized the buffer do it now.  */
+  once_execute (once, init);
+
+  if (threaded)
+    /* We do not allocate memory for the data.  It is only a word.
+       We can store it in place of the pointer.  */
+    setspecific (key, (void *) (intptr_t) value);
+#endif	/* TLS */
+
+  global_error = value >= 0 && value < nmsgidx ? value : ELF_E_UNKNOWN_ERROR;
+}
+
+
+const char *
+elf_errmsg (error)
+     int error;
+{
+  int last_error;
+
+#ifndef USE_TLS
+  /* If we have not yet initialized the buffer do it now.  */
+  once_execute (once, init);
+
+  if ((error == 0 || error == -1) && threaded)
+    /* We do not allocate memory for the data.  It is only a word.
+       We can store it in place of the pointer.  */
+    last_error = (intptr_t) getspecific (key);
+  else
+#endif	/* TLS */
+    last_error = global_error;
+
+  if (error == 0)
+    {
+      assert (msgidx[last_error] < sizeof (msgstr));
+      return last_error != 0 ? _(msgstr + msgidx[last_error]) : NULL;
+    }
+  else if (error < -1 || error >= nmsgidx)
+    return _(msgstr + ELF_E_UNKNOWN_ERROR_IDX);
+
+  assert (msgidx[error == -1 ? last_error : error] < sizeof (msgstr));
+  return _(msgstr + msgidx[error == -1 ? last_error : error]);
+}
+
+
+#ifndef USE_TLS
+/* Free the thread specific data, this is done if a thread terminates.  */
+static void
+free_key_mem (void *mem __attribute__ ((unused)))
+{
+  setspecific (key, NULL);
+}
+
+
+/* Initialize the key for the global variable.  */
+static void
+init (void)
+{
+  // XXX Screw you, gcc4, the unused function attribute does not work.
+  __asm ("" :: "r" (free_key_mem));
+
+  if (key_create (&key, free_key_mem) == 0)
+    /* Creating the key succeeded.  */
+    threaded = true;
+}
+#endif	/* TLS */
diff --git a/libelf/elf_fill.c b/libelf/elf_fill.c
new file mode 100644
index 0000000..f09cc7b
--- /dev/null
+++ b/libelf/elf_fill.c
@@ -0,0 +1,35 @@
+/* Set fill byte used when constructing ELF objects.
+   Copyright (C) 1998, 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+
+#include "libelfP.h"
+
+
+int __libelf_fill_byte;
+
+
+void
+elf_fill (fill)
+     int fill;
+{
+  __libelf_fill_byte = fill;
+}
diff --git a/libelf/elf_flagdata.c b/libelf/elf_flagdata.c
new file mode 100644
index 0000000..b519131
--- /dev/null
+++ b/libelf/elf_flagdata.c
@@ -0,0 +1,59 @@
+/* Manipulate ELF data flag.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagdata (data, cmd, flags)
+     Elf_Data *data;
+     Elf_Cmd cmd;
+     unsigned int flags;
+{
+  Elf_Data_Scn *data_scn;
+  unsigned int result;
+
+  if (data == NULL)
+    return 0;
+
+  data_scn = (Elf_Data_Scn *) data;
+
+  if (data_scn == NULL || unlikely (data_scn->s->elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  if (likely (cmd == ELF_C_SET))
+    result = (data_scn->s->flags |= (flags & ELF_F_DIRTY));
+  else if (likely (cmd == ELF_C_CLR))
+    result = (data_scn->s->flags &= ~(flags & ELF_F_DIRTY));
+  else
+    {
+      __libelf_seterrno (ELF_E_INVALID_COMMAND);
+      return 0;
+    }
+
+  return result;
+}
diff --git a/libelf/elf_flagehdr.c b/libelf/elf_flagehdr.c
new file mode 100644
index 0000000..2099fc5
--- /dev/null
+++ b/libelf/elf_flagehdr.c
@@ -0,0 +1,56 @@
+/* Manipulate ELF header flags.
+   Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagehdr (elf, cmd, flags)
+     Elf *elf;
+     Elf_Cmd cmd;
+     unsigned int flags;
+{
+  unsigned int result;
+
+  if (elf == NULL)
+    return 0;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  if (likely (cmd == ELF_C_SET))
+    result = (elf->state.elf.ehdr_flags |= (flags & ELF_F_DIRTY));
+  else if (cmd == ELF_C_CLR)
+    result = (elf->state.elf.ehdr_flags &= ~(flags & ELF_F_DIRTY));
+  else
+    {
+      __libelf_seterrno (ELF_E_INVALID_COMMAND);
+      return 0;
+    }
+
+  return result;
+}
diff --git a/libelf/elf_flagelf.c b/libelf/elf_flagelf.c
new file mode 100644
index 0000000..3a001f6
--- /dev/null
+++ b/libelf/elf_flagelf.c
@@ -0,0 +1,58 @@
+/* Manipulate ELF file flags.
+   Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagelf (elf, cmd, flags)
+     Elf *elf;
+     Elf_Cmd cmd;
+     unsigned int flags;
+{
+  unsigned int result;
+
+  if (elf == NULL)
+    return 0;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  if (likely (cmd == ELF_C_SET))
+    result = (elf->flags
+	      |= (flags & (ELF_F_DIRTY | ELF_F_LAYOUT | ELF_F_PERMISSIVE)));
+  else if (likely (cmd == ELF_C_CLR))
+    result = (elf->flags
+	      &= ~(flags & (ELF_F_DIRTY | ELF_F_LAYOUT | ELF_F_PERMISSIVE)));
+  else
+    {
+      __libelf_seterrno (ELF_E_INVALID_COMMAND);
+      return 0;
+    }
+
+  return result;
+}
diff --git a/libelf/elf_flagphdr.c b/libelf/elf_flagphdr.c
new file mode 100644
index 0000000..c2f8794
--- /dev/null
+++ b/libelf/elf_flagphdr.c
@@ -0,0 +1,56 @@
+/* Manipulate ELF program header flags.
+   Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagphdr (elf, cmd, flags)
+     Elf *elf;
+     Elf_Cmd cmd;
+     unsigned int flags;
+{
+  unsigned int result;
+
+  if (elf == NULL)
+    return 0;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  if (likely (cmd == ELF_C_SET))
+    result = (elf->state.elf.phdr_flags |= (flags & ELF_F_DIRTY));
+  else if (likely (cmd == ELF_C_CLR))
+    result = (elf->state.elf.phdr_flags &= ~(flags & ELF_F_DIRTY));
+  else
+    {
+      __libelf_seterrno (ELF_E_INVALID_COMMAND);
+      return 0;
+    }
+
+  return result;
+}
diff --git a/libelf/elf_flagscn.c b/libelf/elf_flagscn.c
new file mode 100644
index 0000000..9cd1cc4
--- /dev/null
+++ b/libelf/elf_flagscn.c
@@ -0,0 +1,56 @@
+/* Manipulate ELF section flags.
+   Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagscn (scn, cmd, flags)
+     Elf_Scn *scn;
+     Elf_Cmd cmd;
+     unsigned int flags;
+{
+  unsigned int result;
+
+  if (scn == NULL)
+    return 0;
+
+  if (unlikely (scn->elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  if (likely (cmd == ELF_C_SET))
+    result = (scn->flags |= (flags & ELF_F_DIRTY));
+  else if (likely (cmd == ELF_C_CLR))
+    result = (scn->flags &= ~(flags & ELF_F_DIRTY));
+  else
+    {
+      __libelf_seterrno (ELF_E_INVALID_COMMAND);
+      return 0;
+    }
+
+  return result;
+}
diff --git a/libelf/elf_flagshdr.c b/libelf/elf_flagshdr.c
new file mode 100644
index 0000000..0972d27
--- /dev/null
+++ b/libelf/elf_flagshdr.c
@@ -0,0 +1,56 @@
+/* Manipulate ELF section header flags.
+   Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagshdr (scn, cmd, flags)
+     Elf_Scn *scn;
+     Elf_Cmd cmd;
+     unsigned int flags;
+{
+  unsigned int result;
+
+  if (scn == NULL)
+    return 0;
+
+  if (unlikely (scn->elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  if (likely (cmd == ELF_C_SET))
+    result = (scn->shdr_flags |= (flags & ELF_F_DIRTY));
+  else if (likely (cmd == ELF_C_CLR))
+    result = (scn->shdr_flags &= ~(flags & ELF_F_DIRTY));
+  else
+    {
+      __libelf_seterrno (ELF_E_INVALID_COMMAND);
+      return 0;
+    }
+
+  return result;
+}
diff --git a/libelf/elf_getarhdr.c b/libelf/elf_getarhdr.c
new file mode 100644
index 0000000..da0b4a4
--- /dev/null
+++ b/libelf/elf_getarhdr.c
@@ -0,0 +1,53 @@
+/* Read header of next archive member.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Arhdr *
+elf_getarhdr (elf)
+     Elf *elf;
+{
+  Elf *parent = elf->parent;
+
+  /* Calling this function is not ok for any file type but archives.  */
+  if (parent == NULL)
+    {
+      __libelf_seterrno (ELF_E_INVALID_OP);
+      return NULL;
+    }
+
+  /* Make sure we have read the archive header.  */
+  if (parent->state.ar.elf_ar_hdr.ar_name == NULL
+      && __libelf_next_arhdr (parent) != 0)
+    /* Something went wrong.  Maybe there is no member left.  */
+    return NULL;
+
+
+  /* We can be sure the parent is an archive.  */
+  assert (parent->kind == ELF_K_AR);
+
+  return &parent->state.ar.elf_ar_hdr;
+}
diff --git a/libelf/elf_getarsym.c b/libelf/elf_getarsym.c
new file mode 100644
index 0000000..1dafa9a
--- /dev/null
+++ b/libelf/elf_getarsym.c
@@ -0,0 +1,241 @@
+/* Return symbol table of archive.
+   Copyright (C) 1998, 1999, 2000, 2002, 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <dl-hash.h>
+#include "libelfP.h"
+
+
+Elf_Arsym *
+elf_getarsym (elf, ptr)
+     Elf *elf;
+     size_t *ptr;
+{
+  if (elf->kind != ELF_K_AR)
+    {
+      /* This is no archive.  */
+      __libelf_seterrno (ELF_E_NO_ARCHIVE);
+      return NULL;
+    }
+
+  if (ptr != NULL)
+    /* In case of an error or when we know the value store the expected
+       value now.  Doing this allows us easier exits in an error case.  */
+    *ptr = elf->state.ar.ar_sym_num;
+
+  if (elf->state.ar.ar_sym == (Elf_Arsym *) -1l)
+    {
+      /* There is no index.  */
+      __libelf_seterrno (ELF_E_NO_INDEX);
+      return NULL;
+    }
+
+  Elf_Arsym *result = elf->state.ar.ar_sym;
+  if (result == NULL)
+    {
+      /* We have not yet read the index.  */
+      rwlock_wrlock (elf->lock);
+
+      /* In case we find no index remember this for the next call.  */
+      elf->state.ar.ar_sym = (Elf_Arsym *) -1l;
+
+      struct ar_hdr *index_hdr;
+      if (elf->map_address == NULL)
+	{
+	  /* We must read index from the file.  */
+	  assert (elf->fildes != -1);
+	  if (pread (elf->fildes, &elf->state.ar.ar_hdr,
+		     sizeof (struct ar_hdr), elf->start_offset + SARMAG)
+	      != sizeof (struct ar_hdr))
+	    {
+	      /* It is not possible to read the index.  Maybe it does not
+		 exist.  */
+	      __libelf_seterrno (ELF_E_READ_ERROR);
+	      goto out;
+	    }
+
+	  index_hdr = &elf->state.ar.ar_hdr;
+	}
+      else
+	{
+	  if (SARMAG + sizeof (struct ar_hdr) > elf->maximum_size)
+	    {
+	      /* There is no room for the full archive.  */
+	      __libelf_seterrno (ELF_E_NO_INDEX);
+	      goto out;
+	    }
+
+	  index_hdr = (struct ar_hdr *) (elf->map_address
+					 + elf->start_offset + SARMAG);
+	}
+
+      /* Now test whether this really is an archive.  */
+      if (memcmp (index_hdr->ar_fmag, ARFMAG, 2) != 0)
+	{
+	  /* Invalid magic bytes.  */
+	  __libelf_seterrno (ELF_E_ARCHIVE_FMAG);
+	  goto out;
+	}
+
+      /* Now test whether this is the index.  It is denoted by the
+	 name being "/ ".
+	 XXX This is not entirely true.  There are some more forms.
+	 Which of them shall we handle?  */
+      if (memcmp (index_hdr->ar_name, "/               ", 16) != 0)
+	{
+	  /* If the index is not the first entry, there is no index.
+
+	     XXX Is this true?  */
+	  __libelf_seterrno (ELF_E_NO_INDEX);
+	  goto out;
+	}
+
+      /* We have an archive.  The first word in there is the number of
+	 entries in the table.  */
+      uint32_t n;
+      if (elf->map_address == NULL)
+	{
+	  if (pread (elf->fildes, &n, sizeof (n),
+		     elf->start_offset + SARMAG + sizeof (struct ar_hdr))
+	      != sizeof (n))
+	    {
+	      /* Cannot read the number of entries.  */
+	      __libelf_seterrno (ELF_E_NO_INDEX);
+	      goto out;
+	    }
+	}
+      else
+	n = *(uint32_t *) (elf->map_address + elf->start_offset
+			   + SARMAG + sizeof (struct ar_hdr));
+
+      if (__BYTE_ORDER == __LITTLE_ENDIAN)
+	n = bswap_32 (n);
+
+      /* Now we can perform some first tests on whether all the data
+	 needed for the index is available.  */
+      char tmpbuf[17];
+      memcpy (tmpbuf, index_hdr->ar_size, 10);
+      tmpbuf[10] = '\0';
+      size_t index_size = atol (tmpbuf);
+
+      if (SARMAG + sizeof (struct ar_hdr) + index_size > elf->maximum_size
+	  || n * sizeof (uint32_t) > index_size)
+	{
+	  /* This index table cannot be right since it does not fit into
+	     the file.  */
+	  __libelf_seterrno (ELF_E_NO_INDEX);
+	  goto out;
+	}
+
+      /* Now we can allocate the arrays needed to store the index.  */
+      size_t ar_sym_len = (n + 1) * sizeof (Elf_Arsym);
+      elf->state.ar.ar_sym = (Elf_Arsym *) malloc (ar_sym_len);
+      if (elf->state.ar.ar_sym != NULL)
+	{
+	  uint32_t *file_data;
+	  char *str_data;
+
+	  if (elf->map_address == NULL)
+	    {
+	      file_data = (uint32_t *) alloca (n * sizeof (uint32_t));
+
+	      ar_sym_len += index_size - n * sizeof (uint32_t);
+	      Elf_Arsym *newp = (Elf_Arsym *) realloc (elf->state.ar.ar_sym,
+						       ar_sym_len);
+	      if (newp == NULL)
+		{
+		  free (elf->state.ar.ar_sym);
+		  elf->state.ar.ar_sym = NULL;
+		  __libelf_seterrno (ELF_E_NOMEM);
+		  goto out;
+		}
+	      elf->state.ar.ar_sym = newp;
+
+	      char *new_str = (char *) (elf->state.ar.ar_sym + n + 1);
+
+	      /* Now read the data from the file.  */
+	      if ((size_t) pread (elf->fildes, file_data,
+				  n * sizeof (uint32_t), elf->start_offset
+				  + SARMAG + sizeof (struct ar_hdr)
+				  + sizeof (uint32_t)) != n * sizeof (uint32_t)
+		  || ((size_t) pread (elf->fildes, new_str,
+				      index_size - n * sizeof (uint32_t),
+				      elf->start_offset
+				      + SARMAG + sizeof (struct ar_hdr)
+				      + (n + 1) * sizeof (uint32_t))
+		      != index_size - n * sizeof (uint32_t)))
+		{
+		  /* We were not able to read the data.  */
+		  free (elf->state.ar.ar_sym);
+		  elf->state.ar.ar_sym = NULL;
+		  __libelf_seterrno (ELF_E_NO_INDEX);
+		  goto out;
+		}
+
+	      str_data = (char *) new_str;
+	    }
+	  else
+	    {
+	      file_data = (uint32_t *) (elf->map_address + elf->start_offset
+					+ SARMAG + sizeof (struct ar_hdr)
+					+ sizeof (uint32_t));
+	      str_data = (char *) &file_data[n];
+	    }
+
+	  /* Now we can build the data structure.  */
+	  Elf_Arsym *arsym = elf->state.ar.ar_sym;
+	  for (size_t cnt = 0; cnt < n; ++cnt)
+	    {
+	      arsym[cnt].as_name = str_data;
+	      if (__BYTE_ORDER == __LITTLE_ENDIAN)
+		arsym[cnt].as_off = bswap_32 (file_data[cnt]);
+	      else
+		arsym[cnt].as_off = file_data[cnt];
+	      arsym[cnt].as_hash = _dl_elf_hash (str_data);
+	      str_data = rawmemchr (str_data, '\0') + 1;
+	    }
+	  /* At the end a special entry.  */
+	  arsym[n].as_name = NULL;
+	  arsym[n].as_off = 0;
+	  arsym[n].as_hash = ~0UL;
+
+	  /* Tell the caller how many entries we have.  */
+	  elf->state.ar.ar_sym_num = n + 1;
+	}
+
+      result = elf->state.ar.ar_sym;
+
+    out:
+      rwlock_unlock (elf->lock);
+    }
+
+  if (ptr != NULL)
+    *ptr = elf->state.ar.ar_sym_num;
+
+  return result;
+}
diff --git a/libelf/elf_getbase.c b/libelf/elf_getbase.c
new file mode 100644
index 0000000..ea76f41
--- /dev/null
+++ b/libelf/elf_getbase.c
@@ -0,0 +1,33 @@
+/* Return offset of first byte for the object.
+   Copyright (C) 1998, 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+off_t
+elf_getbase (elf)
+     Elf *elf;
+{
+  return elf == NULL ? (off_t) -1 : elf->start_offset;
+}
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
new file mode 100644
index 0000000..20e8e62
--- /dev/null
+++ b/libelf/elf_getdata.c
@@ -0,0 +1,454 @@
+/* Return the next data element from the section after possibly converting it.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "libelfP.h"
+#include "common.h"
+#include "elf-knowledge.h"
+
+
+#if _STRING_ARCH_unaligned
+# define ALLOW_ALIGNED	1
+#else
+# define ALLOW_ALIGNED	0
+#endif
+
+
+#define TYPEIDX(Sh_Type) \
+  (Sh_Type >= SHT_NULL && Sh_Type < SHT_NUM				      \
+   ? Sh_Type								      \
+   : (Sh_Type >= SHT_GNU_LIBLIST && Sh_Type <= SHT_HISUNW		      \
+      ? SHT_NUM + Sh_Type - SHT_GNU_LIBLIST				      \
+      : 0))
+
+static const struct
+{
+  Elf_Type type;
+  size_t size;
+#if ALLOW_ALIGNED
+# define AL(val)
+#else
+  size_t align;
+# define AL(val), val
+#endif
+} shtype_map[EV_NUM - 1][ELFCLASSNUM - 1][TYPEIDX (SHT_HISUNW) + 1] =
+{
+  [EV_CURRENT - 1] =
+  {
+    [ELFCLASS32 - 1] =
+    {
+      /* Associate section types with libelf types, their sizes and
+	 alignment.  SHT_GNU_verdef is special since the section does
+	 not contain entries of only one size.  */
+#define DEFINE(Bits) \
+      [SHT_SYMTAB] = { ELF_T_SYM, sizeof (ElfW2(Bits,Sym))		      \
+		       AL (__alignof__ (ElfW2(Bits,Sym))) },		      \
+      [SHT_RELA] = { ELF_T_RELA, sizeof (ElfW2(Bits,Rela))		      \
+		       AL (__alignof__ (ElfW2(Bits,Rela))) },		      \
+      [SHT_HASH] = { ELF_T_WORD, sizeof (ElfW2(Bits,Word))		      \
+		       AL (__alignof__ (ElfW2(Bits,Word))) },		      \
+      [SHT_DYNAMIC] = { ELF_T_DYN, sizeof (ElfW2(Bits,Dyn))		      \
+		       AL (__alignof__ (ElfW2(Bits,Dyn))) },		      \
+      [SHT_REL] = { ELF_T_REL, sizeof (ElfW2(Bits,Rel))			      \
+		       AL (__alignof__ (ElfW2(Bits,Rel))) },		      \
+      [SHT_DYNSYM] = { ELF_T_SYM, sizeof (ElfW2(Bits,Sym))		      \
+		       AL (__alignof__ (ElfW2(Bits,Sym))) },		      \
+      [SHT_INIT_ARRAY] = { ELF_T_ADDR, sizeof (ElfW2(Bits,Addr))	      \
+			   AL (__alignof__ (ElfW2(Bits,Addr))) },	      \
+      [SHT_FINI_ARRAY] = { ELF_T_ADDR, sizeof (ElfW2(Bits,Addr))	      \
+			   AL (__alignof__ (ElfW2(Bits,Addr))) },	      \
+      [SHT_PREINIT_ARRAY] = { ELF_T_ADDR, sizeof (ElfW2(Bits,Addr))	      \
+			      AL (__alignof__ (ElfW2(Bits,Addr))) },	      \
+      [SHT_GROUP] = { ELF_T_WORD, sizeof (Elf32_Word)			      \
+		      AL (__alignof__ (Elf32_Word)) },			      \
+      [SHT_SYMTAB_SHNDX] = { ELF_T_WORD, sizeof (Elf32_Word)		      \
+			     AL (__alignof__ (Elf32_Word)) },		      \
+      [TYPEIDX (SHT_GNU_verdef)] = { ELF_T_VDEF, 1 AL (1) },		      \
+      [TYPEIDX (SHT_GNU_verneed)] = { ELF_T_VNEED,			      \
+				      sizeof (ElfW2(Bits,Verneed))	      \
+				      AL (__alignof__ (ElfW2(Bits,Verneed)))},\
+      [TYPEIDX (SHT_GNU_versym)] = { ELF_T_HALF, sizeof (ElfW2(Bits,Versym))  \
+				     AL (__alignof__ (ElfW2(Bits,Versym))) }, \
+      [TYPEIDX (SHT_SUNW_syminfo)] = { ELF_T_SYMINFO,			      \
+				       sizeof (ElfW2(Bits,Syminfo))	      \
+				       AL(__alignof__ (ElfW2(Bits,Syminfo)))},\
+      [TYPEIDX (SHT_SUNW_move)] = { ELF_T_MOVE, sizeof (ElfW2(Bits,Move))     \
+				    AL (__alignof__ (ElfW2(Bits,Move))) },    \
+      [TYPEIDX (SHT_GNU_LIBLIST)] = { ELF_T_LIB, sizeof (ElfW2(Bits,Lib))     \
+				    AL (__alignof__ (ElfW2(Bits,Lib))) }
+      DEFINE (32)
+    },
+    [ELFCLASS64 - 1] =
+    {
+      DEFINE (64)
+    }
+  }
+};
+
+
+/* Convert the data in the current section.  */
+static void
+convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass,
+	      int data, size_t size, size_t type)
+{
+#if ALLOW_ALIGNED
+  /* No need to compute the alignment requirement of the host.  */
+  const size_t align = 1;
+#else
+# if EV_NUM != 2
+  size_t align = shtype_map[version - 1][eclass - 1][type].align;
+# else
+  size_t align = shtype_map[0][eclass - 1][type].align;
+# endif
+#endif
+
+  if (data == MY_ELFDATA)
+    {
+      if (ALLOW_ALIGNED
+	  || (((size_t) ((char *) scn->rawdata_base)) & (align - 1)) == 0)
+	/* No need to copy, we can use the raw data.  */
+	scn->data_base = scn->rawdata_base;
+      else
+	{
+	  scn->data_base = (char *) malloc (size);
+	  if (scn->data_base == NULL)
+	    {
+	      __libelf_seterrno (ELF_E_NOMEM);
+	      return;
+	    }
+
+	  /* The copy will be appropriately aligned for direct access.  */
+	  memcpy (scn->data_base, scn->rawdata_base, size);
+	}
+    }
+  else
+    {
+      xfct_t fp;
+
+      scn->data_base = (char *) malloc (size);
+      if (scn->data_base == NULL)
+	{
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  return;
+	}
+
+      /* Get the conversion function.  */
+#if EV_NUM != 2
+      fp = __elf_xfctstom[version - 1][__libelf_version - 1][eclass - 1][type];
+#else
+      fp = __elf_xfctstom[0][0][eclass - 1][type];
+#endif
+
+      fp (scn->data_base, scn->rawdata_base, size, 0);
+    }
+
+  scn->data_list.data.d.d_buf = scn->data_base;
+  scn->data_list.data.d.d_size = size;
+  scn->data_list.data.d.d_type = type;
+  scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
+  scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
+  scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
+
+  scn->data_list.data.s = scn;
+}
+
+
+/* Store the information for the raw data in the `rawdata' element.  */
+int
+internal_function_def
+__libelf_set_rawdata (Elf_Scn *scn)
+{
+  size_t offset;
+  size_t size;
+  size_t align;
+  int type;
+  Elf *elf = scn->elf;
+
+  if (elf->class == ELFCLASS32)
+    {
+      Elf32_Shdr *shdr = scn->shdr.e32 ?: INTUSE(elf32_getshdr) (scn);
+
+      if (shdr == NULL)
+	/* Something went terribly wrong.  */
+	return 1;
+
+      offset = shdr->sh_offset;
+      size = shdr->sh_size;
+      type = shdr->sh_type;
+      align = shdr->sh_addralign;
+    }
+  else
+    {
+      Elf64_Shdr *shdr = scn->shdr.e64 ?: INTUSE(elf64_getshdr) (scn);
+
+      if (shdr == NULL)
+	/* Something went terribly wrong.  */
+	return 1;
+
+      offset = shdr->sh_offset;
+      size = shdr->sh_size;
+      type = shdr->sh_type;
+      align = shdr->sh_addralign;
+    }
+
+  /* If the section has no data (for whatever reason), leave the `d_buf'
+     pointer NULL.  */
+  if (size != 0 && type != SHT_NOBITS)
+    {
+      /* First a test whether the section is valid at all.  */
+      size_t entsize;
+
+      if (type == SHT_HASH)
+	{
+	  GElf_Ehdr ehdr_mem;
+
+	  entsize = SH_ENTSIZE_HASH (INTUSE(gelf_getehdr) (elf, &ehdr_mem));
+	}
+      else
+	{
+#if EV_NUM != 2
+	  entsize = shtype_map[__libelf_version - 1][elf->class - 1][TYPEIDX (type)].size;
+#else
+	  entsize = shtype_map[0][elf->class - 1][TYPEIDX (type)].size;
+#endif
+	}
+
+      /* We assume it is an array of bytes if it is none of the structured
+	 sections we know of.  */
+      if (entsize == 0)
+	entsize = 1;
+
+      if (size % entsize != 0)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  return 1;
+	}
+
+      /* We can use the mapped or loaded data if available.  */
+      if (elf->map_address != NULL)
+	{
+	  /* First see whether the information in the section header is
+	     valid and it does not ask for too much.  */
+	  if (offset + size > elf->maximum_size)
+	    {
+	      /* Something is wrong.  */
+	      __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+	      return 1;
+	    }
+
+	  scn->rawdata_base = scn->rawdata.d.d_buf
+	    = (char *) elf->map_address + elf->start_offset + offset;
+	}
+      else if (elf->fildes != -1)
+	{
+	  /* We have to read the data from the file.  Allocate the needed
+	     memory.  */
+	  scn->rawdata_base = scn->rawdata.d.d_buf
+	    = (char *) malloc (size);
+	  if (scn->rawdata.d.d_buf == NULL)
+	    {
+	      __libelf_seterrno (ELF_E_NOMEM);
+	      return 1;
+	    }
+
+	  if ((size_t) pread (elf->fildes, scn->rawdata.d.d_buf, size,
+			      elf->start_offset + offset) != size)
+	    {
+	      /* Cannot read the data.  */
+	      free (scn->rawdata.d.d_buf);
+	      scn->rawdata_base = scn->rawdata.d.d_buf = NULL;
+	      __libelf_seterrno (ELF_E_READ_ERROR);
+	      return 1;
+	    }
+	}
+      else
+	{
+	  /* The file descriptor is already closed, we cannot get the data
+	     anymore.  */
+	  __libelf_seterrno (ELF_E_FD_DISABLED);
+	  return 1;
+	}
+    }
+
+  scn->rawdata.d.d_size = size;
+  /* Some broken ELF ABI for 64-bit machines use the wrong hash table
+     entry size.  See elf-knowledge.h for more information.  */
+  if (type == SHT_HASH && elf->class == ELFCLASS64)
+    {
+      GElf_Ehdr ehdr_mem;
+
+      scn->rawdata.d.d_type
+	= (SH_ENTSIZE_HASH (INTUSE(gelf_getehdr) (elf, &ehdr_mem))
+	   == 4 ? ELF_T_WORD : ELF_T_XWORD);
+    }
+  else
+    {
+#if EV_NUM != 2
+      scn->rawdata.d.d_type =
+	shtype_map[__libelf_version - 1][elf->class - 1][TYPEIDX (type)].type;
+#else
+      scn->rawdata.d.d_type =
+	shtype_map[0][elf->class - 1][TYPEIDX (type)].type;
+#endif
+    }
+  scn->rawdata.d.d_off = 0;
+  scn->rawdata.d.d_align = align;
+  if (elf->class == ELFCLASS32
+      || (offsetof (struct Elf, state.elf32.ehdr)
+	  == offsetof (struct Elf, state.elf64.ehdr)))
+    scn->rawdata.d.d_version =
+      elf->state.elf32.ehdr->e_ident[EI_VERSION];
+  else
+    scn->rawdata.d.d_version =
+      elf->state.elf64.ehdr->e_ident[EI_VERSION];
+
+  scn->rawdata.s = scn;
+
+  scn->data_read = 1;
+
+  /* We actually read data from the file.  At least we tried.  */
+  scn->flags |= ELF_F_FILEDATA;
+
+  return 0;
+}
+
+
+Elf_Data *
+elf_getdata (scn, data)
+     Elf_Scn *scn;
+     Elf_Data *data;
+{
+  Elf_Data *result = NULL;
+  Elf *elf;
+
+  if (scn == NULL)
+    return NULL;
+
+  if (unlikely (scn->elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* We will need this multiple times later on.  */
+  elf = scn->elf;
+
+  rwlock_rdlock (elf->lock);
+
+  /* If `data' is not NULL this means we are not addressing the initial
+     data in the file.  But this also means this data is already read
+     (since otherwise it is not possible to have a valid `data' pointer)
+     and all the data structures are initialized as well.  In this case
+     we can simply walk the list of data records.  */
+  if (data != NULL)
+    {
+      Elf_Data_List *runp;
+
+      /* It is not possible that if DATA is not NULL the first entry is
+	 returned.  But this also means that there must be a first data
+	 entry.  */
+      if (scn->data_list_rear == NULL
+	  /* The section the reference data is for must match the section
+	     parameter.  */
+	  || unlikely (((Elf_Data_Scn *) data)->s != scn))
+	{
+	  __libelf_seterrno (ELF_E_DATA_MISMATCH);
+	  goto out;
+	}
+
+      /* We start searching with the first entry.  */
+      runp = &scn->data_list;
+
+      while (1)
+	{
+	  /* If `data' does not match any known record punt.  */
+	  if (runp == NULL)
+	    {
+	      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+	      goto out;
+	    }
+
+	  if (&runp->data.d == data)
+	    /* Found the entry.  */
+	    break;
+
+	  runp = runp->next;
+	}
+
+      /* Return the data for the next data record.  */
+      result = runp->next ? &runp->next->data.d : NULL;
+      goto out;
+    }
+
+  /* If the data for this section was not yet initialized do it now.  */
+  if (scn->data_read == 0)
+    {
+      /* We cannot acquire a write lock while we are holding a read
+         lock.  Therefore give up the read lock and then get the write
+         lock.  But this means that the data could meanwhile be
+         modified, therefore start the tests again.  */
+      rwlock_unlock (elf->lock);
+      rwlock_wrlock (elf->lock);
+
+      /* Read the data from the file.  There is always a file (or
+	 memory region) associated with this descriptor since
+	 otherwise the `data_read' flag would be set.  */
+      if (scn->data_read == 0 && __libelf_set_rawdata (scn) != 0)
+	/* Something went wrong.  The error value is already set.  */
+	goto out;
+    }
+
+  /* At this point we know the raw data is available.  But it might be
+     empty in case the section has size zero (for whatever reason).
+     Now create the converted data in case this is necessary.  */
+  if (scn->data_list_rear == NULL)
+    {
+      if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
+	/* Convert according to the version and the type.   */
+	convert_data (scn, __libelf_version, elf->class,
+		      (elf->class == ELFCLASS32
+		       || (offsetof (struct Elf, state.elf32.ehdr)
+			   == offsetof (struct Elf, state.elf64.ehdr))
+		       ? elf->state.elf32.ehdr->e_ident[EI_DATA]
+		       : elf->state.elf64.ehdr->e_ident[EI_DATA]),
+		      scn->rawdata.d.d_size, scn->rawdata.d.d_type);
+      else
+	/* This is an empty or NOBITS section.  There is no buffer but
+	   the size information etc is important.  */
+	scn->data_list.data.d = scn->rawdata.d;
+
+      scn->data_list_rear = &scn->data_list;
+    }
+
+  /* If no data is present we cannot return any.  */
+  if (scn->data_list_rear != NULL)
+    /* Return the first data element in the list.  */
+    result = &scn->data_list.data.d;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elf_getdata)
diff --git a/libelf/elf_getident.c b/libelf/elf_getident.c
new file mode 100644
index 0000000..b673b5c
--- /dev/null
+++ b/libelf/elf_getident.c
@@ -0,0 +1,51 @@
+/* Retrieve file identification data.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+char *
+elf_getident (elf, ptr)
+     Elf *elf;
+     size_t *ptr;
+{
+  /* In case this is no ELF file, the handle is invalid and we return
+     NULL.  */
+  if (elf == NULL || elf->kind != ELF_K_ELF)
+    {
+      if (ptr != NULL)
+	*ptr = 0;
+      return NULL;
+    }
+
+  /* We already read the ELF header.  Return a pointer to it and store
+     the length in *PTR.  */
+  if (ptr != NULL)
+    *ptr = EI_NIDENT;
+
+  return (char *) (elf->class == ELFCLASS32
+		   || (offsetof (struct Elf, state.elf32.ehdr)
+		       == offsetof (struct Elf, state.elf64.ehdr))
+		   ? elf->state.elf32.ehdr->e_ident
+		   : elf->state.elf64.ehdr->e_ident);
+}
diff --git a/libelf/elf_getscn.c b/libelf/elf_getscn.c
new file mode 100644
index 0000000..a6b4767
--- /dev/null
+++ b/libelf/elf_getscn.c
@@ -0,0 +1,77 @@
+/* Get section at specific index.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+Elf_Scn *
+elf_getscn (elf, idx)
+     Elf *elf;
+     size_t idx;
+{
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  rwlock_rdlock (elf->lock);
+
+  Elf_Scn *result = NULL;
+
+  /* Find the section in the list.  */
+  Elf_ScnList *runp = (elf->class == ELFCLASS32
+		       || (offsetof (struct Elf, state.elf32.scns)
+			   == offsetof (struct Elf, state.elf64.scns))
+		       ? &elf->state.elf32.scns : &elf->state.elf64.scns);
+  while (1)
+    {
+      if (idx < runp->max)
+	{
+	  if (idx < runp->cnt)
+	    result = &runp->data[idx];
+	  else
+	    __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  break;
+	}
+
+      idx -= runp->max;
+
+      runp = runp->next;
+      if (runp == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  break;
+	}
+    }
+
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elf_getscn)
diff --git a/libelf/elf_getshnum.c b/libelf/elf_getshnum.c
new file mode 100644
index 0000000..52d6a05
--- /dev/null
+++ b/libelf/elf_getshnum.c
@@ -0,0 +1,64 @@
+/* Return number of sections in the ELF file.
+   Copyright (C) 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+int
+elf_getshnum (elf, dst)
+     Elf *elf;
+     size_t *dst;
+{
+  int result = 0;
+  int idx;
+
+  if (elf == NULL)
+    return -1;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return -1;
+    }
+
+  rwlock_rdlock (elf->lock);
+
+  idx = elf->state.elf.scns_last->cnt;
+  if (idx != 0
+      || (elf->state.elf.scns_last
+	  != (elf->class == ELFCLASS32
+	      || (offsetof (Elf, state.elf32.scns)
+		  == offsetof (Elf, state.elf64.scns))
+	      ? &elf->state.elf32.scns : &elf->state.elf64.scns)))
+    /* There is at least one section.  */
+    *dst = 1 + elf->state.elf.scns_last->data[idx - 1].index;
+  else
+    *dst = 0;
+
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elf_getshnum)
diff --git a/libelf/elf_getshstrndx.c b/libelf/elf_getshstrndx.c
new file mode 100644
index 0000000..706092b
--- /dev/null
+++ b/libelf/elf_getshstrndx.c
@@ -0,0 +1,168 @@
+/* Return section index of section header string table.
+   Copyright (C) 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stddef.h>
+#include <unistd.h>
+
+#include "libelfP.h"
+#include "common.h"
+
+
+int
+elf_getshstrndx (elf, dst)
+     Elf *elf;
+     size_t *dst;
+{
+  int result = 0;
+
+  if (elf == NULL)
+    return -1;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return -1;
+    }
+
+  rwlock_rdlock (elf->lock);
+
+  /* We rely here on the fact that the `elf' element is a common prefix
+     of `elf32' and `elf64'.  */
+  assert (offsetof (struct Elf, state.elf.ehdr)
+	  == offsetof (struct Elf, state.elf32.ehdr));
+  assert (sizeof (elf->state.elf.ehdr)
+	  == sizeof (elf->state.elf32.ehdr));
+  assert (offsetof (struct Elf, state.elf.ehdr)
+	  == offsetof (struct Elf, state.elf64.ehdr));
+  assert (sizeof (elf->state.elf.ehdr)
+	  == sizeof (elf->state.elf64.ehdr));
+
+  if (unlikely (elf->state.elf.ehdr == NULL))
+    {
+      __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+      result = -1;
+    }
+  else
+    {
+      Elf32_Word num;
+
+      num = (elf->class == ELFCLASS32
+	     ? elf->state.elf32.ehdr->e_shstrndx
+	     : elf->state.elf64.ehdr->e_shstrndx);
+
+      /* Determine whether the index is too big to fit in the ELF
+	 header.  */
+      if (unlikely (num == SHN_XINDEX))
+	{
+	  /* Yes.  Search the zeroth section header.  */
+	  if (elf->class == ELFCLASS32)
+	    {
+	      size_t offset;
+
+	      if (elf->state.elf32.scns.data[0].shdr.e32 != NULL)
+		{
+		  num = elf->state.elf32.scns.data[0].shdr.e32->sh_link;
+		  goto success;
+		}
+
+	      offset = elf->state.elf32.ehdr->e_shoff;
+
+	      if (elf->map_address != NULL
+		  && elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA
+		  && (ALLOW_UNALIGNED
+		      || (((size_t) ((char *) elf->map_address + offset))
+			  & (__alignof__ (Elf32_Shdr) - 1)) == 0))
+		/* We can directly access the memory.  */
+		num = ((Elf32_Shdr *) (elf->map_address + offset))->sh_link;
+	      else
+		{
+		  /* We avoid reading in all the section headers.  Just read
+		     the first one.  */
+		  Elf32_Shdr shdr_mem;
+
+		  if (pread (elf->fildes, &shdr_mem, sizeof (Elf32_Shdr),
+			     offset) != sizeof (Elf32_Shdr))
+		    {
+		      /* We must be able to read this ELF section header.  */
+		      __libelf_seterrno (ELF_E_INVALID_FILE);
+		      result = -1;
+		      goto out;
+		    }
+
+		  if (elf->state.elf32.ehdr->e_ident[EI_DATA] != MY_ELFDATA)
+		    CONVERT (shdr_mem.sh_link);
+		  num = shdr_mem.sh_link;
+		}
+	    }
+	  else
+	    {
+	      size_t offset;
+
+	      if (elf->state.elf64.scns.data[0].shdr.e64 != NULL)
+		{
+		  num = elf->state.elf64.scns.data[0].shdr.e64->sh_link;
+		  goto success;
+		}
+
+	      offset = elf->state.elf64.ehdr->e_shoff;
+
+	      if (elf->map_address != NULL
+		  && elf->state.elf64.ehdr->e_ident[EI_DATA] == MY_ELFDATA
+		  && (ALLOW_UNALIGNED
+		      || (((size_t) ((char *) elf->map_address + offset))
+			  & (__alignof__ (Elf64_Shdr) - 1)) == 0))
+		/* We can directly access the memory.  */
+		num = ((Elf64_Shdr *) (elf->map_address + offset))->sh_link;
+	      else
+		{
+		  /* We avoid reading in all the section headers.  Just read
+		     the first one.  */
+		  Elf64_Shdr shdr_mem;
+
+		  if (pread (elf->fildes, &shdr_mem, sizeof (Elf64_Shdr),
+			     offset) != sizeof (Elf64_Shdr))
+		    {
+		      /* We must be able to read this ELF section header.  */
+		      __libelf_seterrno (ELF_E_INVALID_FILE);
+		      result = -1;
+		      goto out;
+		    }
+
+		  if (elf->state.elf64.ehdr->e_ident[EI_DATA] != MY_ELFDATA)
+		    CONVERT (shdr_mem.sh_link);
+		  num = shdr_mem.sh_link;
+		}
+	    }
+	}
+
+      /* Store the result.  */
+    success:
+      *dst = num;
+    }
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elf_getshstrndx)
diff --git a/libelf/elf_hash.c b/libelf/elf_hash.c
new file mode 100644
index 0000000..38f4ae0
--- /dev/null
+++ b/libelf/elf_hash.c
@@ -0,0 +1,33 @@
+/* Hash function used in ELF implementations.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelfP.h>
+
+/* Get the implementation.  */
+#include <dl-hash.h>
+
+unsigned long int
+elf_hash (string)
+     const char *string;
+{
+  return _dl_elf_hash (string);
+}
+INTDEF(elf_hash)
diff --git a/libelf/elf_kind.c b/libelf/elf_kind.c
new file mode 100644
index 0000000..a67ebe7
--- /dev/null
+++ b/libelf/elf_kind.c
@@ -0,0 +1,33 @@
+/* Return the kind of file associated with the descriptor.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Kind
+elf_kind (elf)
+     Elf *elf;
+{
+  return elf == NULL ? ELF_K_NONE : elf->kind;
+}
diff --git a/libelf/elf_memory.c b/libelf/elf_memory.c
new file mode 100644
index 0000000..57221f9
--- /dev/null
+++ b/libelf/elf_memory.c
@@ -0,0 +1,40 @@
+/* Create descriptor for memory region.
+   Copyright (C) 1999, 2000, 2002 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf *
+elf_memory (image, size)
+     char *image;
+     size_t size;
+{
+  if (image == NULL)
+    {
+      __libelf_seterrno (ELF_E_INVALID_OPERAND);
+      return NULL;
+    }
+
+  return __libelf_read_mmaped_file (-1, image, 0, size, ELF_C_READ, NULL);
+}
diff --git a/libelf/elf_ndxscn.c b/libelf/elf_ndxscn.c
new file mode 100644
index 0000000..edd6bda
--- /dev/null
+++ b/libelf/elf_ndxscn.c
@@ -0,0 +1,36 @@
+/* Get index of section.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+size_t
+elf_ndxscn (scn)
+     Elf_Scn *scn;
+{
+  if (scn == NULL)
+    return SHN_UNDEF;
+
+  return scn->index;
+}
diff --git a/libelf/elf_newdata.c b/libelf/elf_newdata.c
new file mode 100644
index 0000000..bae3b3f
--- /dev/null
+++ b/libelf/elf_newdata.c
@@ -0,0 +1,97 @@
+/* Create new, empty section data.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+Elf_Data *
+elf_newdata (Elf_Scn *scn)
+{
+  Elf_Data_List *result = NULL;
+
+  if (scn == NULL)
+    return NULL;
+
+  if (unlikely (scn->index == 0))
+    {
+      /* It is not allowed to add something to the 0th section.  */
+      __libelf_seterrno (ELF_E_NOT_NUL_SECTION);
+      return NULL;
+    }
+
+  if (scn->elf->class == ELFCLASS32
+      || (offsetof (struct Elf, state.elf32.ehdr)
+	  == offsetof (struct Elf, state.elf64.ehdr))
+      ? scn->elf->state.elf32.ehdr == NULL
+      : scn->elf->state.elf64.ehdr == NULL)
+    {
+      __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+      return NULL;
+    }
+
+  rwlock_wrlock (scn->elf->lock);
+
+  if (scn->data_read && scn->data_list_rear == NULL)
+    {
+      /* This means the section was created by the user and this is the
+	 first data.  */
+      result = &scn->data_list;
+      result->flags = ELF_F_DIRTY;
+    }
+  else
+    {
+      /* Create a new, empty data descriptor.  */
+      result = (Elf_Data_List *) calloc (1, sizeof (Elf_Data_List));
+      if (result == NULL)
+	{
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  goto out;
+	}
+
+      result->flags = ELF_F_DIRTY | ELF_F_MALLOCED;
+
+      if (scn->data_list_rear == NULL)
+	/* We create new data without reading/converting the data from the
+	   file.  That is fine but we have to remember this.  */
+	scn->data_list_rear = &scn->data_list;
+    }
+
+  /* Set the predefined values.  */
+  result->data.d.d_version = __libelf_version;
+
+  result->data.s = scn;
+
+  /* Add to the end of the list.  */
+  if (scn->data_list_rear != NULL)
+    scn->data_list_rear->next = result;
+
+  scn->data_list_rear = result;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  /* Please note that the following is thread safe and is also defined
+     for RESULT == NULL since it still return NULL.  */
+  return &result->data.d;
+}
diff --git a/libelf/elf_newscn.c b/libelf/elf_newscn.c
new file mode 100644
index 0000000..f3ea0d8
--- /dev/null
+++ b/libelf/elf_newscn.c
@@ -0,0 +1,143 @@
+/* Append new section.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+Elf_Scn *
+elf_newscn (elf)
+     Elf *elf;
+{
+  Elf_Scn *result = NULL;
+  bool first = false;
+
+  if (elf == NULL)
+    return NULL;
+
+  /* We rely on the prefix of the `elf', `elf32', and `elf64' element
+     being the same.  */
+  assert (offsetof (Elf, state.elf.scns_last)
+	  == offsetof (Elf, state.elf32.scns_last));
+  assert (offsetof (Elf, state.elf.scns_last)
+	  == offsetof (Elf, state.elf64.scns_last));
+  assert (offsetof (Elf, state.elf32.scns)
+	  == offsetof (Elf, state.elf64.scns));
+
+  rwlock_wrlock (elf->lock);
+
+ again:
+  if (elf->state.elf.scns_last->cnt < elf->state.elf.scns_last->max)
+    {
+      result = &elf->state.elf.scns_last->data[elf->state.elf.scns_last->cnt];
+
+      if (++elf->state.elf.scns_last->cnt == 1
+	  && (elf->state.elf.scns_last
+	      == (elf->class == ELFCLASS32
+		  || (offsetof (Elf, state.elf32.scns)
+		      == offsetof (Elf, state.elf64.scns))
+		  ? &elf->state.elf32.scns : &elf->state.elf64.scns)))
+	/* This is zeroth section.  */
+	first = true;
+      else
+	{
+	  assert (elf->state.elf.scns_last->cnt > 1);
+	  result->index = result[-1].index + 1;
+	}
+    }
+  else
+    {
+      /* We must allocate a new element.  */
+      Elf_ScnList *newp;
+
+      assert (elf->state.elf.scnincr > 0);
+
+      newp = (Elf_ScnList *) calloc (sizeof (Elf_ScnList)
+				     + ((elf->state.elf.scnincr *= 2)
+					* sizeof (Elf_Scn)), 1);
+      if (newp == NULL)
+	{
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  goto out;
+	}
+
+      result = &newp->data[0];
+
+      /* One section used.  */
+      ++newp->cnt;
+
+      /* This is the number of sections we allocated.  */
+      newp->max = elf->state.elf.scnincr;
+
+      /* Remember the index for the first section in this block.  */
+      newp->data[0].index
+	= 1 + elf->state.elf.scns_last->data[elf->state.elf.scns_last->max - 1].index;
+
+      /* Enqueue the new list element.  */
+      elf->state.elf.scns_last = elf->state.elf.scns_last->next = newp;
+    }
+
+  /* Create a section header for this section.  */
+  if (elf->class == ELFCLASS32)
+    {
+      result->shdr.e32 = (Elf32_Shdr *) calloc (1, sizeof (Elf32_Shdr));
+      if (result->shdr.e32 == NULL)
+	{
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  goto out;
+	}
+    }
+  else
+    {
+      result->shdr.e64 = (Elf64_Shdr *) calloc (1, sizeof (Elf64_Shdr));
+      if (result->shdr.e64 == NULL)
+	{
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  goto out;
+	}
+    }
+
+  result->elf = elf;
+  result->shdr_flags = ELF_F_DIRTY | ELF_F_MALLOCED;
+  result->list = elf->state.elf.scns_last;
+
+  /* Initialize the data part.  */
+  result->data_read = 1;
+  if (unlikely (first))
+    {
+      /* For the first section we mark the data as already available.  */
+      //result->data_list_rear = &result->data_list;
+      first = false;
+      goto again;
+    }
+
+  result->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/libelf/elf_next.c b/libelf/elf_next.c
new file mode 100644
index 0000000..58a0775
--- /dev/null
+++ b/libelf/elf_next.c
@@ -0,0 +1,53 @@
+/* Advance in archive to next element.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Cmd
+elf_next (elf)
+     Elf *elf;
+{
+  Elf *parent;
+
+  /* Be gratious, the specs demand it.  */
+  if (elf == NULL || elf->parent == NULL)
+    return ELF_C_NULL;
+
+  /* We can be sure the parent is an archive.  */
+  parent = elf->parent;
+  assert (parent->kind == ELF_K_AR);
+
+  /* Now advance the offset.  */
+  parent->state.ar.offset += (sizeof (struct ar_hdr)
+			      + ((parent->state.ar.elf_ar_hdr.ar_size + 1)
+				 & ~1l));
+
+  /* Get the next archive header.  */
+  if (__libelf_next_arhdr (parent) != 0)
+    return ELF_C_NULL;
+
+  return elf->cmd;
+}
diff --git a/libelf/elf_nextscn.c b/libelf/elf_nextscn.c
new file mode 100644
index 0000000..de9df64
--- /dev/null
+++ b/libelf/elf_nextscn.c
@@ -0,0 +1,77 @@
+/* Get next section.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Scn *
+elf_nextscn (elf, scn)
+     Elf *elf;
+     Elf_Scn *scn;
+{
+  Elf_Scn *result = NULL;
+
+  if (elf == NULL)
+    return NULL;
+
+  rwlock_rdlock (elf->lock);
+
+  if (scn == NULL)
+    {
+      /* If no section handle is given return the first (not 0th) section.  */
+      if (elf->class == ELFCLASS32
+	   || (offsetof (Elf, state.elf32.scns)
+	       == offsetof (Elf, state.elf64.scns)))
+	{
+	  if (elf->state.elf32.scns.cnt > 1)
+	    result = &elf->state.elf32.scns.data[1];
+	}
+      else
+	{
+	  if (elf->state.elf64.scns.cnt > 1)
+	    result = &elf->state.elf64.scns.data[1];
+	}
+    }
+  else
+    {
+      Elf_ScnList *list = scn->list;
+
+      if (scn + 1 < &list->data[list->cnt])
+	result = scn + 1;
+      else if (scn + 1 == &list->data[list->max]
+	       && (list = list->next) != NULL)
+	{
+	  /* If there is another element in the section list it must
+	     have at least one entry.  */
+	  assert (list->cnt > 0);
+	  result = &list->data[0];
+	}
+    }
+
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elf_nextscn)
diff --git a/libelf/elf_rand.c b/libelf/elf_rand.c
new file mode 100644
index 0000000..76c3862
--- /dev/null
+++ b/libelf/elf_rand.c
@@ -0,0 +1,49 @@
+/* Select specific element in archive.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+size_t
+elf_rand (elf, offset)
+     Elf *elf;
+     size_t offset;
+{
+  /* Be gratious, the specs demand it.  */
+  if (elf == NULL || elf->kind != ELF_K_AR)
+    return 0;
+
+  /* Save the old offset and set the offset.  */
+  elf->state.ar.offset = elf->start_offset + offset;
+
+  /* Get the next archive header.  */
+  if (__libelf_next_arhdr (elf) != 0)
+    {
+      /* Mark the archive header as unusable.  */
+      elf->state.ar.elf_ar_hdr.ar_name = NULL;
+      return 0;
+    }
+
+  return offset;
+}
diff --git a/libelf/elf_rawdata.c b/libelf/elf_rawdata.c
new file mode 100644
index 0000000..547c37f
--- /dev/null
+++ b/libelf/elf_rawdata.c
@@ -0,0 +1,66 @@
+/* Return raw section content.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+Elf_Data *
+elf_rawdata (scn, data)
+     Elf_Scn *scn;
+     Elf_Data *data;
+{
+  if (scn == NULL || scn->elf->kind != ELF_K_ELF)
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* If `data' is not NULL this means we are not addressing the initial
+     data in the file.  But this also means this data is already read
+     (since otherwise it is not possible to have a valid `data' pointer)
+     and all the data structures are initialized as well.  In this case
+     we can simply walk the list of data records.  */
+  if (data != NULL
+      || (scn->data_read != 0 && (scn->flags & ELF_F_FILEDATA) == 0))
+    {
+      /* We don't allow accessing any but the data read from the file
+	 as raw.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return NULL;
+    }
+
+  /* If the data for this section was not yet initialized do it now.  */
+  if (scn->data_read == 0)
+    {
+      /* First thing we do is to read the data from the file.  There is
+	 always a file (or memory region) associated with this descriptor
+	 since otherwise the `data_read' flag would be set.  */
+      if (__libelf_set_rawdata (scn) != 0)
+	/* Something went wrong.  The error value is already set.  */
+	return NULL;
+    }
+
+  /* Return the first data element in the list.  */
+  return &scn->rawdata.d;
+}
+INTDEF(elf_rawdata)
diff --git a/libelf/elf_rawfile.c b/libelf/elf_rawfile.c
new file mode 100644
index 0000000..3f6dc3c
--- /dev/null
+++ b/libelf/elf_rawfile.c
@@ -0,0 +1,51 @@
+/* Retrieve uninterpreted file contents.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+char *
+elf_rawfile (elf, ptr)
+     Elf *elf;
+     size_t *ptr;
+{
+  if (elf == NULL)
+    {
+      /* No valid descriptor.  */
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+    error_out:
+      if (ptr != NULL)
+	*ptr = 0;
+      return NULL;
+    }
+
+  /* If the file is not mmap'ed and not previously loaded, do it now.  */
+  if (elf->map_address == NULL && __libelf_readall (elf) == NULL)
+    goto error_out;
+
+  if (ptr != NULL)
+    *ptr = elf->maximum_size;
+
+  return (char *) elf->map_address + elf->start_offset;
+}
diff --git a/libelf/elf_readall.c b/libelf/elf_readall.c
new file mode 100644
index 0000000..d36da27
--- /dev/null
+++ b/libelf/elf_readall.c
@@ -0,0 +1,116 @@
+/* Read all of the file associated with the descriptor.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <unistd.h>
+
+#include "libelfP.h"
+#include "common.h"
+
+
+static void
+set_address (Elf *elf, size_t offset)
+{
+  if (elf->kind == ELF_K_AR)
+    {
+      Elf *child = elf->state.ar.children;
+
+      while (child != NULL)
+	{
+	  if (child->map_address == NULL)
+	    {
+	      child->map_address = elf->map_address;
+	      child->start_offset -= offset;
+	      if (child->kind == ELF_K_AR)
+		child->state.ar.offset -= offset;
+
+	      set_address (child, offset);
+	    }
+
+	  child = child->next;
+	}
+    }
+}
+
+
+char *
+__libelf_readall (elf)
+     Elf *elf;
+{
+  /* Get the file.  */
+  rwlock_wrlock (elf->lock);
+
+  if (elf->map_address == NULL && unlikely (elf->fildes == -1))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      rwlock_unlock (elf->lock);
+      return NULL;
+    }
+
+  /* If the file is not mmap'ed and not previously loaded, do it now.  */
+  if (elf->map_address == NULL)
+    {
+      char *mem;
+
+      /* If this is an archive and we have derived descriptors get the
+	 locks for all of them.  */
+      libelf_acquire_all (elf);
+
+      /* Allocate all the memory we need.  */
+      mem = (char *) malloc (elf->maximum_size);
+      if (mem != NULL)
+	{
+	  /* Read the file content.  */
+	  if ((size_t) pread (elf->fildes, mem, elf->maximum_size,
+			      elf->start_offset) != elf->maximum_size)
+	    {
+	      /* Something went wrong.  */
+	      __libelf_seterrno (ELF_E_READ_ERROR);
+	      free (mem);
+	    }
+	  else
+	    {
+	      /* Remember the address.  */
+	      elf->map_address = mem;
+
+	      /* Also remember that we allocated the memory.  */
+	      elf->flags |= ELF_F_MALLOCED;
+
+	      /* Propagate the information down to all children and
+		 their children.  */
+	      set_address (elf, elf->start_offset);
+
+	      /* Correct the own offsets.  */
+	      if (elf->kind == ELF_K_AR)
+		elf->state.ar.offset -= elf->start_offset;
+	      elf->start_offset = 0;
+	    }
+	}
+      else
+	__libelf_seterrno (ELF_E_NOMEM);
+
+      /* Free the locks on the children.  */
+      libelf_release_all (elf);
+    }
+
+  rwlock_unlock (elf->lock);
+
+  return (char *) elf->map_address;
+}
diff --git a/libelf/elf_strptr.c b/libelf/elf_strptr.c
new file mode 100644
index 0000000..327adfd
--- /dev/null
+++ b/libelf/elf_strptr.c
@@ -0,0 +1,122 @@
+/* Return string pointer from string section.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+char *
+elf_strptr (elf, idx, offset)
+     Elf *elf;
+     size_t idx;
+     size_t offset;
+{
+  if (elf == NULL)
+    return NULL;
+
+  if (elf->kind != ELF_K_ELF)
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  rwlock_rdlock (elf->lock);
+
+  char *result = NULL;
+  Elf_Scn *strscn;
+
+  /* Find the section in the list.  */
+  Elf_ScnList *runp = (elf->class == ELFCLASS32
+		       || (offsetof (struct Elf, state.elf32.scns)
+			   == offsetof (struct Elf, state.elf64.scns))
+		       ? &elf->state.elf32.scns : &elf->state.elf64.scns);
+  while (1)
+    {
+      if (idx < runp->max)
+	{
+	  if (idx < runp->cnt)
+	    strscn = &runp->data[idx];
+	  else
+	    {
+	      __libelf_seterrno (ELF_E_INVALID_INDEX);
+	      goto out;
+	    }
+	  break;
+	}
+
+      idx -= runp->max;
+
+      runp = runp->next;
+      if (runp == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+    }
+
+  if (elf->class == ELFCLASS32)
+    {
+      if (unlikely (strscn->shdr.e32->sh_type != SHT_STRTAB))
+	{
+	  /* This is no string section.  */
+	  __libelf_seterrno (ELF_E_INVALID_SECTION);
+	  goto out;
+	}
+
+      if (unlikely (offset >= strscn->shdr.e32->sh_size))
+	{
+	  /* The given offset is too big, it is beyond this section.  */
+	  __libelf_seterrno (ELF_E_OFFSET_RANGE);
+	  goto out;
+	}
+    }
+  else
+    {
+      if (unlikely (strscn->shdr.e64->sh_type != SHT_STRTAB))
+	{
+	  /* This is no string section.  */
+	  __libelf_seterrno (ELF_E_INVALID_SECTION);
+	  goto out;
+	}
+
+      if (unlikely (offset >= strscn->shdr.e64->sh_size))
+	{
+	  /* The given offset is too big, it is beyond this section.  */
+	  __libelf_seterrno (ELF_E_OFFSET_RANGE);
+	  goto out;
+	}
+    }
+
+  if (strscn->rawdata_base == NULL
+      /* Read the section data.  */
+      && __libelf_set_rawdata (strscn) != 0)
+    goto out;
+
+  result = &strscn->rawdata_base[offset];
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elf_strptr)
diff --git a/libelf/elf_update.c b/libelf/elf_update.c
new file mode 100644
index 0000000..5d6c6b7
--- /dev/null
+++ b/libelf/elf_update.c
@@ -0,0 +1,178 @@
+/* Update data structures for changes and write them out.
+   Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include "libelfP.h"
+
+
+static off_t
+write_file (Elf *elf, off_t size, int change_bo, size_t shnum)
+{
+  int class = elf->class;
+
+  /* Adjust the size in any case.  We do this even if we use `write'.
+     We cannot do this if this file is in an archive.  We also don't
+     do it *now* if we are shortening the file since this would
+     prevent programs to use the data of the file in generating the
+     new file.  We truncate the file later in this case.  */
+  if (elf->parent == NULL
+      && (elf->maximum_size == ~((size_t) 0)
+	  || (size_t) size > elf->maximum_size)
+      && unlikely (ftruncate (elf->fildes, size) != 0))
+    {
+      __libelf_seterrno (ELF_E_WRITE_ERROR);
+      return -1;
+    }
+
+  /* Try to map the file if this isn't done yet.  */
+  if (elf->map_address == NULL && elf->cmd == ELF_C_WRITE_MMAP)
+    {
+#if _MUDFLAP
+      /* Mudflap doesn't grok that our mmap'd data is ok.  */
+#else
+      elf->map_address = mmap (NULL, size, PROT_READ | PROT_WRITE,
+			       MAP_SHARED, elf->fildes, 0);
+      if (unlikely (elf->map_address == MAP_FAILED))
+	elf->map_address = NULL;
+#endif
+    }
+
+  if (elf->map_address != NULL)
+    {
+      /* The file is mmaped.  */
+      if ((class == ELFCLASS32
+	   ? __elf32_updatemmap (elf, change_bo, shnum)
+	   : __elf64_updatemmap (elf, change_bo, shnum)) != 0)
+	/* Some problem while writing.  */
+	size = -1;
+    }
+  else
+    {
+      /* The file is not mmaped.  */
+      if ((class == ELFCLASS32
+	   ? __elf32_updatefile (elf, change_bo, shnum)
+	   : __elf64_updatefile (elf, change_bo, shnum)) != 0)
+	/* Some problem while writing.  */
+	size = -1;
+    }
+
+  if (size != -1
+      && elf->parent == NULL
+      && elf->maximum_size != ~((size_t) 0)
+      && (size_t) size < elf->maximum_size
+      && unlikely (ftruncate (elf->fildes, size) != 0))
+    {
+      __libelf_seterrno (ELF_E_WRITE_ERROR);
+      size = -1;
+    }
+
+  if (size != -1 && elf->parent == NULL)
+    elf->maximum_size = size;
+
+  return size;
+}
+
+
+off_t
+elf_update (elf, cmd)
+     Elf *elf;
+     Elf_Cmd cmd;
+{
+  size_t shnum;
+  off_t size;
+  int change_bo = 0;
+
+  if (cmd != ELF_C_NULL
+      && cmd != ELF_C_WRITE
+      && unlikely (cmd != ELF_C_WRITE_MMAP))
+    {
+      __libelf_seterrno (ELF_E_INVALID_CMD);
+      return -1;
+    }
+
+  if (elf == NULL)
+    return -1;
+
+  if (elf->kind != ELF_K_ELF)
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return -1;
+    }
+
+  rwlock_wrlock (elf->lock);
+
+  /* Make sure we have an ELF header.  */
+  if (elf->state.elf.ehdr == NULL)
+    {
+      __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+      size = -1;
+      goto out;
+    }
+
+  /* Determine the number of sections.  */
+  shnum = (elf->state.elf.scns_last->cnt == 0
+	   ? 0
+	   : 1 + elf->state.elf.scns_last->data[elf->state.elf.scns_last->cnt - 1].index);
+
+  /* Update the ELF descriptor.  First, place the program header.  It
+     will come right after the ELF header.  The count the size of all
+     sections and finally place the section table.  */
+  size = (elf->class == ELFCLASS32
+	  ? __elf32_updatenull (elf, &change_bo, shnum)
+	  : __elf64_updatenull (elf, &change_bo, shnum));
+  if (likely (size != -1)
+      /* See whether we actually have to write out the data.  */
+      && (cmd == ELF_C_WRITE || cmd == ELF_C_WRITE_MMAP))
+    {
+      if (elf->cmd != ELF_C_RDWR
+	  && elf->cmd != ELF_C_RDWR_MMAP
+	  && elf->cmd != ELF_C_WRITE
+	  && unlikely (elf->cmd != ELF_C_WRITE_MMAP))
+	{
+	  __libelf_seterrno (ELF_E_UPDATE_RO);
+	  size = -1;
+	}
+      else if (unlikely (elf->fildes == -1))
+	{
+	  /* We closed the file already.  */
+	  __libelf_seterrno (ELF_E_FD_DISABLED);
+	  size = -1;
+	}
+      else
+	{
+	  if (elf->parent != NULL)
+	    {
+	      extern int puts (const char *);
+	      puts ("this is an archive member");
+	    }
+
+	  size = write_file (elf, size, change_bo, shnum);
+	}
+    }
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return size;
+}
diff --git a/libelf/elf_version.c b/libelf/elf_version.c
new file mode 100644
index 0000000..16bfce1
--- /dev/null
+++ b/libelf/elf_version.c
@@ -0,0 +1,58 @@
+/* Coordinate ELF library and application versions.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelfP.h>
+
+
+/* Is the version initialized?  */
+int __libelf_version_initialized;
+
+/* Currently selected version.  */
+unsigned int __libelf_version = EV_CURRENT;
+
+
+unsigned int
+elf_version (version)
+     unsigned int version;
+{
+  if (version == EV_NONE)
+    return __libelf_version;
+
+  if (likely (version < EV_NUM))
+    {
+      /* Phew, we know this version.  */
+      unsigned int last_version = __libelf_version;
+
+      /* Store the new version.  */
+      __libelf_version = version;
+
+      /* Signal that the version is now initialized.  */
+      __libelf_version_initialized = 1;
+
+      /* And return the last version.  */
+      return last_version;
+    }
+
+  /* We cannot handle this version.  */
+  __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
+  return EV_NONE;
+}
+INTDEF(elf_version)
diff --git a/libelf/exttypes.h b/libelf/exttypes.h
new file mode 100644
index 0000000..b6bde82
--- /dev/null
+++ b/libelf/exttypes.h
@@ -0,0 +1,86 @@
+/* External ELF types.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _EXTTYPES_H
+#define	_EXTTYPES_H 1
+
+/* Integral types.  */
+typedef char Elf32_Ext_Addr[ELF32_FSZ_ADDR];
+typedef char Elf32_Ext_Off[ELF32_FSZ_OFF];
+typedef char Elf32_Ext_Half[ELF32_FSZ_HALF];
+typedef char Elf32_Ext_Sword[ELF32_FSZ_SWORD];
+typedef char Elf32_Ext_Word[ELF32_FSZ_WORD];
+typedef char Elf32_Ext_Sxword[ELF32_FSZ_SXWORD];
+typedef char Elf32_Ext_Xword[ELF32_FSZ_XWORD];
+
+typedef char Elf64_Ext_Addr[ELF64_FSZ_ADDR];
+typedef char Elf64_Ext_Off[ELF64_FSZ_OFF];
+typedef char Elf64_Ext_Half[ELF64_FSZ_HALF];
+typedef char Elf64_Ext_Sword[ELF64_FSZ_SWORD];
+typedef char Elf64_Ext_Word[ELF64_FSZ_WORD];
+typedef char Elf64_Ext_Sxword[ELF64_FSZ_SXWORD];
+typedef char Elf64_Ext_Xword[ELF64_FSZ_XWORD];
+
+
+/* Define the composed types.  */
+#define START(Bits, Name, EName) typedef struct {
+#define END(Bits, Name) } ElfW2(Bits, Name)
+#define TYPE_NAME(Type, Name) Type Name;
+#define TYPE_EXTRA(Text) Text
+#define TYPE_XLATE(Text)
+
+/* Get the abstract definitions. */
+#include "abstract.h"
+
+/* And define the types.  */
+Ehdr32 (Ext_);
+Phdr32 (Ext_);
+Shdr32 (Ext_);
+Sym32 (Ext_);
+Rel32 (Ext_);
+Rela32 (Ext_);
+Note32 (Ext_);
+Dyn32 (Ext_);
+Verdef32 (Ext_);
+Verdaux32 (Ext_);
+Verneed32 (Ext_);
+Vernaux32 (Ext_);
+Syminfo32 (Ext_);
+Move32 (Ext_);
+
+Ehdr64 (Ext_);
+Phdr64 (Ext_);
+Shdr64 (Ext_);
+Sym64 (Ext_);
+Rel64 (Ext_);
+Rela64 (Ext_);
+Note64 (Ext_);
+Dyn64 (Ext_);
+Verdef64 (Ext_);
+Verdaux64 (Ext_);
+Verneed64 (Ext_);
+Vernaux64 (Ext_);
+Syminfo64 (Ext_);
+Move64 (Ext_);
+
+#undef START
+#undef END
+#undef TYPE_NAME
+#undef TYPE_EXTRA
+#undef TYPE_XLATE
+
+#endif	/* exttypes.h */
diff --git a/libelf/gelf.h b/libelf/gelf.h
new file mode 100644
index 0000000..299d6c8
--- /dev/null
+++ b/libelf/gelf.h
@@ -0,0 +1,308 @@
+/* This file defines generic ELF types, structures, and macros.
+   Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005 Red Hat, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _GELF_H
+#define	_GELF_H 1
+
+#include <libelf.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Class independent type definitions.  Correctly speaking this is not
+   true.  We assume that 64-bit binaries are the largest class and
+   therefore all other classes can be represented without loss.  */
+
+/* Type for a 16-bit quantity.  */
+typedef Elf64_Half GElf_Half;
+
+/* Types for signed and unsigned 32-bit quantities.  */
+typedef Elf64_Word GElf_Word;
+typedef	Elf64_Sword GElf_Sword;
+
+/* Types for signed and unsigned 64-bit quantities.  */
+typedef Elf64_Xword GElf_Xword;
+typedef	Elf64_Sxword GElf_Sxword;
+
+/* Type of addresses.  */
+typedef Elf64_Addr GElf_Addr;
+
+/* Type of file offsets.  */
+typedef Elf64_Off GElf_Off;
+
+
+/* The ELF file header.  This appears at the start of every ELF file.  */
+typedef Elf64_Ehdr GElf_Ehdr;
+
+/* Section header.  */
+typedef Elf64_Shdr GElf_Shdr;
+
+/* Section index.  */
+/* XXX This should probably be a larger type in preparation of times when
+   regular section indices can be larger.  */
+typedef Elf64_Section GElf_Section;
+
+/* Symbol table entry.  */
+typedef Elf64_Sym GElf_Sym;
+
+/* The syminfo section if available contains additional information about
+   every dynamic symbol.  */
+typedef Elf64_Syminfo GElf_Syminfo;
+
+/* Relocation table entry without addend (in section of type SHT_REL).  */
+typedef Elf64_Rel GElf_Rel;
+
+/* Relocation table entry with addend (in section of type SHT_RELA).  */
+typedef Elf64_Rela GElf_Rela;
+
+/* Program segment header.  */
+typedef Elf64_Phdr GElf_Phdr;
+
+/* Dynamic section entry.  */
+typedef Elf64_Dyn GElf_Dyn;
+
+
+/* Version definition sections.  */
+typedef Elf64_Verdef GElf_Verdef;
+
+/* Auxialiary version information.  */
+typedef Elf64_Verdaux GElf_Verdaux;
+
+/* Version dependency section.  */
+typedef Elf64_Verneed GElf_Verneed;
+
+/* Auxiliary needed version information.  */
+typedef Elf64_Vernaux GElf_Vernaux;
+
+
+/* Type for version symbol information.  */
+typedef Elf64_Versym GElf_Versym;
+
+
+/* Auxiliary vector.  */
+typedef Elf64_auxv_t GElf_auxv_t;
+
+
+/* Note section contents.  */
+typedef Elf64_Nhdr GElf_Nhdr;
+
+
+/* Move structure.  */
+typedef Elf64_Move GElf_Move;
+
+
+/* Library list structure.  */
+typedef Elf64_Lib GElf_Lib;
+
+
+/* How to extract and insert information held in the st_info field.  */
+
+#define GELF_ST_BIND(val)		ELF64_ST_BIND (val)
+#define GELF_ST_TYPE(val)		ELF64_ST_TYPE (val)
+#define GELF_ST_INFO(bind, type)	ELF64_ST_INFO (bind, type)
+
+/* How to extract information held in the st_other field.  */
+
+#define GELF_ST_VISIBILITY(val)		ELF64_ST_VISIBILITY (val)
+
+
+/* How to extract and insert information held in the r_info field.  */
+
+#define GELF_R_SYM(info)		ELF64_R_SYM (info)
+#define GELF_R_TYPE(info)		ELF64_R_TYPE (info)
+#define GELF_R_INFO(sym, type)		ELF64_R_INFO (sym, type)
+
+
+/* How to extract and insert information held in the m_info field.  */
+#define GELF_M_SYM(info)		ELF64_M_SYM (info)
+#define GELF_M_SIZE(info)		ELF64_M_SIZE (info)
+#define GELF_M_INFO(sym, size)		ELF64_M_INFO (sym, size)
+
+
+/* Get class of the file associated with ELF.  */
+extern int gelf_getclass (Elf *__elf);
+
+
+/* Return size of array of COUNT elemeents of the type denoted by TYPE
+   in the external representation.  The binary class is taken from ELF.
+   The result is based on version VERSION of the ELF standard.  */
+extern size_t gelf_fsize (Elf *__elf, Elf_Type __type, size_t __count,
+			  unsigned int __version);
+
+/* Retrieve object file header.  */
+extern GElf_Ehdr *gelf_getehdr (Elf *__elf, GElf_Ehdr *__dest);
+
+/* Update the ELF header.  */
+extern int gelf_update_ehdr (Elf *__elf, GElf_Ehdr *__src);
+
+/* Create new ELF header if none exists.  */
+extern unsigned long int gelf_newehdr (Elf *__elf, int __class);
+
+/* Retrieve section header.  */
+extern GElf_Shdr *gelf_getshdr (Elf_Scn *__scn, GElf_Shdr *__dst);
+
+/* Update section header.  */
+extern int gelf_update_shdr (Elf_Scn *__scn, GElf_Shdr *__src);
+
+/* Retrieve program header table entry.  */
+extern GElf_Phdr *gelf_getphdr (Elf *__elf, int __ndx, GElf_Phdr *__dst);
+
+/* Update the program header.  */
+extern int gelf_update_phdr (Elf *__elf, int __ndx, GElf_Phdr *__src);
+
+/* Create new program header with PHNUM entries.  */
+extern unsigned long int gelf_newphdr (Elf *__elf, size_t __phnum);
+
+
+/* Convert data structure from the representation in the file represented
+   by ELF to their memory representation.  */
+extern Elf_Data *gelf_xlatetom (Elf *__elf, Elf_Data *__dest,
+				const Elf_Data *__src, unsigned int __encode);
+
+/* Convert data structure from to the representation in memory
+   represented by ELF file representation.  */
+extern Elf_Data *gelf_xlatetof (Elf *__elf, Elf_Data *__dest,
+				const Elf_Data *__src, unsigned int __encode);
+
+
+/* Retrieve REL relocation info at the given index.  */
+extern GElf_Rel *gelf_getrel (Elf_Data *__data, int __ndx, GElf_Rel *__dst);
+
+/* Retrieve RELA relocation info at the given index.  */
+extern GElf_Rela *gelf_getrela (Elf_Data *__data, int __ndx, GElf_Rela *__dst);
+
+/* Update REL relocation information at given index.  */
+extern int gelf_update_rel (Elf_Data *__dst, int __ndx, GElf_Rel *__src);
+
+/* Update RELA relocation information at given index.  */
+extern int gelf_update_rela (Elf_Data *__dst, int __ndx, GElf_Rela *__src);
+
+
+/* Retrieve symbol information from the symbol table at the given index.  */
+extern GElf_Sym *gelf_getsym (Elf_Data *__data, int __ndx, GElf_Sym *__dst);
+
+/* Update symbol information in the symbol table at the given index.  */
+extern int gelf_update_sym (Elf_Data *__data, int __ndx, GElf_Sym *__src);
+
+
+/* Retrieve symbol information and separate section index from the
+   symbol table at the given index.  */
+extern GElf_Sym *gelf_getsymshndx (Elf_Data *__symdata, Elf_Data *__shndxdata,
+				   int __ndx, GElf_Sym *__sym,
+				   Elf32_Word *__xshndx);
+
+/* Update symbol information and separate section index in the symbol
+   table at the given index.  */
+extern int gelf_update_symshndx (Elf_Data *__symdata, Elf_Data *__shndxdata,
+				 int __ndx, GElf_Sym *__sym,
+				 Elf32_Word __xshndx);
+
+
+/* Retrieve additional symbol information from the symbol table at the
+   given index.  */
+extern GElf_Syminfo *gelf_getsyminfo (Elf_Data *__data, int __ndx,
+				      GElf_Syminfo *__dst);
+
+/* Update additional symbol information in the symbol table at the
+   given index.  */
+extern int gelf_update_syminfo (Elf_Data *__data, int __ndx,
+				GElf_Syminfo *__src);
+
+
+/* Get information from dynamic table at the given index.  */
+extern GElf_Dyn *gelf_getdyn (Elf_Data *__data, int __ndx, GElf_Dyn *__dst);
+
+/* Update information in dynamic table at the given index.  */
+extern int gelf_update_dyn (Elf_Data *__dst, int __ndx, GElf_Dyn *__src);
+
+
+/* Get move structure at the given index.  */
+extern GElf_Move *gelf_getmove (Elf_Data *__data, int __ndx, GElf_Move *__dst);
+
+/* Update move structure at the given index.  */
+extern int gelf_update_move (Elf_Data *__data, int __ndx,
+			     GElf_Move *__src);
+
+
+/* Get library from table at the given index.  */
+extern GElf_Lib *gelf_getlib (Elf_Data *__data, int __ndx, GElf_Lib *__dst);
+
+/* Update library in table at the given index.  */
+extern int gelf_update_lib (Elf_Data *__data, int __ndx, GElf_Lib *__src);
+
+
+
+/* Retrieve symbol version information at given index.  */
+extern GElf_Versym *gelf_getversym (Elf_Data *__data, int __ndx,
+				    GElf_Versym *__dst);
+
+/* Update symbol version information.  */
+extern int gelf_update_versym (Elf_Data *__data, int __ndx,
+			       GElf_Versym *__src);
+
+
+/* Retrieve required symbol version information at given offset.  */
+extern GElf_Verneed *gelf_getverneed (Elf_Data *__data, int __offset,
+				      GElf_Verneed *__dst);
+
+/* Update required symbol version information.  */
+extern int gelf_update_verneed (Elf_Data *__data, int __offset,
+				GElf_Verneed *__src);
+
+/* Retrieve additional required symbol version information at given offset.  */
+extern GElf_Vernaux *gelf_getvernaux (Elf_Data *__data, int __offset,
+				      GElf_Vernaux *__dst);
+
+/* Update additional required symbol version information.  */
+extern int gelf_update_vernaux (Elf_Data *__data, int __offset,
+				GElf_Vernaux *__src);
+
+
+/* Retrieve symbol version definition information at given offset.  */
+extern GElf_Verdef *gelf_getverdef (Elf_Data *__data, int __offset,
+				    GElf_Verdef *__dst);
+
+/* Update symbol version definition information.  */
+extern int gelf_update_verdef (Elf_Data *__data, int __offset,
+			       GElf_Verdef *__src);
+
+/* Retrieve additional symbol version definition information at given
+   offset.  */
+extern GElf_Verdaux *gelf_getverdaux (Elf_Data *__data, int __offset,
+				      GElf_Verdaux *__dst);
+
+/* Update additional symbol version definition information.  */
+extern int gelf_update_verdaux (Elf_Data *__data, int __offset,
+				GElf_Verdaux *__src);
+
+
+/* Retrieve uninterpreted chunk of the file contents.  */
+extern char *gelf_rawchunk (Elf *__elf, GElf_Off __offset, GElf_Word __size);
+
+/* Release uninterpreted chunk of the file contents.  */
+extern void gelf_freechunk (Elf *__elf, char *__ptr);
+
+
+/* Compute simple checksum from permanent parts of the ELF file.  */
+extern long int gelf_checksum (Elf *__elf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* gelf.h */
diff --git a/libelf/gelf_checksum.c b/libelf/gelf_checksum.c
new file mode 100644
index 0000000..bbd04df
--- /dev/null
+++ b/libelf/gelf_checksum.c
@@ -0,0 +1,37 @@
+/* Convert from file to memory representation.  Generic ELF version.
+   Copyright (C) 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+long int
+gelf_checksum (elf)
+     Elf *elf;
+{
+  if (elf == NULL)
+    return -1l;
+
+  return (elf->class == ELFCLASS32
+	  ? INTUSE(elf32_checksum) (elf) : INTUSE(elf64_checksum) (elf));
+}
diff --git a/libelf/gelf_freechunk.c b/libelf/gelf_freechunk.c
new file mode 100644
index 0000000..c47ec9a
--- /dev/null
+++ b/libelf/gelf_freechunk.c
@@ -0,0 +1,45 @@
+/* Release uninterpreted chunk of the file contents.
+   Copyright (C) 2002 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+void
+gelf_freechunk (elf, ptr)
+     Elf *elf;
+     char *ptr;
+{
+  if (elf == NULL)
+    /* No valid descriptor.  */
+    return;
+
+  /* We do not have to do anything if the pointer returned by
+     gelf_rawchunk points into the memory allocated for the ELF
+     descriptor.  */
+  if (ptr < (char *) elf->map_address + elf->start_offset
+      || ptr >= ((char *) elf->map_address + elf->start_offset
+		 + elf->maximum_size))
+    free (ptr);
+}
diff --git a/libelf/gelf_fsize.c b/libelf/gelf_fsize.c
new file mode 100644
index 0000000..0432ba0
--- /dev/null
+++ b/libelf/gelf_fsize.c
@@ -0,0 +1,96 @@
+/* Return the size of an object file type.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+/* These are the sizes for all the known types.  */
+const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
+{
+  /* We have no entry for EV_NONE siince we have to set an error.  */
+  [EV_CURRENT - 1] = {
+    [ELFCLASS32 - 1] = {
+#define TYPE_SIZES(LIBELFBITS) \
+      [ELF_T_ADDR]	= ELFW2(LIBELFBITS, FSZ_ADDR),			      \
+      [ELF_T_OFF]	= ELFW2(LIBELFBITS, FSZ_OFF),			      \
+      [ELF_T_BYTE]	= 1,						      \
+      [ELF_T_HALF]	= ELFW2(LIBELFBITS, FSZ_HALF),			      \
+      [ELF_T_WORD]	= ELFW2(LIBELFBITS, FSZ_WORD),			      \
+      [ELF_T_SWORD]	= ELFW2(LIBELFBITS, FSZ_SWORD),			      \
+      [ELF_T_XWORD]	= ELFW2(LIBELFBITS, FSZ_XWORD),			      \
+      [ELF_T_SXWORD]	= ELFW2(LIBELFBITS, FSZ_SXWORD),		      \
+      [ELF_T_EHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Ehdr)),		      \
+      [ELF_T_SHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Shdr)),		      \
+      [ELF_T_SYM]	= sizeof (ElfW2(LIBELFBITS, Ext_Sym)),		      \
+      [ELF_T_REL]	= sizeof (ElfW2(LIBELFBITS, Ext_Rel)),		      \
+      [ELF_T_RELA]	= sizeof (ElfW2(LIBELFBITS, Ext_Rela)),		      \
+      [ELF_T_PHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Phdr)),		      \
+      [ELF_T_DYN]	= sizeof (ElfW2(LIBELFBITS, Ext_Dyn)),		      \
+      [ELF_T_VDEF]	= sizeof (ElfW2(LIBELFBITS, Ext_Verdef)),	      \
+      [ELF_T_VDAUX]	= sizeof (ElfW2(LIBELFBITS, Ext_Verdaux)),	      \
+      [ELF_T_VNEED]	= sizeof (ElfW2(LIBELFBITS, Ext_Verneed)),	      \
+      [ELF_T_VNAUX]	= sizeof (ElfW2(LIBELFBITS, Ext_Vernaux)),	      \
+      [ELF_T_NHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Nhdr)),		      \
+      [ELF_T_SYMINFO]	= sizeof (ElfW2(LIBELFBITS, Ext_Syminfo)),	      \
+      [ELF_T_MOVE]	= sizeof (ElfW2(LIBELFBITS, Ext_Move))
+      TYPE_SIZES (32)
+    },
+    [ELFCLASS64 - 1] = {
+      TYPE_SIZES (64)
+    }
+  }
+};
+
+
+size_t
+gelf_fsize (elf, type, count, version)
+     Elf *elf;
+     Elf_Type type;
+     size_t count;
+     unsigned int version;
+{
+  /* We do not have differences between file and memory sizes.  Better
+     not since otherwise `mmap' would not work.  */
+  if (elf == NULL)
+    return 0;
+
+  if (version == EV_NONE || version >= EV_NUM)
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
+      return 0;
+    }
+
+  if (type >= ELF_T_NUM)
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_TYPE);
+      return 0;
+    }
+
+#if EV_NUM != 2
+  return count * __libelf_type_sizes[version - 1][elf->class - 1][type];
+#else
+  return count * __libelf_type_sizes[0][elf->class - 1][type];
+#endif
+}
+INTDEF(gelf_fsize)
diff --git a/libelf/gelf_getclass.c b/libelf/gelf_getclass.c
new file mode 100644
index 0000000..2ae1b32
--- /dev/null
+++ b/libelf/gelf_getclass.c
@@ -0,0 +1,33 @@
+/* Return the class of file associated with the descriptor.
+   Copyright (C) 1999, 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_getclass (elf)
+     Elf *elf;
+{
+  return elf == NULL || elf->kind != ELF_K_ELF ? ELFCLASSNONE : elf->class;
+}
diff --git a/libelf/gelf_getdyn.c b/libelf/gelf_getdyn.c
new file mode 100644
index 0000000..d75744e
--- /dev/null
+++ b/libelf/gelf_getdyn.c
@@ -0,0 +1,99 @@
+/* Get information from dynamic table at the given index.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Dyn *
+gelf_getdyn (data, ndx, dst)
+     Elf_Data *data;
+     int ndx;
+     GElf_Dyn *dst;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  GElf_Dyn *result = NULL;
+  Elf *elf;
+
+  if (data_scn == NULL)
+    return NULL;
+
+  if (unlikely (data_scn->d.d_type != ELF_T_DYN))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  elf = data_scn->s->elf;
+
+  rwlock_rdlock (elf->lock);
+
+  /* This is the one place where we have to take advantage of the fact
+     that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
+     The interface is broken so that it requires this hack.  */
+  if (elf->class == ELFCLASS32)
+    {
+      Elf32_Dyn *src;
+
+      /* Here it gets a bit more complicated.  The format of the symbol
+	 table entries has to be adopted.  The user better has provided
+	 a buffer where we can store the information.  While copying the
+	 data we are converting the format.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      src = &((Elf32_Dyn *) data_scn->d.d_buf)[ndx];
+
+      /* This might look like a simple copy operation but it's
+	 not.  There are zero- and sign-extensions going on.  */
+      dst->d_tag = src->d_tag;
+      /* It OK to copy `d_val' since `d_ptr' has the same size.  */
+      dst->d_un.d_val = src->d_un.d_val;
+    }
+  else
+    {
+      /* If this is a 64 bit object it's easy.  */
+      assert (sizeof (GElf_Dyn) == sizeof (Elf64_Dyn));
+
+      /* The data is already in the correct form.  Just make sure the
+	 index is OK.  */
+      if (unlikely ((ndx + 1) * sizeof (GElf_Dyn) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      *dst = ((GElf_Dyn *) data_scn->d.d_buf)[ndx];
+    }
+
+  result = dst;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_getehdr.c b/libelf/gelf_getehdr.c
new file mode 100644
index 0000000..5c323dc
--- /dev/null
+++ b/libelf/gelf_getehdr.c
@@ -0,0 +1,88 @@
+/* Get ELF header.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Ehdr *
+gelf_getehdr (elf, dest)
+     Elf *elf;
+     GElf_Ehdr *dest;
+{
+  GElf_Ehdr *result = NULL;
+
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  rwlock_rdlock (elf->lock);
+
+  /* The following is an optimization: the ehdr element is at the same
+     position in both the elf32 and elf64 structure.  */
+  if (offsetof (struct Elf, state.elf32.ehdr)
+      != offsetof (struct Elf, state.elf64.ehdr))
+    abort ();
+  /* Just pick one of the values.  */
+ if (unlikely (elf->state.elf64.ehdr == NULL))
+    /* Maybe no ELF header was created yet.  */
+    __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+  else if (elf->class == ELFCLASS32)
+    {
+      Elf32_Ehdr *ehdr = elf->state.elf32.ehdr;
+
+      /* Convert the 32-bit struct to an 64-bit one.  */
+      memcpy (dest->e_ident, ehdr->e_ident, EI_NIDENT);
+#define COPY(name) \
+      dest->name = ehdr->name
+      COPY (e_type);
+      COPY (e_machine);
+      COPY (e_version);
+      COPY (e_entry);
+      COPY (e_phoff);
+      COPY (e_shoff);
+      COPY (e_flags);
+      COPY (e_ehsize);
+      COPY (e_phentsize);
+      COPY (e_phnum);
+      COPY (e_shentsize);
+      COPY (e_shnum);
+      COPY (e_shstrndx);
+
+      result = dest;
+    }
+  else
+    result = memcpy (dest, elf->state.elf64.ehdr, sizeof (*dest));
+
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(gelf_getehdr)
diff --git a/libelf/gelf_getlib.c b/libelf/gelf_getlib.c
new file mode 100644
index 0000000..9366c79
--- /dev/null
+++ b/libelf/gelf_getlib.c
@@ -0,0 +1,68 @@
+/* Get library from table at the given index.
+   Copyright (C) 2004 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Lib *
+gelf_getlib (data, ndx, dst)
+     Elf_Data *data;
+     int ndx;
+     GElf_Lib *dst;
+{
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_LIB))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+
+  rwlock_rdlock (data_scn->s->elf->lock);
+
+  /* The on disk format of Elf32_Lib and Elf64_Lib is identical.  So
+     we can simplify things significantly.  */
+  assert (sizeof (GElf_Lib) == sizeof (Elf32_Lib));
+  assert (sizeof (GElf_Lib) == sizeof (Elf64_Lib));
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  GElf_Lib *result = NULL;
+  if (unlikely ((ndx + 1) * sizeof (GElf_Lib) > data->d_size))
+    __libelf_seterrno (ELF_E_INVALID_INDEX);
+  else
+    {
+      *dst = ((GElf_Lib *) data->d_buf)[ndx];
+
+      result = dst;
+    }
+
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_getmove.c b/libelf/gelf_getmove.c
new file mode 100644
index 0000000..a3b96bb
--- /dev/null
+++ b/libelf/gelf_getmove.c
@@ -0,0 +1,70 @@
+/* Get move structure at the given index.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+GElf_Move *
+gelf_getmove (data, ndx, dst)
+     Elf_Data *data;
+     int ndx;
+     GElf_Move *dst;
+{
+  GElf_Move *result = NULL;
+  Elf *elf;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_MOVE))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Move) == sizeof (Elf32_Move));
+  assert (sizeof (GElf_Move) == sizeof (Elf64_Move));
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  if (unlikely ((ndx + 1) * sizeof (GElf_Move) > data->d_size))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      goto out;
+    }
+
+  elf = ((Elf_Data_Scn *) data)->s->elf;
+  rwlock_rdlock (elf->lock);
+
+  *dst = ((GElf_Move *) data->d_buf)[ndx];
+
+  rwlock_unlock (elf->lock);
+
+  result = dst;
+
+ out:
+  return result;
+}
diff --git a/libelf/gelf_getphdr.c b/libelf/gelf_getphdr.c
new file mode 100644
index 0000000..fd033e5
--- /dev/null
+++ b/libelf/gelf_getphdr.c
@@ -0,0 +1,117 @@
+/* Return program header table entry.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Phdr *
+gelf_getphdr (elf, ndx, dst)
+     Elf *elf;
+     int ndx;
+     GElf_Phdr *dst;
+{
+  GElf_Phdr *result = NULL;
+
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  if (dst == NULL)
+    {
+      __libelf_seterrno (ELF_E_INVALID_OPERAND);
+      return NULL;
+    }
+
+  rwlock_rdlock (elf->lock);
+
+  if (elf->class == ELFCLASS32)
+    {
+      /* Copy the elements one-by-one.  */
+      Elf32_Phdr *phdr = elf->state.elf32.phdr;
+
+      if (phdr == NULL)
+	{
+	  phdr = INTUSE(elf32_getphdr) (elf);
+	  if (phdr == NULL)
+	    /* The error number is already set.  */
+	    goto out;
+	}
+
+      /* Test whether the index is ok.  */
+      if (ndx >= elf->state.elf32.ehdr->e_phnum)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      /* We know the result now.  */
+      result = dst;
+
+      /* Now correct the pointer to point to the correct element.  */
+      phdr += ndx;
+
+#define COPY(Name) result->Name = phdr->Name
+      COPY (p_type);
+      COPY (p_offset);
+      COPY (p_vaddr);
+      COPY (p_paddr);
+      COPY (p_filesz);
+      COPY (p_memsz);
+      COPY (p_flags);
+      COPY (p_align);
+    }
+  else
+    {
+      /* Copy the elements one-by-one.  */
+      Elf64_Phdr *phdr = elf->state.elf64.phdr;
+
+      if (phdr == NULL)
+	{
+	  phdr = INTUSE(elf64_getphdr) (elf);
+	  if (phdr == NULL)
+	    /* The error number is already set.  */
+	    goto out;
+	}
+
+      /* Test whether the index is ok.  */
+      if (ndx >= elf->state.elf64.ehdr->e_phnum)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      /* We only have to copy the data.  */
+      result = memcpy (dst, phdr + ndx, sizeof (GElf_Phdr));
+    }
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_getrel.c b/libelf/gelf_getrel.c
new file mode 100644
index 0000000..7dc78a7
--- /dev/null
+++ b/libelf/gelf_getrel.c
@@ -0,0 +1,96 @@
+/* Get REL relocation information at given index.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Rel *
+gelf_getrel (data, ndx, dst)
+     Elf_Data *data;
+     int ndx;
+     GElf_Rel *dst;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  Elf_Scn *scn;
+  GElf_Rel *result;
+
+  if (data_scn == NULL)
+    return NULL;
+
+  if (unlikely (ndx < 0))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return NULL;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_REL))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* This is the one place where we have to take advantage of the fact
+     that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
+     The interface is broken so that it requires this hack.  */
+  scn = data_scn->s;
+
+  rwlock_rdlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      /* We have to convert the data.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  result = NULL;
+	}
+      else
+	{
+	  Elf32_Rel *src = &((Elf32_Rel *) data_scn->d.d_buf)[ndx];
+
+	  dst->r_offset = src->r_offset;
+	  dst->r_info = GELF_R_INFO (ELF32_R_SYM (src->r_info),
+				     ELF32_R_TYPE (src->r_info));
+
+	  result = dst;
+	}
+    }
+  else
+    {
+      /* Simply copy the data after we made sure we are actually getting
+	 correct data.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  result = NULL;
+	}
+      else
+	result = memcpy (dst, &((Elf64_Rel *) data_scn->d.d_buf)[ndx],
+			 sizeof (Elf64_Rel));
+    }
+
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_getrela.c b/libelf/gelf_getrela.c
new file mode 100644
index 0000000..fb94b00
--- /dev/null
+++ b/libelf/gelf_getrela.c
@@ -0,0 +1,97 @@
+/* Get RELA relocation information at given index.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Rela *
+gelf_getrela (data, ndx, dst)
+     Elf_Data *data;
+     int ndx;
+     GElf_Rela *dst;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  Elf_Scn *scn;
+  GElf_Rela *result;
+
+  if (data_scn == NULL)
+    return NULL;
+
+  if (unlikely (ndx < 0))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return NULL;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_RELA))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* This is the one place where we have to take advantage of the fact
+     that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
+     The interface is broken so that it requires this hack.  */
+  scn = data_scn->s;
+
+  rwlock_rdlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      /* We have to convert the data.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  result = NULL;
+	}
+      else
+	{
+	  Elf32_Rela *src = &((Elf32_Rela *) data_scn->d.d_buf)[ndx];
+
+	  dst->r_offset = src->r_offset;
+	  dst->r_info = GELF_R_INFO (ELF32_R_SYM (src->r_info),
+				     ELF32_R_TYPE (src->r_info));
+	  dst->r_addend = src->r_addend;
+
+	  result = dst;
+	}
+    }
+  else
+    {
+      /* Simply copy the data after we made sure we are actually getting
+	 correct data.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  result = NULL;
+	}
+      else
+	result = memcpy (dst, &((Elf64_Rela *) data_scn->d.d_buf)[ndx],
+			 sizeof (Elf64_Rela));
+    }
+
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_getshdr.c b/libelf/gelf_getshdr.c
new file mode 100644
index 0000000..4ea5886
--- /dev/null
+++ b/libelf/gelf_getshdr.c
@@ -0,0 +1,91 @@
+/* Return section header.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Shdr *
+gelf_getshdr (scn, dst)
+     Elf_Scn *scn;
+     GElf_Shdr *dst;
+{
+  GElf_Shdr *result = NULL;
+
+  if (scn == NULL)
+    return NULL;
+
+  if (dst == NULL)
+    {
+      __libelf_seterrno (ELF_E_INVALID_OPERAND);
+      return NULL;
+    }
+
+  rwlock_rdlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      /* Copy the elements one-by-one.  */
+      Elf32_Shdr *shdr = scn->shdr.e32 ?: INTUSE(elf32_getshdr) (scn);
+
+      if (shdr == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_OPERAND);
+	  goto out;
+	}
+
+#define COPY(name) \
+      dst->name = shdr->name
+      COPY (sh_name);
+      COPY (sh_type);
+      COPY (sh_flags);
+      COPY (sh_addr);
+      COPY (sh_offset);
+      COPY (sh_size);
+      COPY (sh_link);
+      COPY (sh_info);
+      COPY (sh_addralign);
+      COPY (sh_entsize);
+
+      result = dst;
+    }
+  else
+    {
+      Elf64_Shdr *shdr = scn->shdr.e64 ?: INTUSE(elf64_getshdr) (scn);
+
+      if (shdr == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_OPERAND);
+	  goto out;
+	}
+
+      /* We only have to copy the data.  */
+      result = memcpy (dst, shdr, sizeof (GElf_Shdr));
+    }
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
+INTDEF(gelf_getshdr)
diff --git a/libelf/gelf_getsym.c b/libelf/gelf_getsym.c
new file mode 100644
index 0000000..90536c6
--- /dev/null
+++ b/libelf/gelf_getsym.c
@@ -0,0 +1,105 @@
+/* Get symbol information from symbol table at the given index.
+   Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Sym *
+gelf_getsym (data, ndx, dst)
+     Elf_Data *data;
+     int ndx;
+     GElf_Sym *dst;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  GElf_Sym *result = NULL;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_SYM))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  rwlock_rdlock (data_scn->s->elf->lock);
+
+  /* This is the one place where we have to take advantage of the fact
+     that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
+     The interface is broken so that it requires this hack.  */
+  if (data_scn->s->elf->class == ELFCLASS32)
+    {
+      Elf32_Sym *src;
+
+      /* Here it gets a bit more complicated.  The format of the symbol
+	 table entries has to be adopted.  The user better has provided
+	 a buffer where we can store the information.  While copying the
+	 data we are converting the format.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      src = &((Elf32_Sym *) data->d_buf)[ndx];
+
+      /* This might look like a simple copy operation but it's
+	 not.  There are zero- and sign-extensions going on.  */
+#define COPY(name) \
+      dst->name = src->name
+      COPY (st_name);
+      /* Please note that we can simply copy the `st_info' element since
+	 the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same
+	 for the 64 bit variant.  */
+      COPY (st_info);
+      COPY (st_other);
+      COPY (st_shndx);
+      COPY (st_value);
+      COPY (st_size);
+    }
+  else
+    {
+      /* If this is a 64 bit object it's easy.  */
+      assert (sizeof (GElf_Sym) == sizeof (Elf64_Sym));
+
+      /* The data is already in the correct form.  Just make sure the
+	 index is OK.  */
+      if (unlikely ((ndx + 1) * sizeof (GElf_Sym) > data->d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      *dst = ((GElf_Sym *) data->d_buf)[ndx];
+    }
+
+  result = dst;
+
+ out:
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return result;
+}
+INTDEF(gelf_getsym)
diff --git a/libelf/gelf_getsyminfo.c b/libelf/gelf_getsyminfo.c
new file mode 100644
index 0000000..70cfdcd
--- /dev/null
+++ b/libelf/gelf_getsyminfo.c
@@ -0,0 +1,68 @@
+/* Get additional symbol information from symbol table at the given index.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Syminfo *
+gelf_getsyminfo (data, ndx, dst)
+     Elf_Data *data;
+     int ndx;
+     GElf_Syminfo *dst;
+{
+  GElf_Syminfo *result = NULL;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_SYMINFO))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Syminfo) == sizeof (Elf32_Syminfo));
+  assert (sizeof (GElf_Syminfo) == sizeof (Elf64_Syminfo));
+
+  rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  if (unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data->d_size))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      goto out;
+    }
+
+  *dst = ((GElf_Syminfo *) data->d_buf)[ndx];
+
+  result = dst;
+
+ out:
+  rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_getsymshndx.c b/libelf/gelf_getsymshndx.c
new file mode 100644
index 0000000..856f491
--- /dev/null
+++ b/libelf/gelf_getsymshndx.c
@@ -0,0 +1,128 @@
+/* Get symbol information and separate section index from symbol table
+   at the given index.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Sym *
+gelf_getsymshndx (symdata, shndxdata, ndx, dst, dstshndx)
+     Elf_Data *symdata;
+     Elf_Data *shndxdata;
+     int ndx;
+     GElf_Sym *dst;
+     Elf32_Word *dstshndx;
+{
+  Elf_Data_Scn *symdata_scn = (Elf_Data_Scn *) symdata;
+  Elf_Data_Scn *shndxdata_scn = (Elf_Data_Scn *) shndxdata;
+  GElf_Sym *result = NULL;
+  Elf32_Word shndx = 0;
+
+  if (symdata == NULL)
+    return NULL;
+
+  if (unlikely (symdata->d_type != ELF_T_SYM)
+      || (likely (shndxdata_scn != NULL)
+	  && unlikely (shndxdata->d_type != ELF_T_WORD)))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  rwlock_rdlock (symdata_scn->s->elf->lock);
+
+  /* The user is not required to pass a data descriptor for an extended
+     section index table.  */
+  if (likely (shndxdata_scn != NULL))
+    {
+      if (unlikely ((ndx + 1) * sizeof (Elf32_Word) > shndxdata_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      shndx = ((Elf32_Word *) shndxdata_scn->d.d_buf)[ndx];
+    }
+
+  /* This is the one place where we have to take advantage of the fact
+     that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
+     The interface is broken so that it requires this hack.  */
+  if (symdata_scn->s->elf->class == ELFCLASS32)
+    {
+      Elf32_Sym *src;
+
+      /* Here it gets a bit more complicated.  The format of the symbol
+	 table entries has to be adopted.  The user better has provided
+	 a buffer where we can store the information.  While copying the
+	 data we are converting the format.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata->d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      src = &((Elf32_Sym *) symdata->d_buf)[ndx];
+
+      /* This might look like a simple copy operation but it's
+	 not.  There are zero- and sign-extensions going on.  */
+#define COPY(name) \
+      dst->name = src->name
+      COPY (st_name);
+      /* Please note that we can simply copy the `st_info' element since
+	 the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same
+	 for the 64 bit variant.  */
+      COPY (st_info);
+      COPY (st_other);
+      COPY (st_shndx);
+      COPY (st_value);
+      COPY (st_size);
+    }
+  else
+    {
+      /* If this is a 64 bit object it's easy.  */
+      assert (sizeof (GElf_Sym) == sizeof (Elf64_Sym));
+
+      /* The data is already in the correct form.  Just make sure the
+	 index is OK.  */
+      if (unlikely ((ndx + 1) * sizeof (GElf_Sym) > symdata->d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      *dst = ((GElf_Sym *) symdata->d_buf)[ndx];
+    }
+
+  /* Now we can store the section index.  */
+  if (dstshndx != NULL)
+    *dstshndx = shndx;
+
+  result = dst;
+
+ out:
+  rwlock_unlock (symdata_scn->s->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_getverdaux.c b/libelf/gelf_getverdaux.c
new file mode 100644
index 0000000..0a14b12
--- /dev/null
+++ b/libelf/gelf_getverdaux.c
@@ -0,0 +1,70 @@
+/* Get additional symbol version definition information at the given offset.
+   Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Verdaux *
+gelf_getverdaux (data, offset, dst)
+     Elf_Data *data;
+     int offset;
+     GElf_Verdaux *dst;
+{
+  GElf_Verdaux *result;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_VDEF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* It's easy to handle this type.  It has the same size for 32 and
+     64 bit objects.  */
+  assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux));
+  assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux));
+
+  rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  if (unlikely (offset < 0)
+      || unlikely (offset + sizeof (GElf_Verdaux) > data->d_size)
+      || unlikely (offset % __alignof__ (GElf_Verdaux) != 0))
+    {
+      __libelf_seterrno (ELF_E_OFFSET_RANGE);
+      result = NULL;
+    }
+  else
+    result = (GElf_Verdaux *) memcpy (dst, (char *) data->d_buf + offset,
+				      sizeof (GElf_Verdaux));
+
+
+  rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_getverdef.c b/libelf/gelf_getverdef.c
new file mode 100644
index 0000000..b9492ef
--- /dev/null
+++ b/libelf/gelf_getverdef.c
@@ -0,0 +1,69 @@
+/* Get symbol version definition information at the given offset.
+   Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Verdef *
+gelf_getverdef (data, offset, dst)
+     Elf_Data *data;
+     int offset;
+     GElf_Verdef *dst;
+{
+  GElf_Verdef *result;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_VDEF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* It's easy to handle this type.  It has the same size for 32 and
+     64 bit objects.  */
+  assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef));
+  assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef));
+
+  rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  if (unlikely (offset < 0)
+      || unlikely (offset + sizeof (GElf_Verdef) > data->d_size)
+      || unlikely (offset % __alignof__ (GElf_Verdef) != 0))
+    {
+      __libelf_seterrno (ELF_E_OFFSET_RANGE);
+      result = NULL;
+    }
+  else
+    result = (GElf_Verdef *) memcpy (dst, (char *) data->d_buf + offset,
+				     sizeof (GElf_Verdef));
+
+  rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_getvernaux.c b/libelf/gelf_getvernaux.c
new file mode 100644
index 0000000..fbaa109
--- /dev/null
+++ b/libelf/gelf_getvernaux.c
@@ -0,0 +1,72 @@
+/* Get additional required symbol version information at the given offset.
+   Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Vernaux *
+gelf_getvernaux (data, offset, dst)
+     Elf_Data *data;
+     int offset;
+     GElf_Vernaux *dst;
+{
+  GElf_Vernaux *result;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_VNEED))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* It's easy to handle this type.  It has the same size for 32 and
+     64 bit objects.  And fortunately the `ElfXXX_Vernaux' records
+     also have the same size.  */
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Verneed));
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Verneed));
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux));
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux));
+
+  rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  if (unlikely (offset < 0)
+      || unlikely (offset + sizeof (GElf_Vernaux) > data->d_size)
+      || unlikely (offset % sizeof (GElf_Vernaux) != 0))
+    {
+      __libelf_seterrno (ELF_E_OFFSET_RANGE);
+      result = NULL;
+    }
+  else
+    result = (GElf_Vernaux *) memcpy (dst, (char *) data->d_buf + offset,
+				      sizeof (GElf_Verneed));
+
+  rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_getverneed.c b/libelf/gelf_getverneed.c
new file mode 100644
index 0000000..573e116
--- /dev/null
+++ b/libelf/gelf_getverneed.c
@@ -0,0 +1,72 @@
+/* Get required symbol version information at the given offset.
+   Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Verneed *
+gelf_getverneed (data, offset, dst)
+     Elf_Data *data;
+     int offset;
+     GElf_Verneed *dst;
+{
+  GElf_Verneed *result;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_VNEED))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* It's easy to handle this type.  It has the same size for 32 and
+     64 bit objects.  And fortunately the `ElfXXX_Vernaux' records
+     also have the same size.  */
+  assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed));
+  assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed));
+  assert (sizeof (GElf_Verneed) == sizeof (Elf32_Vernaux));
+  assert (sizeof (GElf_Verneed) == sizeof (Elf64_Vernaux));
+
+  rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  if (unlikely (offset < 0)
+      || unlikely (offset + sizeof (GElf_Verneed) > data->d_size)
+      || unlikely (offset % sizeof (GElf_Verneed) != 0))
+    {
+      __libelf_seterrno (ELF_E_OFFSET_RANGE);
+      result = NULL;
+    }
+  else
+    result = (GElf_Verneed *) memcpy (dst, (char *) data->d_buf + offset,
+				      sizeof (GElf_Verneed));
+
+  rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_getversym.c b/libelf/gelf_getversym.c
new file mode 100644
index 0000000..9274b14
--- /dev/null
+++ b/libelf/gelf_getversym.c
@@ -0,0 +1,77 @@
+/* Get symbol version information at the given index.
+   Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Versym *
+gelf_getversym (data, ndx, dst)
+     Elf_Data *data;
+     int ndx;
+     GElf_Versym *dst;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  Elf_Scn *scn;
+  GElf_Versym *result;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_HALF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* This is the one place where we have to take advantage of the fact
+     that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
+     The interface is broken so that it requires this hack.  */
+  scn = data_scn->s;
+
+  /* It's easy to handle this type.  It has the same size for 32 and
+     64 bit objects.  */
+  assert (sizeof (GElf_Versym) == sizeof (Elf32_Versym));
+  assert (sizeof (GElf_Versym) == sizeof (Elf64_Versym));
+
+  rwlock_rdlock (scn->elf->lock);
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  if (unlikely ((ndx + 1) * sizeof (GElf_Versym) > data->d_size))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      result = NULL;
+    }
+  else
+    {
+      *dst = ((GElf_Versym *) data->d_buf)[ndx];
+
+      result = dst;
+    }
+
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_newehdr.c b/libelf/gelf_newehdr.c
new file mode 100644
index 0000000..587283f
--- /dev/null
+++ b/libelf/gelf_newehdr.c
@@ -0,0 +1,36 @@
+/* Create new ELF header.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+unsigned long int
+gelf_newehdr (elf, class)
+     Elf *elf;
+     int class;
+{
+  return (class == ELFCLASS32
+	  ? (unsigned long int) INTUSE(elf32_newehdr) (elf)
+	  : (unsigned long int) INTUSE(elf64_newehdr) (elf));
+}
diff --git a/libelf/gelf_newphdr.c b/libelf/gelf_newphdr.c
new file mode 100644
index 0000000..d1d433e
--- /dev/null
+++ b/libelf/gelf_newphdr.c
@@ -0,0 +1,36 @@
+/* Create new ELF program header.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+unsigned long int
+gelf_newphdr (elf, phnum)
+     Elf *elf;
+     size_t phnum;
+{
+  return (elf->class == ELFCLASS32
+	  ? (unsigned long int) INTUSE(elf32_newphdr) (elf, phnum)
+	  : (unsigned long int) INTUSE(elf64_newphdr) (elf, phnum));
+}
diff --git a/libelf/gelf_rawchunk.c b/libelf/gelf_rawchunk.c
new file mode 100644
index 0000000..667f301
--- /dev/null
+++ b/libelf/gelf_rawchunk.c
@@ -0,0 +1,71 @@
+/* Retrieve uninterpreted chunk of the file contents.
+   Copyright (C) 2002 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "libelfP.h"
+
+
+char *
+gelf_rawchunk (elf, offset, size)
+     Elf *elf;
+     GElf_Off offset;
+     GElf_Word size;
+{
+  if (elf == NULL)
+    {
+      /* No valid descriptor.  */
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  if (offset >= elf->maximum_size
+      || offset + size >= elf->maximum_size
+      || offset + size < offset)
+    {
+      /* Invalid request.  */
+      __libelf_seterrno (ELF_E_INVALID_OP);
+      return NULL;
+    }
+
+  /* If the file is mmap'ed return an appropriate pointer.  */
+  if (elf->map_address != NULL)
+    return (char *) elf->map_address + elf->start_offset + offset;
+
+  /* We allocate the memory and read the data from the file.  */
+  char *result = (char *) malloc (size);
+  if (result == NULL)
+    __libelf_seterrno (ELF_E_NOMEM);
+  else
+    /* Read the file content.  */
+    if ((size_t) pread (elf->fildes, result, size, elf->start_offset + offset)
+	!= size)
+      {
+	/* Something went wrong.  */
+	__libelf_seterrno (ELF_E_READ_ERROR);
+	free (result);
+      }
+
+  return result;
+}
diff --git a/libelf/gelf_update_dyn.c b/libelf/gelf_update_dyn.c
new file mode 100644
index 0000000..b066fd6
--- /dev/null
+++ b/libelf/gelf_update_dyn.c
@@ -0,0 +1,104 @@
+/* Update information in dynamic table at the given index.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_dyn (data, ndx, src)
+     Elf_Data *data;
+     int ndx;
+     GElf_Dyn *src;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  Elf_Scn *scn;
+  int result = 0;
+
+  if (data == NULL)
+    return 0;
+
+  if (unlikely (ndx < 0))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_DYN))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  scn = data_scn->s;
+  rwlock_wrlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      Elf32_Dyn *dyn;
+
+      /* There is the possibility that the values in the input are
+	 too large.  */
+      if (unlikely (src->d_tag < -0x80000000ll)
+	  || unlikely (src->d_tag > 0x7fffffffll)
+	  || unlikely (src->d_un.d_val > 0xffffffffull))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      /* Check whether we have to resize the data buffer.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      dyn = &((Elf32_Dyn *) data_scn->d.d_buf)[ndx];
+
+      dyn->d_tag = src->d_tag;
+      dyn->d_un.d_val = src->d_un.d_val;
+    }
+  else
+    {
+      /* Check whether we have to resize the data buffer.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf64_Dyn) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      ((Elf64_Dyn *) data_scn->d.d_buf)[ndx] = *src;
+    }
+
+  result = 1;
+
+  /* Mark the section as modified.  */
+  scn->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_update_ehdr.c b/libelf/gelf_update_ehdr.c
new file mode 100644
index 0000000..e13121d
--- /dev/null
+++ b/libelf/gelf_update_ehdr.c
@@ -0,0 +1,103 @@
+/* Update ELF header.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_ehdr (Elf *elf, GElf_Ehdr *src)
+{
+  int result = 0;
+
+  if (elf == NULL)
+    return 0;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  rwlock_wrlock (elf->lock);
+
+  if (elf->class == ELFCLASS32)
+    {
+      Elf32_Ehdr *ehdr = elf->state.elf32.ehdr;
+
+      if (ehdr == NULL)
+	{
+	  __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+	  goto out;
+	}
+
+      /* We have to convert the data to the 32 bit format.  This might
+	 overflow some fields so we have to test for this case before
+	 copying.  */
+      if (unlikely (src->e_entry > 0xffffffffull)
+	  || unlikely (src->e_phoff > 0xffffffffull)
+	  || unlikely (src->e_shoff > 0xffffffffull))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      /* Copy the data.  */
+      memcpy (ehdr->e_ident, src->e_ident, EI_NIDENT);
+#define COPY(name) \
+      ehdr->name = src->name
+      COPY (e_type);
+      COPY (e_machine);
+      COPY (e_version);
+      COPY (e_entry);
+      COPY (e_phoff);
+      COPY (e_shoff);
+      COPY (e_flags);
+      COPY (e_ehsize);
+      COPY (e_phentsize);
+      COPY (e_phnum);
+      COPY (e_shentsize);
+      COPY (e_shnum);
+      COPY (e_shstrndx);
+    }
+  else
+    {
+      Elf64_Ehdr *ehdr = elf->state.elf64.ehdr;
+
+      if (ehdr == NULL)
+	{
+	  __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+	  goto out;
+	}
+
+      /* Just copy the data.  */
+      memcpy (ehdr, src, sizeof (Elf64_Ehdr));
+    }
+
+  result = 1;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_update_lib.c b/libelf/gelf_update_lib.c
new file mode 100644
index 0000000..08ce229
--- /dev/null
+++ b/libelf/gelf_update_lib.c
@@ -0,0 +1,72 @@
+/* Update library in table at the given index.
+   Copyright (C) 2004 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_lib (data, ndx, src)
+     Elf_Data *data;
+     int ndx;
+     GElf_Lib *src;
+{
+  if (data == NULL)
+    return 0;
+
+  if (unlikely (ndx < 0))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  if (unlikely (data_scn->d.d_type != ELF_T_LIB))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  Elf_Scn *scn = data_scn->s;
+  rwlock_wrlock (scn->elf->lock);
+
+  /* Check whether we have to resize the data buffer.  */
+  int result = 0;
+  if (unlikely ((ndx + 1) * sizeof (Elf64_Lib) > data_scn->d.d_size))
+    __libelf_seterrno (ELF_E_INVALID_INDEX);
+  else
+    {
+      ((Elf64_Lib *) data_scn->d.d_buf)[ndx] = *src;
+
+      result = 1;
+
+      /* Mark the section as modified.  */
+      scn->flags |= ELF_F_DIRTY;
+    }
+
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_update_move.c b/libelf/gelf_update_move.c
new file mode 100644
index 0000000..090e397
--- /dev/null
+++ b/libelf/gelf_update_move.c
@@ -0,0 +1,69 @@
+/* Update move structure at the given index.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_move (data, ndx, src)
+     Elf_Data *data;
+     int ndx;
+     GElf_Move *src;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+
+  if (data == NULL)
+    return 0;
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Move) == sizeof (Elf32_Move));
+  assert (sizeof (GElf_Move) == sizeof (Elf64_Move));
+
+  /* Check whether we have to resize the data buffer.  */
+  if (unlikely (ndx < 0)
+      || unlikely ((ndx + 1) * sizeof (GElf_Move) > data_scn->d.d_size))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_MOVE))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  rwlock_wrlock (data_scn->s->elf->lock);
+
+  ((GElf_Move *) data_scn->d.d_buf)[ndx] = *src;
+
+  /* Mark the section as modified.  */
+  data_scn->s->flags |= ELF_F_DIRTY;
+
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return 1;
+}
diff --git a/libelf/gelf_update_phdr.c b/libelf/gelf_update_phdr.c
new file mode 100644
index 0000000..ddd4e1e
--- /dev/null
+++ b/libelf/gelf_update_phdr.c
@@ -0,0 +1,120 @@
+/* Update program header program header table entry.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_phdr (Elf *elf, int ndx, GElf_Phdr *src)
+{
+  int result = 0;
+
+  if (elf == NULL)
+    return 0;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  rwlock_wrlock (elf->lock);
+
+  if (elf->class == ELFCLASS32)
+    {
+      Elf32_Phdr *phdr = elf->state.elf32.phdr;
+
+      /* We have to convert the data to the 32 bit format.  This might
+	 overflow some fields so we have to test for this case before
+	 copying.  */
+      if (unlikely (src->p_offset > 0xffffffffull)
+	  || unlikely (src->p_vaddr > 0xffffffffull)
+	  || unlikely (src->p_paddr > 0xffffffffull)
+	  || unlikely (src->p_filesz > 0xffffffffull)
+	  || unlikely (src->p_memsz > 0xffffffffull)
+	  || unlikely (src->p_align > 0xffffffffull))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      if (phdr == NULL)
+	{
+	  phdr = INTUSE(elf32_getphdr) (elf);
+	  if (phdr == NULL)
+	    /* The error number is already set.  */
+	    goto out;
+	}
+
+      /* Test whether the index is ok.  */
+      if (unlikely (ndx >= elf->state.elf32.ehdr->e_phnum))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      /* Now correct the pointer to point to the correct element.  */
+      phdr += ndx;
+
+#define COPY(name) \
+      phdr->name = src->name
+      COPY (p_type);
+      COPY (p_offset);
+      COPY (p_vaddr);
+      COPY (p_paddr);
+      COPY (p_filesz);
+      COPY (p_memsz);
+      COPY (p_flags);
+      COPY (p_align);
+    }
+  else
+    {
+      Elf64_Phdr *phdr = elf->state.elf64.phdr;
+
+      if (phdr == NULL)
+	{
+	  phdr = INTUSE(elf64_getphdr) (elf);
+	  if (phdr == NULL)
+	    /* The error number is already set.  */
+	    goto out;
+	}
+
+      /* Test whether the index is ok.  */
+      if (unlikely (ndx >= elf->state.elf64.ehdr->e_phnum))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      /* Just copy the data.  */
+      memcpy (phdr + ndx, src, sizeof (Elf64_Phdr));
+    }
+
+  result = 1;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_update_rel.c b/libelf/gelf_update_rel.c
new file mode 100644
index 0000000..c59c6dd
--- /dev/null
+++ b/libelf/gelf_update_rel.c
@@ -0,0 +1,102 @@
+/* Update REL relocation information at given index.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_rel (Elf_Data *dst, int ndx, GElf_Rel *src)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) dst;
+  Elf_Scn *scn;
+  int result = 0;
+
+  if (dst == NULL)
+    return 0;
+
+  if (unlikely (ndx < 0))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_REL))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  scn = data_scn->s;
+  rwlock_wrlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      Elf32_Rel *rel;
+
+      /* There is the possibility that the values in the input are
+	 too large.  */
+      if (unlikely (src->r_offset > 0xffffffffull)
+	  || unlikely (GELF_R_SYM (src->r_info) > 0xffffff)
+	  || unlikely (GELF_R_TYPE (src->r_info) > 0xff))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      /* Check whether we have to resize the data buffer.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      rel = &((Elf32_Rel *) data_scn->d.d_buf)[ndx];
+
+      rel->r_offset = src->r_offset;
+      rel->r_info = ELF32_R_INFO (GELF_R_SYM (src->r_info),
+				  GELF_R_TYPE (src->r_info));
+    }
+  else
+    {
+      /* Check whether we have to resize the data buffer.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      ((Elf64_Rel *) data_scn->d.d_buf)[ndx] = *src;
+    }
+
+  result = 1;
+
+  /* Mark the section as modified.  */
+  scn->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_update_rela.c b/libelf/gelf_update_rela.c
new file mode 100644
index 0000000..f932c01
--- /dev/null
+++ b/libelf/gelf_update_rela.c
@@ -0,0 +1,105 @@
+/* Update RELA relocation information at given index.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_rela (Elf_Data *dst, int ndx, GElf_Rela *src)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) dst;
+  Elf_Scn *scn;
+  int result = 0;
+
+  if (dst == NULL)
+    return 0;
+
+  if (unlikely (ndx < 0))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_RELA))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  scn = data_scn->s;
+  rwlock_wrlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      Elf32_Rela *rel;
+
+      /* There is the possibility that the values in the input are
+	 too large.  */
+      if (unlikely (src->r_offset > 0xffffffffull)
+	  || unlikely (GELF_R_SYM (src->r_info) > 0xffffff)
+	  || unlikely (GELF_R_TYPE (src->r_info) > 0xff)
+	  || unlikely (src->r_addend < -0x80000000ll)
+	  || unlikely (src->r_addend > 0x7fffffffll))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      /* Check whether we have to resize the data buffer.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      rel = &((Elf32_Rela *) data_scn->d.d_buf)[ndx];
+
+      rel->r_offset = src->r_offset;
+      rel->r_info = ELF32_R_INFO (GELF_R_SYM (src->r_info),
+				  GELF_R_TYPE (src->r_info));
+      rel->r_addend = src->r_addend;
+    }
+  else
+    {
+      /* Check whether we have to resize the data buffer.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      ((Elf64_Rela *) data_scn->d.d_buf)[ndx] = *src;
+    }
+
+  result = 1;
+
+  /* Mark the section as modified.  */
+  scn->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_update_shdr.c b/libelf/gelf_update_shdr.c
new file mode 100644
index 0000000..c54e8c5
--- /dev/null
+++ b/libelf/gelf_update_shdr.c
@@ -0,0 +1,94 @@
+/* Update section header.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_shdr (Elf_Scn *scn, GElf_Shdr *src)
+{
+  int result = 0;
+  Elf *elf;
+
+  if (scn == NULL || src == NULL)
+    return 0;
+
+  elf = scn->elf;
+  rwlock_wrlock (elf->lock);
+
+  if (elf->class == ELFCLASS32)
+    {
+      Elf32_Shdr *shdr = scn->shdr.e32 ?: INTUSE(elf32_getshdr) (scn);
+
+      if (shdr == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_OPERAND);
+	  goto out;
+	}
+
+      if (unlikely (src->sh_flags > 0xffffffffull)
+	  || unlikely (src->sh_addr > 0xffffffffull)
+	  || unlikely (src->sh_offset > 0xffffffffull)
+	  || unlikely (src->sh_size > 0xffffffffull)
+	  || unlikely (src->sh_addralign > 0xffffffffull)
+	  || unlikely (src->sh_entsize > 0xffffffffull))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+#define COPY(name) \
+      shdr->name = src->name
+      COPY (sh_name);
+      COPY (sh_type);
+      COPY (sh_flags);
+      COPY (sh_addr);
+      COPY (sh_offset);
+      COPY (sh_size);
+      COPY (sh_link);
+      COPY (sh_info);
+      COPY (sh_addralign);
+      COPY (sh_entsize);
+    }
+  else
+    {
+      Elf64_Shdr *shdr = scn->shdr.e64 ?: INTUSE(elf64_getshdr) (scn);
+
+      if (shdr == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_OPERAND);
+	  goto out;
+	}
+
+      /* We only have to copy the data.  */
+      (void) memcpy (shdr, src, sizeof (GElf_Shdr));
+    }
+
+  result = 1;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_update_sym.c b/libelf/gelf_update_sym.c
new file mode 100644
index 0000000..8fc7dd6
--- /dev/null
+++ b/libelf/gelf_update_sym.c
@@ -0,0 +1,113 @@
+/* Update symbol information in symbol table at the given index.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_sym (data, ndx, src)
+     Elf_Data *data;
+     int ndx;
+     GElf_Sym *src;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  Elf_Scn *scn;
+  int result = 0;
+
+  if (data == NULL)
+    return 0;
+
+  if (unlikely (ndx < 0))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_SYM))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  scn = data_scn->s;
+  rwlock_wrlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      Elf32_Sym *sym;
+
+      /* There is the possibility that the values in the input are
+	 too large.  */
+      if (unlikely (src->st_value > 0xffffffffull)
+	  || unlikely (src->st_size > 0xffffffffull))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      /* Check whether we have to resize the data buffer.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      sym = &((Elf32_Sym *) data_scn->d.d_buf)[ndx];
+
+#define COPY(name) \
+      sym->name = src->name
+      COPY (st_name);
+      COPY (st_value);
+      COPY (st_size);
+      /* Please note that we can simply copy the `st_info' element since
+	 the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same
+	 for the 64 bit variant.  */
+      COPY (st_info);
+      COPY (st_other);
+      COPY (st_shndx);
+    }
+  else
+    {
+      /* Check whether we have to resize the data buffer.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf64_Sym) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      ((Elf64_Sym *) data_scn->d.d_buf)[ndx] = *src;
+    }
+
+  result = 1;
+
+  /* Mark the section as modified.  */
+  scn->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_update_syminfo.c b/libelf/gelf_update_syminfo.c
new file mode 100644
index 0000000..a60aa5c
--- /dev/null
+++ b/libelf/gelf_update_syminfo.c
@@ -0,0 +1,80 @@
+/* Update additional symbol information in symbol table at the given index.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_syminfo (data, ndx, src)
+     Elf_Data *data;
+     int ndx;
+     GElf_Syminfo *src;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  Elf_Scn *scn;
+  int result = 0;
+
+  if (data == NULL)
+    return 0;
+
+  if (unlikely (ndx < 0))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_SYMINFO))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Syminfo) == sizeof (Elf32_Syminfo));
+  assert (sizeof (GElf_Syminfo) == sizeof (Elf64_Syminfo));
+
+  scn = data_scn->s;
+  rwlock_wrlock (scn->elf->lock);
+
+  /* Check whether we have to resize the data buffer.  */
+  if (unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data_scn->d.d_size))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      goto out;
+    }
+
+  ((GElf_Syminfo *) data_scn->d.d_buf)[ndx] = *src;
+
+  result = 1;
+
+  /* Mark the section as modified.  */
+  scn->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_update_symshndx.c b/libelf/gelf_update_symshndx.c
new file mode 100644
index 0000000..4f37615
--- /dev/null
+++ b/libelf/gelf_update_symshndx.c
@@ -0,0 +1,143 @@
+/* Update symbol information and section index in symbol table at the
+   given index.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_symshndx (symdata, shndxdata, ndx, src, srcshndx)
+     Elf_Data *symdata;
+     Elf_Data *shndxdata;
+     int ndx;
+     GElf_Sym *src;
+     Elf32_Word srcshndx;
+{
+  Elf_Data_Scn *symdata_scn = (Elf_Data_Scn *) symdata;
+  Elf_Data_Scn *shndxdata_scn = (Elf_Data_Scn *) shndxdata;
+  Elf_Scn *scn;
+  Elf32_Word *shndx = NULL;
+  int result = 0;
+
+  if (symdata == NULL)
+    return 0;
+
+  if (unlikely (ndx < 0))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (symdata_scn->d.d_type != ELF_T_SYM))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  scn = symdata_scn->s;
+  /* We simply have to believe the user that the two sections belong to
+     the same ELF file.  */
+  rwlock_wrlock (scn->elf->lock);
+
+  /* The user is not required to pass a data descriptor for an extended
+     section index table.  */
+  if (shndxdata_scn != NULL)
+    {
+      if (unlikely ((ndx + 1) * sizeof (Elf32_Word) > shndxdata_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      shndx = &((Elf32_Word *) shndxdata_scn->d.d_buf)[ndx];
+    }
+  /* But if s/he does not the extended sectio index must be zero.  */
+  else if (unlikely (srcshndx != 0))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      goto out;
+    }
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      Elf32_Sym *sym;
+
+      /* There is the possibility that the values in the input are
+	 too large.  */
+      if (unlikely (src->st_value > 0xffffffffull)
+	  || unlikely (src->st_size > 0xffffffffull))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      /* Check whether we have to resize the data buffer.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      sym = &((Elf32_Sym *) symdata_scn->d.d_buf)[ndx];
+
+#define COPY(name) \
+      sym->name = src->name
+      COPY (st_name);
+      COPY (st_value);
+      COPY (st_size);
+      /* Please note that we can simply copy the `st_info' element since
+	 the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same
+	 for the 64 bit variant.  */
+      COPY (st_info);
+      COPY (st_other);
+      COPY (st_shndx);
+    }
+  else
+    {
+      /* Check whether we have to resize the data buffer.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf64_Sym) > symdata_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      ((Elf64_Sym *) symdata_scn->d.d_buf)[ndx] = *src;
+    }
+
+  /* Now we can store the section index.  */
+  if (shndx != NULL)
+    *shndx = srcshndx;
+
+  result = 1;
+
+  /* Mark the section as modified.  */
+  scn->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_update_verdaux.c b/libelf/gelf_update_verdaux.c
new file mode 100644
index 0000000..e21428e
--- /dev/null
+++ b/libelf/gelf_update_verdaux.c
@@ -0,0 +1,69 @@
+/* Update additional symbol version definition information.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_verdaux (data, offset, src)
+     Elf_Data *data;
+     int offset;
+     GElf_Verdaux *src;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+
+  if (data == NULL)
+    return 0;
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux));
+  assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux));
+
+  /* Check whether we have to resize the data buffer.  */
+  if (unlikely (offset < 0)
+      || unlikely ((offset + sizeof (GElf_Verdaux)) > data_scn->d.d_size))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_VDEF))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  rwlock_wrlock (data_scn->s->elf->lock);
+
+  memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Verdaux));
+
+  /* Mark the section as modified.  */
+  data_scn->s->flags |= ELF_F_DIRTY;
+
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return 1;
+}
diff --git a/libelf/gelf_update_verdef.c b/libelf/gelf_update_verdef.c
new file mode 100644
index 0000000..833a058
--- /dev/null
+++ b/libelf/gelf_update_verdef.c
@@ -0,0 +1,69 @@
+/* Update symbol version definition information.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_verdef (data, offset, src)
+     Elf_Data *data;
+     int offset;
+     GElf_Verdef *src;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+
+  if (data == NULL)
+    return 0;
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef));
+  assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef));
+
+  /* Check whether we have to resize the data buffer.  */
+  if (unlikely (offset < 0)
+      || unlikely ((offset + sizeof (GElf_Verdef)) > data_scn->d.d_size))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_VDEF))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  rwlock_wrlock (data_scn->s->elf->lock);
+
+  memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Verdef));
+
+  /* Mark the section as modified.  */
+  data_scn->s->flags |= ELF_F_DIRTY;
+
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return 1;
+}
diff --git a/libelf/gelf_update_vernaux.c b/libelf/gelf_update_vernaux.c
new file mode 100644
index 0000000..3f506d4
--- /dev/null
+++ b/libelf/gelf_update_vernaux.c
@@ -0,0 +1,69 @@
+/* Update additional required symbol version information.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_vernaux (data, offset, src)
+     Elf_Data *data;
+     int offset;
+     GElf_Vernaux *src;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+
+  if (data == NULL)
+    return 0;
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux));
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux));
+
+  /* Check whether we have to resize the data buffer.  */
+  if (unlikely (offset < 0)
+      || unlikely ((offset + sizeof (GElf_Vernaux)) > data_scn->d.d_size))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_VNEED))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  rwlock_wrlock (data_scn->s->elf->lock);
+
+  memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Vernaux));
+
+  /* Mark the section as modified.  */
+  data_scn->s->flags |= ELF_F_DIRTY;
+
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return 1;
+}
diff --git a/libelf/gelf_update_verneed.c b/libelf/gelf_update_verneed.c
new file mode 100644
index 0000000..6fccd93
--- /dev/null
+++ b/libelf/gelf_update_verneed.c
@@ -0,0 +1,69 @@
+/* Update required symbol version information.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_verneed (data, offset, src)
+     Elf_Data *data;
+     int offset;
+     GElf_Verneed *src;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+
+  if (data == NULL)
+    return 0;
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed));
+  assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed));
+
+  /* Check whether we have to resize the data buffer.  */
+  if (unlikely (offset < 0)
+      || unlikely ((offset + sizeof (GElf_Verneed)) > data_scn->d.d_size))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_VNEED))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  rwlock_wrlock (data_scn->s->elf->lock);
+
+  memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Verneed));
+
+  /* Mark the section as modified.  */
+  data_scn->s->flags |= ELF_F_DIRTY;
+
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return 1;
+}
diff --git a/libelf/gelf_update_versym.c b/libelf/gelf_update_versym.c
new file mode 100644
index 0000000..404d5bc
--- /dev/null
+++ b/libelf/gelf_update_versym.c
@@ -0,0 +1,69 @@
+/* Update symbol version information.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_versym (data, ndx, src)
+     Elf_Data *data;
+     int ndx;
+     GElf_Versym *src;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+
+  if (data == NULL)
+    return 0;
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Versym) == sizeof (Elf32_Versym));
+  assert (sizeof (GElf_Versym) == sizeof (Elf64_Versym));
+
+  /* Check whether we have to resize the data buffer.  */
+  if (unlikely (ndx < 0)
+      || unlikely ((ndx + 1) * sizeof (GElf_Versym) > data_scn->d.d_size))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_HALF))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  rwlock_wrlock (data_scn->s->elf->lock);
+
+  ((GElf_Versym *) data_scn->d.d_buf)[ndx] = *src;
+
+  /* Mark the section as modified.  */
+  data_scn->s->flags |= ELF_F_DIRTY;
+
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return 1;
+}
diff --git a/libelf/gelf_xlate.c b/libelf/gelf_xlate.c
new file mode 100644
index 0000000..bbb133a
--- /dev/null
+++ b/libelf/gelf_xlate.c
@@ -0,0 +1,182 @@
+/* Transformation functions for ELF data types.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <byteswap.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS	32
+#endif
+
+
+/* Well, what shall I say.  Nothing to do here.  */
+#define elf_cvt_Byte(dest, src, n) \
+  (__builtin_constant_p (n) && (n) == 1					      \
+   ? (void) (*((char *) (dest)) = *((char *) (src)))			      \
+   : Elf32_cvt_Byte (dest, src, n))
+static void
+(elf_cvt_Byte) (void *dest, const void *src, size_t n,
+		int encode __attribute__ ((unused)))
+{
+  memmove (dest, src, n);
+}
+
+
+/* We'll optimize the definition of the conversion functions here a
+   bit.  We need only functions for 16, 32, and 64 bits.  The
+   functions referenced in the table will be aliases for one of these
+   functions.  Which one is decided by the ELFxx_FSZ_type.  */
+#define LEN2_SWAP(Src)  bswap_16 (*((uint16_t *) Src))
+#define word2_t uint16_t
+
+#define LEN4_SWAP(Src)  bswap_32 (*((uint32_t *) Src))
+#define word4_t uint32_t
+
+#define LEN8_SWAP(Src)  bswap_64 (*((uint64_t *) Src))
+#define word8_t uint64_t
+
+
+/* Now define the conversion functions for the basic types.  We use here
+   the fact that file and memory types are the same and that we have the
+   ELFxx_FSZ_* macros.
+
+   At the same time we define inline functions which we will use to
+   convert the complex types.  */
+#define FUNDAMENTAL(NAME, Name, Bits) \
+  INLINE2 (ELFW2(Bits,FSZ_##NAME), ElfW2(Bits,cvt_##Name), ElfW2(Bits,Name))
+#define INLINE2(Bytes, FName, TName) \
+  INLINE3 (Bytes, FName, TName)
+#define INLINE3(Bytes, FName, TName) \
+  static void FName (void *dest, const void *ptr, size_t len,		      \
+		     int encode __attribute__ ((unused)))		      \
+  {									      \
+    size_t n = len / sizeof (TName);					      \
+    if (dest < ptr)							      \
+      {									      \
+	word##Bytes##_t *tdest = (word##Bytes##_t *) dest;		      \
+        const word##Bytes##_t *tptr = (const word##Bytes##_t *) ptr;	      \
+        while (n-- > 0)							      \
+	  {								      \
+	    *tdest++ = LEN##Bytes##_SWAP (tptr);			      \
+	    tptr++;							      \
+	  }								      \
+      }									      \
+    else								      \
+      {									      \
+	word##Bytes##_t *tdest = (word##Bytes##_t *) dest + n;		      \
+	const word##Bytes##_t *tptr = (const word##Bytes##_t *) ptr + n;      \
+	while (n-- > 0)							      \
+	  {								      \
+	    --tptr;							      \
+	    *--tdest = LEN##Bytes##_SWAP (tptr);			      \
+	  }								      \
+      }									      \
+ }									      \
+									      \
+  static inline void FName##1 (void *dest, const void *ptr)		      \
+  {									      \
+    *((word##Bytes##_t *) dest) =					      \
+      LEN##Bytes##_SWAP ((((word##Bytes##_t *) ptr)));			      \
+  }
+
+
+/* Now the tricky part: define the transformation functions for the
+   complex types.  We will use the definitions of the types in
+   abstract.h.  */
+#define START(Bits, Name, EName) \
+  static void								      \
+  ElfW2 (Bits, cvt_##Name) (void *dest, const void *src, size_t len,	      \
+			    int encode __attribute__ ((unused)))	      \
+  { ElfW2(Bits, Name) *tdest = (ElfW2(Bits, Name) *) dest;		      \
+    ElfW2(Bits, Name) *tsrc = (ElfW2(Bits, Name) *) src;		      \
+    size_t n;								      \
+    for (n = len / sizeof (ElfW2(Bits, Name)); n > 0; ++tdest, ++tsrc, --n) {
+#define END(Bits, Name) } }
+#define TYPE_EXTRA(Code)
+#define TYPE_XLATE(Code) Code
+#define TYPE_NAME(Type, Name) TYPE_NAME2 (Type, Name)
+#define TYPE_NAME2(Type, Name) Type##1 (&tdest->Name, &tsrc->Name);
+#define TYPE(Name, Bits) TYPE2 (Name, Bits)
+#define TYPE2(Name, Bits) TYPE3 (Name##Bits)
+#define TYPE3(Name) Name (cvt_)
+
+/* Signal that we are generating conversion functions.  */
+#define GENERATE_CONVERSION
+
+/* First generate the 32-bit conversion functions.  */
+#define LIBELFBITS 32
+#include "gelf_xlate.h"
+
+/* Now generate the 64-bit conversion functions.  */
+#define LIBELFBITS 64
+#include "gelf_xlate.h"
+
+
+/* We have a few functions which we must create by hand since the sections
+   do not contain records of only one type.  */
+#include "version_xlate.h"
+
+
+/* Now the externally visible table with the function pointers.  */
+const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
+{
+  [EV_CURRENT - 1] = {
+    [EV_CURRENT - 1] = {
+      [ELFCLASS32 - 1] = {
+#define define_xfcts(Bits) \
+	[ELF_T_BYTE]	= elf_cvt_Byte,					      \
+	[ELF_T_ADDR]	= ElfW2(Bits, cvt_Addr),			      \
+	[ELF_T_DYN]	= ElfW2(Bits, cvt_Dyn),				      \
+	[ELF_T_EHDR]	= ElfW2(Bits, cvt_Ehdr),			      \
+	[ELF_T_HALF]	= ElfW2(Bits, cvt_Half),			      \
+	[ELF_T_OFF]	= ElfW2(Bits, cvt_Off),				      \
+	[ELF_T_PHDR]	= ElfW2(Bits, cvt_Phdr),			      \
+	[ELF_T_RELA]	= ElfW2(Bits, cvt_Rela),			      \
+	[ELF_T_REL]	= ElfW2(Bits, cvt_Rel),				      \
+	[ELF_T_SHDR]	= ElfW2(Bits, cvt_Shdr),			      \
+	[ELF_T_SWORD]	= ElfW2(Bits, cvt_Sword),			      \
+	[ELF_T_SYM]	= ElfW2(Bits, cvt_Sym),				      \
+	[ELF_T_WORD]	= ElfW2(Bits, cvt_Word),			      \
+	[ELF_T_XWORD]	= ElfW2(Bits, cvt_Xword),			      \
+	[ELF_T_SXWORD]	= ElfW2(Bits, cvt_Sxword),			      \
+	[ELF_T_VDEF]	= elf_cvt_Verdef,				      \
+	[ELF_T_VDAUX]	= elf_cvt_Verdef,				      \
+	[ELF_T_VNEED]	= elf_cvt_Verneed,				      \
+	[ELF_T_VNAUX]	= elf_cvt_Verneed,				      \
+	[ELF_T_NHDR]	= ElfW2(Bits, cvt_Nhdr),			      \
+	[ELF_T_SYMINFO] = ElfW2(Bits, cvt_Syminfo),			      \
+	[ELF_T_MOVE]	= ElfW2(Bits, cvt_Move),			      \
+	[ELF_T_LIB]	= ElfW2(Bits, cvt_Lib)
+        define_xfcts (32)
+      },
+      [ELFCLASS64 - 1] = {
+	define_xfcts (64)
+      }
+    }
+  }
+};
+/* For now we only handle the case where the memory representation is the
+   same as the file representation.  Should this change we have to define
+   separate functions.  For now reuse them.  */
+strong_alias (__elf_xfctstom, __elf_xfctstof)
diff --git a/libelf/gelf_xlate.h b/libelf/gelf_xlate.h
new file mode 100644
index 0000000..42e91c0
--- /dev/null
+++ b/libelf/gelf_xlate.h
@@ -0,0 +1,43 @@
+/* Helper file for type conversion function generation.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+
+/* Simple types.  */
+FUNDAMENTAL (ADDR, Addr, LIBELFBITS);
+FUNDAMENTAL (OFF, Off, LIBELFBITS);
+FUNDAMENTAL (HALF, Half, LIBELFBITS);
+FUNDAMENTAL (WORD, Word, LIBELFBITS);
+FUNDAMENTAL (SWORD, Sword, LIBELFBITS);
+FUNDAMENTAL (XWORD, Xword, LIBELFBITS);
+FUNDAMENTAL (SXWORD, Sxword, LIBELFBITS);
+
+/* The structured types.  */
+TYPE (Ehdr, LIBELFBITS)
+TYPE (Phdr, LIBELFBITS)
+TYPE (Shdr, LIBELFBITS)
+TYPE (Sym, LIBELFBITS)
+TYPE (Rel, LIBELFBITS)
+TYPE (Rela, LIBELFBITS)
+TYPE (Note, LIBELFBITS)
+TYPE (Dyn, LIBELFBITS)
+TYPE (Syminfo, LIBELFBITS)
+TYPE (Move, LIBELFBITS)
+TYPE (Lib, LIBELFBITS)
+
+
+/* Prepare for the next round.  */
+#undef LIBELFBITS
diff --git a/libelf/gelf_xlatetof.c b/libelf/gelf_xlatetof.c
new file mode 100644
index 0000000..53cfae2
--- /dev/null
+++ b/libelf/gelf_xlatetof.c
@@ -0,0 +1,41 @@
+/* Convert from memory to file representation.  Generic ELF version.
+   Copyright (C) 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Data *
+gelf_xlatetof (elf, dest, src, encode)
+     Elf *elf;
+     Elf_Data *dest;
+     const Elf_Data * src;
+     unsigned int encode;
+{
+  if (elf == NULL)
+    return NULL;
+
+  return (elf->class == ELFCLASS32
+	  ? INTUSE(elf32_xlatetof) (dest, src, encode)
+	  : INTUSE(elf64_xlatetof) (dest, src, encode));
+}
diff --git a/libelf/gelf_xlatetom.c b/libelf/gelf_xlatetom.c
new file mode 100644
index 0000000..9295ee0
--- /dev/null
+++ b/libelf/gelf_xlatetom.c
@@ -0,0 +1,41 @@
+/* Convert from file to memory representation.  Generic ELF version.
+   Copyright (C) 2000, 2002 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Data *
+gelf_xlatetom (elf, dest, src, encode)
+     Elf *elf;
+     Elf_Data *dest;
+     const Elf_Data * src;
+     unsigned int encode;
+{
+  if (elf == NULL)
+    return NULL;
+
+  return (elf->class == ELFCLASS32
+	  ? INTUSE(elf32_xlatetom) (dest, src, encode)
+	  : INTUSE(elf64_xlatetom) (dest, src, encode));
+}
diff --git a/libelf/libelf.h b/libelf/libelf.h
new file mode 100644
index 0000000..5b3dc00
--- /dev/null
+++ b/libelf/libelf.h
@@ -0,0 +1,343 @@
+/* Interface for libelf.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004 Red Hat, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _LIBELF_H
+#define _LIBELF_H 1
+
+#include <sys/types.h>
+
+/* Get the ELF types.  */
+#include <elf.h>
+
+
+/* Known translation types.  */
+typedef enum
+{
+  ELF_T_BYTE,                   /* unsigned char */
+  ELF_T_ADDR,                   /* Elf32_Addr, Elf64_Addr, ... */
+  ELF_T_DYN,                    /* Dynamic section record.  */
+  ELF_T_EHDR,                   /* ELF header.  */
+  ELF_T_HALF,                   /* Elf32_Half, Elf64_Half, ... */
+  ELF_T_OFF,                    /* Elf32_Off, Elf64_Off, ... */
+  ELF_T_PHDR,                   /* Program header.  */
+  ELF_T_RELA,                   /* Relocation entry with addend.  */
+  ELF_T_REL,                    /* Relocation entry.  */
+  ELF_T_SHDR,                   /* Section header.  */
+  ELF_T_SWORD,                  /* Elf32_Sword, Elf64_Sword, ... */
+  ELF_T_SYM,                    /* Symbol record.  */
+  ELF_T_WORD,                   /* Elf32_Word, Elf64_Word, ... */
+  ELF_T_XWORD,                  /* Elf32_Xword, Elf64_Xword, ... */
+  ELF_T_SXWORD,                 /* Elf32_Sxword, Elf64_Sxword, ... */
+  ELF_T_VDEF,                   /* Elf32_Verdef, Elf64_Verdef, ... */
+  ELF_T_VDAUX,                  /* Elf32_Verdaux, Elf64_Verdaux, ... */
+  ELF_T_VNEED,                  /* Elf32_Verneed, Elf64_Verneed, ... */
+  ELF_T_VNAUX,                  /* Elf32_Vernaux, Elf64_Vernaux, ... */
+  ELF_T_NHDR,                   /* Elf32_Nhdr, Elf64_Nhdr, ... */
+  ELF_T_SYMINFO,		/* Elf32_Syminfo, Elf64_Syminfo, ... */
+  ELF_T_MOVE,			/* Elf32_Move, Elf64_Move, ... */
+  ELF_T_LIB,			/* Elf32_Lib, Elf64_Lib, ... */
+  /* Keep this the last entry.  */
+  ELF_T_NUM
+} Elf_Type;
+
+/* Descriptor for data to be converted to or from memory format.  */
+typedef struct
+{
+  void *d_buf;			/* Pointer to the actual data.  */
+  Elf_Type d_type;		/* Type of this piece of data.  */
+  unsigned int d_version;	/* ELF version.  */
+  size_t d_size;		/* Size in bytes.  */
+  off_t d_off;			/* Offset into section.  */
+  size_t d_align;		/* Alignment in section.  */
+} Elf_Data;
+
+
+/* Commands for `...'.  */
+typedef enum
+{
+  ELF_C_NULL,			/* Nothing, terminate, or compute only.  */
+  ELF_C_READ,			/* Read .. */
+  ELF_C_RDWR,			/* Read and write .. */
+  ELF_C_WRITE,			/* Write .. */
+  ELF_C_CLR,			/* Clear flag.  */
+  ELF_C_SET,			/* Set flag.  */
+  ELF_C_FDDONE,			/* Signal that file descriptor will not be
+				   used anymore.  */
+  ELF_C_FDREAD,			/* Read rest of data so that file descriptor
+				   is not used anymore.  */
+  /* The following are extensions.  */
+  ELF_C_READ_MMAP,		/* Read, but mmap the file if possible.  */
+  ELF_C_RDWR_MMAP,		/* Read and write, with mmap.  */
+  ELF_C_WRITE_MMAP,		/* Write, with mmap.  */
+  ELF_C_READ_MMAP_PRIVATE,	/* Read, but memory is writable, results are
+				   not written to the file.  */
+  ELF_C_EMPTY,			/* Copy basic file data but not the content. */
+  /* Keep this the last entry.  */
+  ELF_C_NUM
+} Elf_Cmd;
+
+
+/* Flags for the ELF structures.  */
+enum
+{
+  ELF_F_DIRTY = 0x1,
+#define ELF_F_DIRTY		ELF_F_DIRTY
+  ELF_F_LAYOUT = 0x4,
+#define ELF_F_LAYOUT		ELF_F_LAYOUT
+  ELF_F_PERMISSIVE = 0x8
+#define ELF_F_PERMISSIVE	ELF_F_PERMISSIVE
+};
+
+
+/* Identification values for recognized object files.  */
+typedef enum
+{
+  ELF_K_NONE,			/* Unknown.  */
+  ELF_K_AR,			/* Archive.  */
+  ELF_K_COFF,			/* Stupid old COFF.  */
+  ELF_K_ELF,			/* ELF file.  */
+  /* Keep this the last entry.  */
+  ELF_K_NUM
+} Elf_Kind;
+
+
+/* Archive member header.  */
+typedef struct
+{
+  char *ar_name;		/* Name of archive member.  */
+  time_t ar_date;		/* File date.  */
+  uid_t ar_uid;			/* User ID.  */
+  gid_t ar_gid;			/* Group ID.  */
+  mode_t ar_mode;		/* File mode.  */
+  off_t ar_size;		/* File size.  */
+  char *ar_rawname;		/* Original name of archive member.  */
+} Elf_Arhdr;
+
+
+/* Archive symbol table entry.  */
+typedef struct
+{
+  char *as_name;		/* Symbol name.  */
+  size_t as_off;		/* Offset for this file in the archive.  */
+  unsigned long int as_hash;	/* Hash value of the name.  */
+} Elf_Arsym;
+
+
+/* Descriptor for the ELF file.  */
+typedef struct Elf Elf;
+
+/* Descriptor for ELF file section.  */
+typedef struct Elf_Scn Elf_Scn;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Return descriptor for ELF file to work according to CMD.  */
+extern Elf *elf_begin (int __fildes, Elf_Cmd __cmd, Elf *__ref);
+
+/* Create a clone of an existing ELF descriptor.  */
+  extern Elf *elf_clone (Elf *__elf, Elf_Cmd __cmd);
+
+/* Create descriptor for memory region.  */
+extern Elf *elf_memory (char *__image, size_t __size);
+
+/* Advance archive descriptor to next element.  */
+extern Elf_Cmd elf_next (Elf *__elf);
+
+/* Free resources allocated for ELF.  */
+extern int elf_end (Elf *__elf);
+
+/* Update ELF descriptor and write file to disk.  */
+extern off_t elf_update (Elf *__elf, Elf_Cmd __cmd);
+
+/* Determine what kind of file is associated with ELF.  */
+extern Elf_Kind elf_kind (Elf *__elf) __attribute__ ((__pure__));
+
+/* Get the base offset for an object file.  */
+extern off_t elf_getbase (Elf *__elf);
+
+
+/* Retrieve file identification data.  */
+extern char *elf_getident (Elf *__elf, size_t *__ptr);
+
+/* Retrieve class-dependent object file header.  */
+extern Elf32_Ehdr *elf32_getehdr (Elf *__elf);
+/* Similar but this time the binary calls is ELFCLASS64.  */
+extern Elf64_Ehdr *elf64_getehdr (Elf *__elf);
+
+/* Create ELF header if none exists.  */
+extern Elf32_Ehdr *elf32_newehdr (Elf *__elf);
+/* Similar but this time the binary calls is ELFCLASS64.  */
+extern Elf64_Ehdr *elf64_newehdr (Elf *__elf);
+
+/* Retrieve class-dependent program header table.  */
+extern Elf32_Phdr *elf32_getphdr (Elf *__elf);
+/* Similar but this time the binary calls is ELFCLASS64.  */
+extern Elf64_Phdr *elf64_getphdr (Elf *__elf);
+
+/* Create ELF program header.  */
+extern Elf32_Phdr *elf32_newphdr (Elf *__elf, size_t __cnt);
+/* Similar but this time the binary calls is ELFCLASS64.  */
+extern Elf64_Phdr *elf64_newphdr (Elf *__elf, size_t __cnt);
+
+
+/* Get section at INDEX.  */
+extern Elf_Scn *elf_getscn (Elf *__elf, size_t __index);
+
+/* Get index of section.  */
+extern size_t elf_ndxscn (Elf_Scn *__scn);
+
+/* Get section with next section index.  */
+extern Elf_Scn *elf_nextscn (Elf *__elf, Elf_Scn *__scn);
+
+/* Create a new section and append it at the end of the table.  */
+extern Elf_Scn *elf_newscn (Elf *__elf);
+
+/* Get the number of sections in the ELF file.  If the file uses more
+   sections than can be represented in the e_shnum field of the ELF
+   header the information from the sh_size field in the zeroth section
+   header is used.  */
+extern int elf_getshnum (Elf *__elf, size_t *__dst);
+
+
+/* Get the section index of the section header string table in the ELF
+   file.  If the index cannot be represented in the e_shnum field of
+   the ELF header the information from the sh_link field in the zeroth
+   section header is used.  */
+extern int elf_getshstrndx (Elf *__elf, size_t *__dst);
+
+
+/* Retrieve section header of ELFCLASS32 binary.  */
+extern Elf32_Shdr *elf32_getshdr (Elf_Scn *__scn);
+/* Similar for ELFCLASS64.  */
+extern Elf64_Shdr *elf64_getshdr (Elf_Scn *__scn);
+
+
+/* Set or clear flags for ELF file.  */
+extern unsigned int elf_flagelf (Elf *__elf, Elf_Cmd __cmd,
+				 unsigned int __flags);
+/* Similarly for the ELF header.  */
+extern unsigned int elf_flagehdr (Elf *__elf, Elf_Cmd __cmd,
+				  unsigned int __flags);
+/* Similarly for the ELF program header.  */
+extern unsigned int elf_flagphdr (Elf *__elf, Elf_Cmd __cmd,
+				  unsigned int __flags);
+/* Similarly for the given ELF section.  */
+extern unsigned int elf_flagscn (Elf_Scn *__scn, Elf_Cmd __cmd,
+				 unsigned int __flags);
+/* Similarly for the given ELF data.  */
+extern unsigned int elf_flagdata (Elf_Data *__data, Elf_Cmd __cmd,
+				  unsigned int __flags);
+/* Similarly for the given ELF section header.  */
+extern unsigned int elf_flagshdr (Elf_Scn *__scn, Elf_Cmd __cmd,
+				  unsigned int __flags);
+
+
+/* Get data from section while translating from file representation
+   to memory representation.  */
+extern Elf_Data *elf_getdata (Elf_Scn *__scn, Elf_Data *__data);
+
+/* Get uninterpreted section content.  */
+extern Elf_Data *elf_rawdata (Elf_Scn *__scn, Elf_Data *__data);
+
+/* Create new data descriptor for section SCN.  */
+extern Elf_Data *elf_newdata (Elf_Scn *__scn);
+
+
+/* Return pointer to string at OFFSET in section INDEX.  */
+extern char *elf_strptr (Elf *__elf, size_t __index, size_t __offset);
+
+
+/* Return header of archive.  */
+extern Elf_Arhdr *elf_getarhdr (Elf *__elf);
+
+/* Select archive element at OFFSET.  */
+extern size_t elf_rand (Elf *__elf, size_t __offset);
+
+/* Get symbol table of archhive.  */
+extern Elf_Arsym *elf_getarsym (Elf *__elf, size_t *__ptr);
+
+
+/* Control ELF descriptor.  */
+extern int elf_cntl (Elf *__elf, Elf_Cmd __cmd);
+
+/* Retrieve uninterpreted file contents.  */
+extern char *elf_rawfile (Elf *__elf, size_t *__ptr);
+
+
+/* Return size of array of COUNT elements of the type denoted by TYPE
+   in the external representation.  The binary class is taken from ELF.
+   The result is based on version VERSION of the ELF standard.  */
+extern size_t elf32_fsize (Elf_Type __type, size_t __count,
+			   unsigned int __version)
+       __attribute__ ((__const__));
+/* Similar but this time the binary calls is ELFCLASS64.  */
+extern size_t elf64_fsize (Elf_Type __type, size_t __count,
+			   unsigned int __version)
+       __attribute__ ((__const__));
+
+
+/* Convert data structure from the representation in the file represented
+   by ELF to their memory representation.  */
+extern Elf_Data *elf32_xlatetom (Elf_Data *__dest, const Elf_Data *__src,
+				 unsigned int __encode);
+/* Same for 64 bit class.  */
+extern Elf_Data *elf64_xlatetom (Elf_Data *__dest, const Elf_Data *__src,
+				 unsigned int __encode);
+
+/* Convert data structure from to the representation in memory
+   represented by ELF file representation.  */
+extern Elf_Data *elf32_xlatetof (Elf_Data *__dest, const Elf_Data *__src,
+				 unsigned int __encode);
+/* Same for 64 bit class.  */
+extern Elf_Data *elf64_xlatetof (Elf_Data *__dest, const Elf_Data *__src,
+				 unsigned int __encode);
+
+
+/* Return error code of last failing function call.  This value is kept
+   separately for each thread.  */
+extern int elf_errno (void);
+
+/* Return error string for ERROR.  If ERROR is zero, return error string
+   for most recent error or NULL is none occurred.  If ERROR is -1 the
+   behaviour is similar to the last case except that not NULL but a legal
+   string is returned.  */
+extern const char *elf_errmsg (int __error);
+
+
+/* Coordinate ELF library and application versions.  */
+extern unsigned int elf_version (unsigned int __version);
+
+/* Set fill bytes used to fill holes in data structures.  */
+extern void elf_fill (int __fill);
+
+/* Compute hash value.  */
+extern unsigned long int elf_hash (const char *__string)
+       __attribute__ ((__pure__));
+
+
+/* Compute simple checksum from permanent parts of the ELF file.  */
+extern long int elf32_checksum (Elf *__elf);
+/* Similar but this time the binary calls is ELFCLASS64.  */
+extern long int elf64_checksum (Elf *__elf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* libelf.h */
diff --git a/libelf/libelf.map b/libelf/libelf.map
new file mode 100644
index 0000000..f416da7
--- /dev/null
+++ b/libelf/libelf.map
@@ -0,0 +1,106 @@
+ELFUTILS_1.0 {
+  global:
+    elf32_checksum;
+    elf32_fsize;
+    elf32_getehdr;
+    elf32_getphdr;
+    elf32_getshdr;
+    elf32_newehdr;
+    elf32_newphdr;
+    elf32_xlatetof;
+    elf32_xlatetom;
+    elf64_checksum;
+    elf64_fsize;
+    elf64_getehdr;
+    elf64_getphdr;
+    elf64_getshdr;
+    elf64_newehdr;
+    elf64_newphdr;
+    elf64_xlatetof;
+    elf64_xlatetom;
+    elf_begin;
+    elf_clone;
+    elf_cntl;
+    elf_end;
+    elf_errmsg;
+    elf_errno;
+    elf_fill;
+    elf_flagdata;
+    elf_flagehdr;
+    elf_flagelf;
+    elf_flagphdr;
+    elf_flagscn;
+    elf_flagshdr;
+    elf_getarhdr;
+    elf_getarsym;
+    elf_getbase;
+    elf_getdata;
+    elf_getident;
+    elf_getscn;
+    elf_getshnum;
+    elf_getshstrndx;
+    elf_hash;
+    elf_kind;
+    elf_memory;
+    elf_ndxscn;
+    elf_newdata;
+    elf_newscn;
+    elf_next;
+    elf_nextscn;
+    elf_rand;
+    elf_rawdata;
+    elf_rawfile;
+    elf_scncnt;
+    elf_strptr;
+    elf_update;
+    elf_version;
+    gelf_checksum;
+    gelf_freechunk;
+    gelf_fsize;
+    gelf_getclass;
+    gelf_getdyn;
+    gelf_getehdr;
+    gelf_getmove;
+    gelf_getphdr;
+    gelf_getrel;
+    gelf_getrela;
+    gelf_getshdr;
+    gelf_getsym;
+    gelf_getsyminfo;
+    gelf_getsymshndx;
+    gelf_getverdaux;
+    gelf_getverdef;
+    gelf_getvernaux;
+    gelf_getverneed;
+    gelf_getversym;
+    gelf_newehdr;
+    gelf_newphdr;
+    gelf_rawchunk;
+    gelf_update_dyn;
+    gelf_update_ehdr;
+    gelf_update_move;
+    gelf_update_phdr;
+    gelf_update_rel;
+    gelf_update_rela;
+    gelf_update_shdr;
+    gelf_update_sym;
+    gelf_update_syminfo;
+    gelf_update_symshndx;
+    gelf_update_verdaux;
+    gelf_update_verdef;
+    gelf_update_vernaux;
+    gelf_update_verneed;
+    gelf_update_versym;
+    gelf_xlatetof;
+    gelf_xlatetom;
+    nlist;
+
+  local:
+    *;
+};
+
+ELFUTILS_1.1 {
+  global:
+    gelf_getlib;
+    gelf_update_lib;
+} ELFUTILS_1.0;
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
new file mode 100644
index 0000000..100f349
--- /dev/null
+++ b/libelf/libelfP.h
@@ -0,0 +1,534 @@
+/* Internal interfaces for libelf.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Red Hat, Inc.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _LIBELFP_H
+#define _LIBELFP_H 1
+
+#include <ar.h>
+#include <gelf.h>
+#include <stdint.h>
+
+/* gettext helper macros.  */
+#define _(Str) dgettext ("libelf", Str)
+
+
+/* Helper Macros to write 32 bit and 64 bit functions.  */
+#define __elfw2_(Bits, Name) __elf##Bits##_##Name
+#define elfw2_(Bits, Name) elf##Bits##_##Name
+#define ElfW2_(Bits, Name) Elf##Bits##_##Name
+#define ELFW2_(Bits, Name) ELF##Bits##_##Name
+#define ELFW_(Name, Bits) Name##Bits
+#define __elfw2(Bits, Name) __elfw2_(Bits, Name)
+#define elfw2(Bits, Name) elfw2_(Bits, Name)
+#define ElfW2(Bits, Name) ElfW2_(Bits, Name)
+#define ELFW2(Bits, Name) ELFW2_(Bits, Name)
+#define ELFW(Name, Bits)  ELFW_(Name, Bits)
+
+
+/* Sizes of the external types, for 32 bits objects.  */
+#define ELF32_FSZ_ADDR   4
+#define ELF32_FSZ_OFF    4
+#define ELF32_FSZ_HALF   2
+#define ELF32_FSZ_WORD   4
+#define ELF32_FSZ_SWORD  4
+#define ELF32_FSZ_XWORD  8
+#define ELF32_FSZ_SXWORD 8
+
+/* Same for 64 bits objects.  */
+#define ELF64_FSZ_ADDR   8
+#define ELF64_FSZ_OFF    8
+#define ELF64_FSZ_HALF   2
+#define ELF64_FSZ_WORD   4
+#define ELF64_FSZ_SWORD  4
+#define ELF64_FSZ_XWORD  8
+#define ELF64_FSZ_SXWORD 8
+
+
+/* This is an extension of the ELF_F_* enumeration.  The values here are
+   not part of the library interface, they are only used internally.  */
+enum
+{
+  ELF_F_MMAPPED = 0x40,
+  ELF_F_MALLOCED = 0x80,
+  ELF_F_FILEDATA = 0x100
+};
+
+
+/* Get definition of all the external types.  */
+#include "exttypes.h"
+
+
+/* Error values.  */
+enum
+{
+  ELF_E_NOERROR = 0,
+  ELF_E_UNKNOWN_ERROR,
+  ELF_E_UNKNOWN_VERSION,
+  ELF_E_UNKNOWN_TYPE,
+  ELF_E_INVALID_HANDLE,
+  ELF_E_SOURCE_SIZE,
+  ELF_E_DEST_SIZE,
+  ELF_E_INVALID_ENCODING,
+  ELF_E_NOMEM,
+  ELF_E_INVALID_FILE,
+  ELF_E_INVALID_OP,
+  ELF_E_NO_VERSION,
+  ELF_E_INVALID_CMD,
+  ELF_E_RANGE,
+  ELF_E_ARCHIVE_FMAG,
+  ELF_E_INVALID_ARCHIVE,
+  ELF_E_NO_ARCHIVE,
+  ELF_E_NO_INDEX,
+  ELF_E_READ_ERROR,
+  ELF_E_WRITE_ERROR,
+  ELF_E_INVALID_CLASS,
+  ELF_E_INVALID_INDEX,
+  ELF_E_INVALID_OPERAND,
+  ELF_E_INVALID_SECTION,
+  ELF_E_INVALID_COMMAND,
+  ELF_E_WRONG_ORDER_EHDR,
+  ELF_E_FD_DISABLED,
+  ELF_E_FD_MISMATCH,
+  ELF_E_OFFSET_RANGE,
+  ELF_E_NOT_NUL_SECTION,
+  ELF_E_DATA_MISMATCH,
+  ELF_E_INVALID_SECTION_HEADER,
+  ELF_E_INVALID_DATA,
+  ELF_E_DATA_ENCODING,
+  ELF_E_SECTION_TOO_SMALL,
+  ELF_E_INVALID_ALIGN,
+  ELF_E_INVALID_SHENTSIZE,
+  ELF_E_UPDATE_RO,
+  ELF_E_NOFILE,
+  ELF_E_GROUP_NOT_REL,
+  ELF_E_INVALID_PHDR,
+  ELF_E_NO_PHDR,
+  /* Keep this as the last entry.  */
+  ELF_E_NUM
+};
+
+
+/* The visible `Elf_Data' type is not sufficent for some operations due
+   to a misdesigned interface.  Extend it for internal purposes.  */
+typedef struct
+{
+  Elf_Data d;
+  Elf_Scn *s;
+} Elf_Data_Scn;
+
+
+/* List of `Elf_Data' descriptors.  This is what makes up the section
+   contents.  */
+typedef struct Elf_Data_List
+{
+  /* `data' *must* be the first element in the struct.  */
+  Elf_Data_Scn data;
+  struct Elf_Data_List *next;
+  int flags;
+} Elf_Data_List;
+
+
+/* Descriptor for ELF section.  */
+struct Elf_Scn
+{
+  /* We have to distinguish several different situations:
+
+     1. the section is user created.  Therefore there is no file or memory
+        region to read the data from.  Here we have two different subcases:
+
+        a) data was not yet added (before the first `elf_newdata' call)
+
+        b) at least one data set is available
+
+     2. this is a section from a file/memory region.  We have to read the
+        current content in one data block if we have to.  But we don't
+        read the data until it is necessary.  So we have the subcases:
+
+        a) the section in the file has size zero (for whatever reason)
+
+        b) the data of the file is not (yet) read
+
+        c) the data is read and available.
+
+     In addition to this we have different data sets, the raw and the converted
+     data.  This distinction only exists for the data read from the file.
+     All user-added data set (all but the first when read from the file or
+     all of them for user-create sections) are the same in both formats.
+     We don't create the converted data before it is necessary.
+
+     The `data_read' element signals whether data is available in the
+     raw format.
+
+     If there is data from the file/memory region or if read one data
+     set is added the `rawdata_list_read' pointer in non-NULL and points
+     to the last filled data set.  `raw_datalist_rear' is therefore NULL
+     only if there is no data set at all.
+
+     This so far allows to distinguish all but two cases (given that the
+     `rawdata_list' and `data_list' entries are initialized to zero) is
+     between not yet loaded data from the file/memory region and a section
+     with zero size and type ELF_T_BYTE.   */
+  Elf_Data_List data_list;	/* List of data buffers.  */
+  Elf_Data_List *data_list_rear; /* Pointer to the rear of the data list. */
+
+  Elf_Data_Scn rawdata;		/* Uninterpreted data of the section.  */
+
+  int data_read;		/* Nonzero if the section was created by the
+				   user or if the data from the file/memory
+				   is read.  */
+
+  size_t index;			/* Index of this section.  */
+  struct Elf *elf;		/* The underlying ELF file.  */
+
+  union
+  {
+    Elf32_Shdr *e32;		/* Pointer to 32bit section header.  */
+    Elf64_Shdr *e64;		/* Pointer to 64bit section header.  */
+  } shdr;
+
+  unsigned int shdr_flags;	/* Section header modified?  */
+  unsigned int flags;		/* Section changed in size?  */
+
+  char *rawdata_base;		/* The unmodified data of the section.  */
+  char *data_base;		/* The converted data of the section.  */
+
+  struct Elf_ScnList *list;	/* Pointer the the section list element the
+				   data is in.  */
+};
+
+
+/* List of section.  */
+typedef struct Elf_ScnList
+{
+  unsigned int cnt;		/* Number of elements of 'data' used.  */
+  unsigned int max;		/* Number of elements of 'data' allocated.  */
+  struct Elf_ScnList *next;	/* Next block of sections.  */
+  struct Elf_Scn data[0];	/* Section data.  */
+} Elf_ScnList;
+
+
+/* The ELF descriptor.  */
+struct Elf
+{
+  /* What kind of file is underneath (ELF file, archive...).  */
+  Elf_Kind kind;
+
+  /* Command used to create this descriptor.  */
+  Elf_Cmd cmd;
+
+  /* The binary class.  */
+  unsigned int class;
+
+  /* The used file descriptor.  -1 if not available anymore.  */
+  int fildes;
+
+  /* Offset in the archive this file starts or zero.  */
+  off_t start_offset;
+
+  /* Size of the file in the archive or the entire file size, or ~0
+     for an (yet) unknown size.  */
+  size_t maximum_size;
+
+  /* Address to which the file was mapped.  NULL if not mapped.  */
+  void *map_address;
+
+  /* Describes the way the memory was allocated and if the dirty bit is
+     signalled it means that the whole file has to be rewritten since
+     the layout changed.  */
+  int flags;
+
+  /* When created for an archive member this points to the descriptor
+     for the archive. */
+  Elf *parent;
+
+  /* Lock to handle multithreaded programs.  */
+  rwlock_define (,lock);
+
+  /* Reference counting for the descriptor.  */
+  int ref_count;
+
+  struct Elf *next;             /* Used in list of archive descriptors.  */
+
+  union
+  {
+    struct
+    {
+      int ehdr_flags;		/* Flags (dirty) for ELF header.  */
+      int phdr_flags;		/* Flags (dirty|malloc) for program header.  */
+      int shdr_malloced;	/* Nonzero if shdr array was allocated.  */
+
+      /* The next fields are only useful when testing for ==/!= NULL.  */
+      void *ehdr;
+      void *shdr;
+      void *phdr;
+
+      Elf_ScnList *scns_last;	/* Last element in the section list.
+				   If NULL the data has not yet been
+				   read from the file.  */
+      unsigned int scnincr;	/* Number of sections allocate the last
+				   time.  */
+      off64_t sizestr_offset;	/* Offset of the size string in the parent
+				   if this is an archive member.  */
+    } elf;
+
+    struct
+    {
+      int ehdr_flags;		/* Flags (dirty) for ELF header.  */
+      int phdr_flags;		/* Flags (dirty|malloc) for program header.  */
+      int shdr_malloced;	/* Nonzero if shdr array was allocated.  */
+
+      Elf32_Ehdr *ehdr;		/* Pointer to the ELF header.  This is
+				   never malloced.  */
+      Elf32_Shdr *shdr;		/* Used when reading from a file.  */
+      Elf32_Phdr *phdr;		/* Pointer to the program header array.  */
+      Elf_ScnList *scns_last;	/* Last element in the section list.
+				   If NULL the data has not yet been
+				   read from the file.  */
+      unsigned int scnincr;	/* Number of sections allocate the last
+				   time.  */
+      off64_t sizestr_offset;	/* Offset of the size string in the parent
+				   if this is an archive member.  */
+      Elf32_Ehdr ehdr_mem;	/* Memory used for ELF header when not
+				   mmaped.  */
+      char __e32scnspad[sizeof (Elf64_Ehdr) - sizeof (Elf32_Ehdr)];
+
+      /* The section array.  */
+      Elf_ScnList scns;
+    } elf32;
+
+    struct
+    {
+      int ehdr_flags;		/* Flags (dirty) for ELF header.  */
+      int phdr_flags;		/* Flags (dirty|malloc) for program header.  */
+      int shdr_malloced;	/* Nonzero if shdr array was allocated.  */
+
+      Elf64_Ehdr *ehdr;		/* Pointer to the ELF header.  This is
+				   never malloced.  */
+      Elf64_Shdr *shdr;		/* Used when reading from a file.  */
+      Elf64_Phdr *phdr;		/* Pointer to the program header array.  */
+      Elf_ScnList *scns_last;	/* Last element in the section list.
+				   If NULL the data has not yet been
+				   read from the file.  */
+      unsigned int scnincr;	/* Number of sections allocate the last
+				   time.  */
+      off64_t sizestr_offset;	/* Offset of the size string in the parent
+				   if this is an archive member.  */
+      Elf64_Ehdr ehdr_mem;	/* Memory used for ELF header when not
+				   mmaped.  */
+
+      /* The section array.  */
+      Elf_ScnList scns;
+    } elf64;
+
+    struct
+    {
+      int has_index;		/* Set when file has index.  0 means
+				   undecided, > 0 means it has one.  */
+      Elf_Arsym *ar_sym;	/* Symbol table returned by elf_getarsym.  */
+      size_t ar_sym_num;	/* Number of entries in `ar_sym'.  */
+      char *long_names;		/* If no index is available but long names
+				   are used this elements points to the data.*/
+      size_t long_names_len;	/* Length of the long name table.  */
+      off_t offset;		/* Offset in file we are currently at.
+				   elf_next() advances this to the next
+				   member of the archive.  */
+      Elf_Arhdr elf_ar_hdr;	/* Structure returned by 'elf_getarhdr'.  */
+      struct ar_hdr ar_hdr;	/* Header read from file.  */
+      char ar_name[16];		/* NUL terminated ar_name of elf_ar_hdr.  */
+      char raw_name[17];	/* This is a buffer for the NUL terminated
+				   named raw_name used in the elf_ar_hdr.  */
+      struct Elf *children;	/* List of all descriptors for this archive. */
+    } ar;
+  } state;
+
+  /* There absolutely never must be anything following the union.  */
+};
+
+
+/* Type of the conversion functions.  These functions will convert the
+   byte order.  */
+typedef void (*xfct_t) (void *, const void *, size_t, int);
+
+/* The table with the function pointers.  */
+extern const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
+extern const xfct_t __elf_xfctstof[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
+
+
+/* Array with sizes of the external types indexed by ELF version, binary
+   class, and type. */
+extern const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
+/* We often have to access the size for a type in the current version.  */
+#if EV_NUM != 2
+# define elf_typesize(class,type,n) \
+  elfw2(class,fsize) (type, n, __libelf_version)
+#else
+# define elf_typesize(class,type,n) \
+  (__libelf_type_sizes[EV_CURRENT - 1][ELFW(ELFCLASS,class) - 1][type] * n)
+#endif
+
+/* Currently selected version of the ELF specification.  */
+extern unsigned int __libelf_version attribute_hidden;
+
+/* The byte value used for filling gaps.  */
+extern int __libelf_fill_byte attribute_hidden;
+
+/* Nonzero if the version was set.  */
+extern int __libelf_version_initialized attribute_hidden;
+
+
+/* The libelf API does not have such a function but it is still useful.
+   Get the memory size for the given type.
+
+   These functions cannot be marked internal since they are aliases
+   of the export elfXX_fsize functions.*/
+extern size_t __elf32_msize (Elf_Type __type, size_t __count,
+			     unsigned int __version);
+extern size_t __elf64_msize (Elf_Type __type, size_t __count,
+			     unsigned int __version);
+
+
+/* Create Elf descriptor from memory image.  */
+extern Elf *__libelf_read_mmaped_file (int fildes, void *map_address,
+				       off_t offset, size_t maxsize,
+				       Elf_Cmd cmd, Elf *parent)
+     internal_function;
+
+/* Set error value.  */
+extern void __libelf_seterrno (int value) internal_function;
+
+/* Get the next archive header.  */
+extern int __libelf_next_arhdr (Elf *elf) internal_function;
+
+/* Read all of the file associated with the descriptor.  */
+extern char *__libelf_readall (Elf *elf) internal_function;
+
+/* Read the complete section table and convert the byte order if necessary.  */
+extern int __libelf_readsections (Elf *elf) internal_function;
+
+/* Store the information for the raw data in the `rawdata_list' element.  */
+extern int __libelf_set_rawdata (Elf_Scn *scn) internal_function;
+
+
+/* Helper functions for elf_update.  */
+extern off_t __elf32_updatenull (Elf *elf, int *change_bop, size_t shnum)
+     internal_function;
+extern off_t __elf64_updatenull (Elf *elf, int *change_bop, size_t shnum)
+     internal_function;
+
+extern int __elf32_updatemmap (Elf *elf, int change_bo, size_t shnum)
+     internal_function;
+extern int __elf64_updatemmap (Elf *elf, int change_bo, size_t shnum)
+     internal_function;
+extern int __elf32_updatefile (Elf *elf, int change_bo, size_t shnum)
+     internal_function;
+extern int __elf64_updatefile (Elf *elf, int change_bo, size_t shnum)
+     internal_function;
+
+
+/* Alias for exported functions to avoid PLT entries.  */
+extern int __elf_end_internal (Elf *__elf);
+extern Elf *__elf_begin_internal (int __fildes, Elf_Cmd __cmd, Elf *__ref)
+     attribute_hidden;
+extern Elf32_Ehdr *__elf32_getehdr_internal (Elf *__elf) attribute_hidden;
+extern Elf64_Ehdr *__elf64_getehdr_internal (Elf *__elf) attribute_hidden;
+extern Elf32_Ehdr *__elf32_newehdr_internal (Elf *__elf) attribute_hidden;
+extern Elf64_Ehdr *__elf64_newehdr_internal (Elf *__elf) attribute_hidden;
+extern Elf32_Phdr *__elf32_getphdr_internal (Elf *__elf) attribute_hidden;
+extern Elf64_Phdr *__elf64_getphdr_internal (Elf *__elf) attribute_hidden;
+extern Elf32_Phdr *__elf32_newphdr_internal (Elf *__elf, size_t __cnt)
+     attribute_hidden;
+extern Elf64_Phdr *__elf64_newphdr_internal (Elf *__elf, size_t __cnt)
+     attribute_hidden;
+extern int __elf_getshnum_internal (Elf *__elf, size_t *__dst)
+     attribute_hidden;
+extern int __elf_getshstrndx_internal (Elf *__elf, size_t *__dst)
+     attribute_hidden;
+extern Elf32_Shdr *__elf32_getshdr_internal (Elf_Scn *__scn) attribute_hidden;
+extern Elf64_Shdr *__elf64_getshdr_internal (Elf_Scn *__scn) attribute_hidden;
+extern Elf_Scn *__elf_getscn_internal (Elf *__elf, size_t __index)
+     attribute_hidden;
+extern Elf_Scn *__elf_nextscn_internal (Elf *__elf, Elf_Scn *__scn)
+     attribute_hidden;
+extern Elf_Data *__elf_getdata_internal (Elf_Scn *__scn, Elf_Data *__data)
+     attribute_hidden;
+extern Elf_Data *__elf_rawdata_internal (Elf_Scn *__scn, Elf_Data *__data)
+     attribute_hidden;
+extern char *__elf_strptr_internal (Elf *__elf, size_t __index,
+				    size_t __offset) attribute_hidden;
+extern Elf_Data *__elf32_xlatetom_internal (Elf_Data *__dest,
+					    const Elf_Data *__src,
+					    unsigned int __encode)
+     attribute_hidden;
+extern Elf_Data *__elf64_xlatetom_internal (Elf_Data *__dest,
+					    const Elf_Data *__src,
+					    unsigned int __encode)
+     attribute_hidden;
+extern Elf_Data *__elf32_xlatetof_internal (Elf_Data *__dest,
+					    const Elf_Data *__src,
+					    unsigned int __encode)
+     attribute_hidden;
+extern Elf_Data *__elf64_xlatetof_internal (Elf_Data *__dest,
+					    const Elf_Data *__src,
+					    unsigned int __encode)
+     attribute_hidden;
+extern unsigned int __elf_version_internal (unsigned int __version)
+     attribute_hidden;
+extern unsigned long int __elf_hash_internal (const char *__string)
+       __attribute__ ((__pure__, visibility ("hidden")));
+extern long int __elf32_checksum_internal (Elf *__elf) attribute_hidden;
+extern long int __elf64_checksum_internal (Elf *__elf) attribute_hidden;
+
+
+extern GElf_Ehdr *__gelf_getehdr_internal (Elf *__elf, GElf_Ehdr *__dest);
+extern size_t __gelf_fsize_internal (Elf *__elf, Elf_Type __type,
+				     size_t __count, unsigned int __version)
+     attribute_hidden;
+extern GElf_Shdr *__gelf_getshdr_internal (Elf_Scn *__scn, GElf_Shdr *__dst)
+     attribute_hidden;
+extern GElf_Sym *__gelf_getsym_internal (Elf_Data *__data, int __ndx,
+					 GElf_Sym *__dst) attribute_hidden;
+
+
+extern uint32_t __libelf_crc32 (uint32_t crc, unsigned char *buf, size_t len)
+     attribute_hidden;
+
+
+/* We often have to update a flag iff a value changed.  Make this
+   convenient.  None of the parameters must have a side effect.  */
+#ifdef __GNUC__
+# define update_if_changed(var, exp, flag) \
+  do {									      \
+    __typeof__ (var) *_var = &(var);					      \
+    __typeof__ (exp) _exp = (exp);					      \
+    if (*_var != _exp)							      \
+      {									      \
+	*_var = _exp;							      \
+	(flag) |= ELF_F_DIRTY;						      \
+      }									      \
+  } while (0)
+#else
+# define update_if_changed(var, exp, flag) \
+  do {									      \
+    if ((var) != (exp))							      \
+      {									      \
+	(var) = (exp);							      \
+	(flag) |= ELF_F_DIRTY;						      \
+      }									      \
+  } while (0)
+#endif
+
+#endif  /* libelfP.h */
diff --git a/libelf/libelf_crc32.c b/libelf/libelf_crc32.c
new file mode 100644
index 0000000..6971be0
--- /dev/null
+++ b/libelf/libelf_crc32.c
@@ -0,0 +1,23 @@
+/* Copyright (C) 2002 Red Hat, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define crc32 attribute_hidden __libelf_crc32
+#define LIB_SYSTEM_H	1
+#include <libelf.h>
+#include "../lib/crc32.c"
diff --git a/libelf/libelf_next_prime.c b/libelf/libelf_next_prime.c
new file mode 100644
index 0000000..4a71c47
--- /dev/null
+++ b/libelf/libelf_next_prime.c
@@ -0,0 +1,21 @@
+/* Copyright (C) 2002 Red Hat, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define next_prime attribute_hidden __libelf_next_prime
+#include "../lib/next_prime.c"
diff --git a/libelf/nlist.c b/libelf/nlist.c
new file mode 100644
index 0000000..b9ff213
--- /dev/null
+++ b/libelf/nlist.c
@@ -0,0 +1,224 @@
+/* Extract symbol list from binary.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <gelf.h>
+#include <libelf.h>
+#include <nlist.h>
+#include <unistd.h>
+
+#include "libelfP.h"
+
+
+struct hashentry
+{
+  const char *str;
+  GElf_Sym sym;
+};
+#define TYPE struct hashentry
+/* XXX Use a better hash function some day.  */
+#define HASHFCT(str, len) INTUSE(elf_hash) (str)
+#define COMPARE(p1, p2) strcmp ((p1)->str, (p2)->str)
+#define CLASS static
+#define PREFIX nlist_
+#define xcalloc(n, m) calloc (n, m)
+#define next_prime(s) __libelf_next_prime (s)
+#include <fixedsizehash.h>
+
+
+int
+nlist (const char *filename, struct nlist *nl)
+{
+  int fd;
+  Elf *elf;
+  Elf_Scn *scn = NULL;
+  Elf_Scn *symscn = NULL;
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = NULL;
+  Elf_Data *data;
+  struct nlist_fshash *table;
+  size_t nsyms;
+  size_t cnt;
+
+  /* Open the file.  */
+  fd = open (filename, O_RDONLY);
+  if (fd == -1)
+    {
+      __libelf_seterrno (ELF_E_NOFILE);
+      goto fail;
+    }
+
+  /* For compatibility reasons (`nlist' existed before ELF and libelf)
+     we don't expect the caller to set the ELF version.  Do this here
+     if it hasn't happened yet.  */
+  if (__libelf_version_initialized == 0)
+    INTUSE(elf_version) (EV_CURRENT);
+
+  /* Now get an ELF descriptor.  */
+  elf = INTUSE(elf_begin) (fd, ELF_C_READ_MMAP, NULL);
+  if (elf == NULL)
+    goto fail;
+
+  /* Find a symbol table.  We prefer the real symbol table but if it
+     does not exist use the dynamic symbol table.  */
+  while ((scn = INTUSE(elf_nextscn) (elf, scn)) != NULL)
+    {
+      shdr = INTUSE(gelf_getshdr) (scn, &shdr_mem);
+      if (shdr == NULL)
+	goto fail_close;
+
+      /* That is what we are looking for.  */
+      if (shdr->sh_type == SHT_SYMTAB)
+	{
+	  symscn = scn;
+	  break;
+	}
+
+      /* Better than nothing.  Remember this section.  */
+      if (shdr->sh_type == SHT_DYNSYM)
+	symscn = scn;
+    }
+
+  if (symscn == NULL)
+    /* We haven't found anything.  Fail.  */
+    goto fail_close;
+
+  /* Re-get the section header in case we found only the dynamic symbol
+     table.  */
+  if (scn == NULL)
+    shdr = INTUSE(gelf_getshdr) (symscn, &shdr_mem);
+  /* SHDR->SH_LINK now contains the index of the string section.  */
+
+  /* Get the data for the symbol section.  */
+  data = INTUSE(elf_getdata) (symscn, NULL);
+  if (data == NULL)
+    goto fail_close;
+
+  /* How many symbols are there?  */
+  nsyms = (shdr->sh_size
+	   / INTUSE(gelf_fsize) (elf, ELF_T_SYM, 1, data->d_version));
+
+  /* Create the hash table.  */
+  table = nlist_fshash_init (nsyms);
+  if (table == NULL)
+    {
+      __libelf_seterrno (ELF_E_NOMEM);
+      goto fail_close;
+    }
+
+  /* Iterate over all the symbols in the section.  */
+  for (cnt = 0; cnt < nsyms; ++cnt)
+    {
+      struct hashentry mem;
+      GElf_Sym *sym;
+
+      /* Get the symbol.  */
+      sym = INTUSE(gelf_getsym) (data, cnt, &mem.sym);
+      if (sym == NULL)
+	goto fail_dealloc;
+
+      /* Get the name of the symbol.  */
+      mem.str = INTUSE(elf_strptr) (elf, shdr->sh_link, sym->st_name);
+      if (mem.str == NULL)
+	goto fail_dealloc;
+
+      /* Don't allow zero-length strings.  */
+      if (mem.str[0] == '\0')
+	continue;
+
+      /* And add it to the hash table.  Note that we are using the
+         overwrite version.  This will ensure that
+	 a) global symbols are preferred over local symbols since
+	    they are all located at the end
+	 b) if there are multiple local symbols with the same name
+	    the last one is used.
+      */
+      (void) nlist_fshash_overwrite (table, mem.str, 0, &mem);
+    }
+
+  /* Now it is time to look for the symbols the user asked for.
+     XXX What is a `null name/null string'?  This is what the
+     standard says terminates the list.  Is it a null pointer
+     or a zero-length string?  We test for both...  */
+  while (nl->n_name != NULL && nl->n_name[0] != '\0')
+    {
+      struct hashentry search;
+      const struct hashentry *found;
+
+      /* Search for a matching entry in the hash table.  */
+      search.str = nl->n_name;
+      found = nlist_fshash_find (table, nl->n_name, 0, &search);
+
+      if (found != NULL)
+	{
+	  /* Found it.  */
+	  nl->n_value = found->sym.st_value;
+	  nl->n_scnum = found->sym.st_shndx;
+	  nl->n_type = GELF_ST_TYPE (found->sym.st_info);
+	  /* XXX What shall we fill in the next fields?  */
+	  nl->n_sclass = 0;
+	  nl->n_numaux = 0;
+	}
+      else
+	{
+	  /* Not there.  */
+	  nl->n_value = 0;
+	  nl->n_scnum = 0;
+	  nl->n_type = 0;
+	  nl->n_sclass = 0;
+	  nl->n_numaux = 0;
+	}
+
+      /* Next search request.  */
+      ++nl;
+    }
+
+  /* Free the resources.  */
+  nlist_fshash_fini (table);
+
+  /* We do not need the ELF descriptor anymore.  */
+  (void) INTUSE(elf_end) (elf);
+
+  return 0;
+
+ fail_dealloc:
+  nlist_fshash_fini (table);
+
+ fail_close:
+  /* We do not need the ELF descriptor anymore.  */
+  (void) INTUSE(elf_end) (elf);
+
+ fail:
+  /* We have to set all entries to zero.  */
+  while (nl->n_name != NULL && nl->n_name[0] != '\0')
+    {
+      nl->n_value = 0;
+      nl->n_scnum = 0;
+      nl->n_type = 0;
+      nl->n_sclass = 0;
+      nl->n_numaux = 0;
+
+      /* Next entry.  */
+      ++nl;
+    }
+
+  return -1;
+}
diff --git a/libelf/nlist.h b/libelf/nlist.h
new file mode 100644
index 0000000..298f9a2
--- /dev/null
+++ b/libelf/nlist.h
@@ -0,0 +1,44 @@
+/* Interface for nlist.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _NLIST_H
+#define _NLIST_H 1
+
+
+/* Symbol list type.  */
+struct nlist
+{
+  char *n_name;			/* Symbol name.  */
+  long int n_value;		/* Value of symbol.  */
+  short int n_scnum;		/* Section number found in.  */
+  unsigned short int n_type;	/* Type of symbol.  */
+  char n_sclass;		/* Storage class.  */
+  char n_numaux;		/* Number of auxiliary entries.  */
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Get specified entries from file.  */
+extern int nlist (__const char *__filename, struct nlist *__nl);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* nlist.h */
diff --git a/libelf/version_xlate.h b/libelf/version_xlate.h
new file mode 100644
index 0000000..2366cbf
--- /dev/null
+++ b/libelf/version_xlate.h
@@ -0,0 +1,208 @@
+/* Conversion functions for versioning information.
+   Copyright (C) 1998, 1999, 2000, 2002, 2003 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 2.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include <assert.h>
+#include <gelf.h>
+
+#include "libelfP.h"
+
+
+static void
+elf_cvt_Verdef (void *dest, const void *src, size_t len, int encode)
+{
+  /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux.
+     To recognize them we have to walk the data structure and convert
+     them one after the other.  The ENCODE parameter specifies whether
+     we are encoding or decoding.  When we are encoding we can immediately
+     use the data in the buffer; if not, we have to decode the data before
+     using it.  */
+  size_t def_offset = 0;
+  GElf_Verdef *ddest;
+  GElf_Verdef *dsrc;
+
+  /* We rely on the types being all the same size.  */
+  assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef));
+  assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux));
+  assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef));
+  assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux));
+
+  if (len == 0)
+    return;
+
+  do
+    {
+      size_t aux_offset;
+      GElf_Verdaux *asrc;
+
+      /* Test for correct offset.  */
+      if (def_offset + sizeof (GElf_Verdef) > len)
+	return;
+
+      /* Work the tree from the first record.  */
+      ddest = (GElf_Verdef *) ((char *) dest + def_offset);
+      dsrc = (GElf_Verdef *) ((char *) src + def_offset);
+
+      /* Decode first if necessary.  */
+      if (! encode)
+	{
+	  ddest->vd_version = bswap_16 (dsrc->vd_version);
+	  ddest->vd_flags = bswap_16 (dsrc->vd_flags);
+	  ddest->vd_ndx = bswap_16 (dsrc->vd_ndx);
+	  ddest->vd_cnt = bswap_16 (dsrc->vd_cnt);
+	  ddest->vd_hash = bswap_32 (dsrc->vd_hash);
+	  ddest->vd_aux = bswap_32 (dsrc->vd_aux);
+	  ddest->vd_next = bswap_32 (dsrc->vd_next);
+
+	  aux_offset = def_offset + ddest->vd_aux;
+	}
+      else
+	aux_offset = def_offset + dsrc->vd_aux;
+
+      /* Handle all the auxiliary records belonging to this definition.  */
+      do
+	{
+	  GElf_Verdaux *adest;
+
+	  /* Test for correct offset.  */
+	  if (aux_offset + sizeof (GElf_Verdaux) > len)
+	    return;
+
+	  adest = (GElf_Verdaux *) ((char *) dest + aux_offset);
+	  asrc = (GElf_Verdaux *) ((char *) src + aux_offset);
+
+	  if (encode)
+	    aux_offset += asrc->vda_next;
+
+	  adest->vda_name = bswap_32 (asrc->vda_name);
+	  adest->vda_next = bswap_32 (asrc->vda_next);
+
+	  if (! encode)
+	    aux_offset += adest->vda_next;
+	}
+      while (asrc->vda_next != 0);
+
+      /* Encode now if necessary.  */
+      if (encode)
+	{
+	  def_offset += dsrc->vd_next;
+
+	  ddest->vd_version = bswap_16 (dsrc->vd_version);
+	  ddest->vd_flags = bswap_16 (dsrc->vd_flags);
+	  ddest->vd_ndx = bswap_16 (dsrc->vd_ndx);
+	  ddest->vd_cnt = bswap_16 (dsrc->vd_cnt);
+	  ddest->vd_hash = bswap_32 (dsrc->vd_hash);
+	  ddest->vd_aux = bswap_32 (dsrc->vd_aux);
+	  ddest->vd_next = bswap_32 (dsrc->vd_next);
+	}
+      else
+	def_offset += ddest->vd_next;
+    }
+  while (dsrc->vd_next != 0);
+}
+
+
+static void
+elf_cvt_Verneed (void *dest, const void *src, size_t len, int encode)
+{
+  /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux.
+     To recognize them we have to walk the data structure and convert
+     them one after the other.  The ENCODE parameter specifies whether
+     we are encoding or decoding.  When we are encoding we can immediately
+     use the data in the buffer; if not, we have to decode the data before
+     using it.  */
+  size_t need_offset = 0;
+  GElf_Verneed *ndest;
+  GElf_Verneed *nsrc;
+
+  /* We rely on the types being all the same size.  */
+  assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed));
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux));
+  assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed));
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux));
+
+  if (len == 0)
+    return;
+
+  do
+    {
+      size_t aux_offset;
+      GElf_Vernaux *asrc;
+
+      /* Test for correct offset.  */
+      if (need_offset + sizeof (GElf_Verneed) > len)
+	return;
+
+      /* Work the tree from the first record.  */
+      ndest = (GElf_Verneed *) ((char *) dest + need_offset);
+      nsrc = (GElf_Verneed *) ((char *) src + need_offset);
+
+      /* Decode first if necessary.  */
+      if (! encode)
+	{
+	  ndest->vn_version = bswap_16 (nsrc->vn_version);
+	  ndest->vn_cnt = bswap_16 (nsrc->vn_cnt);
+	  ndest->vn_file = bswap_32 (nsrc->vn_file);
+	  ndest->vn_aux = bswap_32 (nsrc->vn_aux);
+	  ndest->vn_next = bswap_32 (nsrc->vn_next);
+
+	  aux_offset = need_offset + ndest->vn_aux;
+	}
+      else
+	aux_offset = need_offset + nsrc->vn_aux;
+
+      /* Handle all the auxiliary records belonging to this requirement.  */
+      do
+	{
+	  GElf_Vernaux *adest;
+
+	  /* Test for correct offset.  */
+	  if (aux_offset + sizeof (GElf_Vernaux) > len)
+	    return;
+
+	  adest = (GElf_Vernaux *) ((char *) dest + aux_offset);
+	  asrc = (GElf_Vernaux *) ((char *) src + aux_offset);
+
+	  if (encode)
+	    aux_offset += asrc->vna_next;
+
+	  adest->vna_hash = bswap_32 (asrc->vna_hash);
+	  adest->vna_flags = bswap_16 (asrc->vna_flags);
+	  adest->vna_other = bswap_16 (asrc->vna_other);
+	  adest->vna_name = bswap_32 (asrc->vna_name);
+	  adest->vna_next = bswap_32 (asrc->vna_next);
+
+	  if (! encode)
+	    aux_offset += adest->vna_next;
+	}
+      while (asrc->vna_next != 0);
+
+      /* Encode now if necessary.  */
+      if (encode)
+	{
+	  need_offset += nsrc->vn_next;
+
+	  ndest->vn_version = bswap_16 (nsrc->vn_version);
+	  ndest->vn_cnt = bswap_16 (nsrc->vn_cnt);
+	  ndest->vn_file = bswap_32 (nsrc->vn_file);
+	  ndest->vn_aux = bswap_32 (nsrc->vn_aux);
+	  ndest->vn_next = bswap_32 (nsrc->vn_next);
+	}
+      else
+	need_offset += ndest->vn_next;
+    }
+  while (nsrc->vn_next != 0);
+}