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);
+}