Squashed 'third_party/elfutils/' content from commit 555e15e

Change-Id: I61cde98949e47e5c8c09c33260de17f30921be79
git-subtree-dir: third_party/elfutils
git-subtree-split: 555e15ebe8bf1eb33d00747173cfc80cc65648a4
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
new file mode 100644
index 0000000..55ab25c
--- /dev/null
+++ b/libelf/ChangeLog
@@ -0,0 +1,1529 @@
+2018-02-09  Joshua Watt  <JPEWhacker@gmail.com>
+
+	* elf32_updatenull.c (updatenull_wrlock): Use FALLTHROUGH macro
+	instead of comment.
+	* elf_begin.c (read_unmmaped_file): Likewise.
+	(elf_begin): Likewise.
+	* elf_cntl.c (elf_cntl): Likewise.
+
+2017-10-04  Mark Wielaard  <mark@klomp.org>
+
+	* elf_begin.c (file_read_elf): Skip sanity checking e_shoff if scncnt
+	is zero, we won't use it then.
+
+2017-10-04  Mark Wielaard  <mark@klomp.org>
+
+	* libelfP.h: Add ELF_E_INVALID_ELF to error values enum.
+	* elf_error.c (ELF_E_INVALID_ELF_IDX): New define. Use it as value
+	for ELF_E_INVALID_ELF in msgidx.
+	* elf_getshdrstrndx.c (elf_getshdrstrndx): Distinquish between pread
+	failing and not having enough data.
+	* elf_begin.c (get_shnum): Likewise. Explicitly set libelf errno on
+	too large value.
+	(file_read_elf): Make sure to always set libelf errno when returning
+	NULL. Distinquish between i/o file and elf data errors.
+
+2017-08-18  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* gelf_xlate.c: Use attribute_packed.
+
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* libelfP.h: Use attribute_hidden.
+
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Use fpic_CFLAGS and dso_LDFLAGS.
+
+2017-08-15  Mark Wielaard  <mark@klomp.org>
+
+	* elf.h: Update from glibc. Add new powerpc note descriptors.
+
+2017-07-19  Gustavo Romero <gromero@linux.vnet.ibm.com>
+
+	* elf.h: Add known type in notes segment descriptor for HTM SPRs.
+
+2017-02-17  Ulf hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Add libelf_so_DEPS, which include libeu.a,
+	libelf_so_LIBS.
+	(libelf_so_LDLIBS): Add $(libelf_so_DEPS).
+	(libelf.so$(EXEEXT): Use $(libelf_so_LIBS), require libelf.map
+	from the right directory.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* libelfP.h: Don't include config.h.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* elf_begin.c: Use F_GETFD rather than F_GETFL.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* libelf.h: Define macros for various function attributes and use
+	them.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* elf_update.c: Set ELF_F_MMAPPED flag if we mmap from elf_update.
+
+2017-04-19  Mark Wielaard  <mark@klomp.org>
+
+	* elf_getarsym.c (elf_getarsym): Initialize n to zero.
+
+2017-03-27  Mark Wielaard  <mark@klomp.org>
+
+	* elf32_updatefile.c (updatemmap): Always update last_positition.
+	(updatefile): Likewise.
+
+2017-03-24  Mark Wielaard  <mark@klomp.org>
+
+	* elf_compress.c (__libelf_decompress): Check insane compression
+	ratios before trying to allocate output buffer.
+
+2016-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+	    Mark Wielaard  <mjw@redhat.com>
+
+	* gelf.h (gelf_newehdr): Change return type to void *.
+	(gelf_newphdr): Likewise.
+	* gelf_newehdr.c (gelf_newehdr): Likewise.
+	* gelf_newphdr.c (gelf_newphdr): Likewise.
+
+2016-10-21  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getdata.c (__libelf_set_rawdata_wrlock): Sanity check
+	offset and size before trying to malloc and read data.
+
+2016-10-26  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (read_file): Always set maxsize when parent == NULL.
+
+2016-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+	* elf_getarsym.c (elf_getarsym): Open code rawmemchr when not
+	available.
+	* elf_strptr.c: Include stdbool.h.
+	(validate_str): New function.
+	(elf_strptr): Use validate_str instead of memrchr.
+
+2016-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+	* elf32_updatefile.c: Remove sys/param.h include.
+	* elf32_updatenull.c: Likewise. Add system.h include.
+	* elf_begin.c: Remove sys/param.h.
+	* elf_compress: Likewise. Add system.h include.
+	(MAX): Remove definition.
+
+2016-08-07  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_compress.c (__libelf_reset_rawdata): Check scn->flags and
+	free rawdata_base when malloced. Set ELF_F_MALLOCED for scn->flags.
+	* elf_end.c (elf_end): Check scn->flags and free rawdata_base if
+	malloced.
+	* libelfP.h (struct Elf_Scn): Document flags ELF_F_MALLOCED usage.
+
+2016-07-06  Mark Wielaard  <mjw@redhat.com>
+
+	* elf-knowledge.h (SH_FLAGS_COMBINE): Removed.
+	(SH_FLAGS_IMPORTANT): Likewise.
+
+2016-07-06  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatenull.c (updatenull_wrlock): Ignore e_type when
+	updating phdrs.
+	* elf_getphdrnum.c (__elf_getphdrnum_chk_rdlock): Only do sanity
+	checking if phdrs haven't been read in yet.
+
+2016-06-24  John Ogness  <john.ogness@linutronix.de>
+
+	* elf32_updatenull.c (updatenull_wrlock): Find first section.
+	* elf_nextscn.c (elf_nextscn): When scn is NULL start from 0th
+	section.
+
+2016-06-28  Richard Henderson  <rth@redhat.com>
+
+	* elf.h: Update from glibc.  Add lots of new EM_* definitions.
+
+2016-04-14  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_compress.c (__libelf_compress): Free out_buf if deflateInit
+	fails.
+
+2016-02-13  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatefile.c (updatemmap): Free scns when out of memory.
+
+2016-01-28  Mark Wielaard  <mjw@redhat.com>
+
+	* elf.h: Update from glibc. Add new i386 and x86_64 relocations.
+
+2016-02-12  Mark Wielaard  <mjw@redhat.com>
+
+	* elf.h: Update from glibc. Add NT_ARM_SYSTEM_CALL.
+
+2016-02-04  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getdata.c (__libelf_set_rawdata_wrlock): Don't adjust align
+	for SHT_NOBITS sections.
+
+2016-01-22  Chih-Hung Hsieh <chh@google.com>
+
+	* elf_compress.c (__libelf_compress): Move nested function
+	'do_deflate_cleanup' to file scope to compile with clang.
+	* elf_strptr.c (elf_strptr): Move nested function 'get_zdata'
+	to file scope to compile with clang.
+
+2016-01-13  Mark Wielaard  <mjw@redhat.com>
+
+	* libelf.h: Check SHF_COMPRESSED is defined. If not define it and the
+	associated ELF compression types/defines.
+
+2015-11-26  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_compress.c (__libelf_decompress_elf): New function, extracted
+	from...
+	(elf_compress): here. Check zdata_base use __libelf_decompress_elf.
+	* elf_strptr.c (elf_strptr): If SHF_COMPRESSED check, uncompress and
+	use zdata.
+	* libelfP.h (struct Elf_Scn): Add zdata_size and zdata_align.
+	(__libelf_decompress_elf): New internal function definition.
+
+2015-10-21  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libelf_a_SOURCES): Add elf_compress.c and
+	elf_compress_gnu.c.
+	* elf_compress.c: New file.
+	* elf_compress_gnu.c: Likewise.
+	* elf_begin.c (file_read_elf): Make a writable copy of the shdrs
+	for ELF_C_READ_MMAP.
+	* elf_end.c (elf_end): Free zdata_base.
+	* elf_error.c: Add ELF_E_ALREADY_COMPRESSED,
+	ELF_E_UNKNOWN_COMPRESSION_TYPE, ELF_E_COMPRESS_ERROR and
+	ELF_E_DECOMPRESS_ERROR.
+	* elf_data.c (__libelf_data_type): New internal function extracted
+	from convert_data.
+	(convert_data): Handle SHF_COMPRESSED.
+	* elf32_updatenull.c (updatenull_wrlock): Check sh_entsize against
+	uncompressed section data size if SHF_COMPRESSED.
+	* elf32_getshdr.c (load_shdr_wrlock): Adjust assert to account for
+	ELF_C_READ_MMAP.
+	* libelf.h: Define elf_compress and elf_compress_gnu.
+	* libelf.map (ELFUTILS_1.7): Add elf_compress and elf_compress_gnu.
+	* libelfP.h: Add ELF_E_ALREADY_COMPRESSED,
+	ELF_E_UNKNOWN_COMPRESSION_TYPE, ELF_E_COMPRESS_ERROR and
+	ELF_E_DECOMPRESS_ERROR. Define __libelf_data_type.
+	(__libelf_compress): New internal function definition.
+	(__libelf_decompress): Likewise.
+	(__libelf_reset_rawdata): Likewise.
+	(__libelf_data_type): Likewise.
+	(struct Elf_Scn): Add zdata_base.
+
+2015-11-19  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libelf_a_SOURCES): Add elf32_getchdr.c,
+	elf64_getchdr.c and gelf_getchdr.c.
+	(noinst_HEADERS): Add chdr_xlate.h.
+	* abstract.h: Define Chdr32 and Chdr64.
+	* chdr_xlate.h: New file.
+	* elf32_getchdr.c: New file.
+	* elf64_getchdr.c: New file.
+	* elf_error.c: Add ELF_E_NOT_COMPRESSED, ELF_E_INVALID_SECTION_TYPE
+	and ELF_E_INVALID_SECTION_FLAGS.
+	* elf_getdata.c (__libelf_set_rawdata_wrlock): Set d_type to
+	ELF_T_CHDR for SHF_COMPRESSED sections.
+	* exttypes.h: Add Chdr32 and Chdr64.
+	* gelf.h (GElf_Chdr): New typedef.
+	(gelf_getchdr): New function definition.
+	* gelf_fsize.c (__libelf_type_sizes): Add ELF_T_CHDR.
+	* gelf_getchdr.c: New file.
+	* gelf_xlate.c (__elf_xfctstom): Add ELF_T_CHDR cvt_chdr.
+	* gelf_xlate.h: Add Chdr.
+	* libelf.h (Elf_Type): Add ELF_T_CHDR.
+	(elf32_getchdr): New function definition.
+	(elf64_getchdr): Likewise.
+	* libelf.map (ELFUTILS_1.7): New sections add elf32_getchdr,
+	elf64_getchdr and gelf_getchdr.
+	* libelfP.h: Add ELF_E_NOT_COMPRESSED, ELF_E_INVALID_SECTION_TYPE
+	and ELF_E_INVALID_SECTION_FLAGS.
+
+2015-10-16  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libelf_so_LDLIBS): Add -lz.
+
+2015-10-14  Mark Wielaard  <mjw@redhat.com>
+
+	* elf.h: Update from glibc. Add section compression constants and
+	structures.
+
+2015-10-20  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* elf_begin.c (get_shnum): Elf64_Shdr.sh_size is an Elf64_Xword.
+	Fix the size argument to pread_retry.
+
+2015-10-13  Chih-Hung Hsieh  <chh@google.com>
+
+	* elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Move nested
+	function 'fill_mmap' to file scope.
+	* elf_begin.c (elf_begin): Move nested function 'lock_dup_elf'
+	to file scope.
+
+2015-10-09  Josh Stone  <jistone@redhat.com>
+
+	* libelf.h: Replace loff_t with int64_t throughout.
+
+2015-10-05  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_update.c (write_file): Only use posix_fallocate when using
+	mmap. Only report failure when errno is ENOSPC.
+
+2015-10-09  Josh Stone  <jistone@redhat.com>
+
+	* libelfP.h (struct Elf): Replace off64_t with off_t.
+	* elf_getdata_rawchunk.c (elf_getdata_rawchunk): Likewise.
+
+2015-10-05  Chih-Hung Hsieh <chh@google.com>
+
+	* elf_getarsym.c (elf_getarsym): Do not use
+	union of variable length arrays.
+
+2015-10-05  Josh Stone  <jistone@redhat.com>
+
+	* Makefile.am (libelf.so): Add AM_V_CCLD and AM_V_at silencers.
+
+2015-09-24  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid
+	relocation overflows in some platforms.
+
+2015-09-29  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatenull.c (default_ehdr): Set e_version when EV_NONE.
+	(updatenull_wrlock): Always set e_shentsize.
+
+2015-09-23  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_getehdr.c (getehdr_wrlock): Mark as internal_function.
+	* elf32_getshdr.c (getshdr_rdlock): Likewise.
+	(getshdr_wrlock): Likewise.
+	* elf_error.c (__libelf_seterrno): Likewise.
+	* elf_getphdrnum.c (__elf_getphdrnum_rdlock): Likewise.
+	(__elf_getphdrnum_chk_rdlock): Likewise.
+	* elf_getshdrnum.c (__elf_getphdrnum_rdlock): Likewise.
+	(__elf_getphdrnum_chk_rdlock): Likewise.
+	* elf_getshdrnum.c (__elf_getshdrnum_rdlock): Likewise.
+	* elf_readall.c (__libelf_readall): Likewise.
+	* gelf_getehdr.c (__gelf_getehdr_rdlock): Likewise.
+
+2015-09-22  Mark Wielaard  <mjw@redhat.com>
+
+	* *.c: Remove old-style function definitions.
+
+2015-06-22  Mark Wielaard  <mjw@redhat.com>
+
+	* dl-hash.h: Update from glibc.
+
+2015-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatefile.c (updatefile): Always free shdr_data and scns
+	when allocated on failure paths.
+
+2015-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* nlist.c (nlist): Check symscn shdr exists before use.
+
+2015-06-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_update.c (write_file): Always also use ftruncate before
+	posix_fallocate to make sure file has the right size.
+
+2015-06-04  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getdata.c (__libelf_type_aligns): Add entries for ELF_T_EHDR,
+	ELF_T_OFF, ELF_T_PHDR, ELF_T_SHDR, ELF_T_SWORD, ELF_T_XWORD,
+	ELF_T_SXWORD, ELF_T_GNUHASH, ELF_T_AUXV.
+	* elf_getdata_rawchunk.c (elf_getdata_rawchunk): Check alignment
+	of rawdata against requested type.
+
+2015-06-02  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getdata.c (convert_data): Make sure source data is properly
+	aligned for type before calling actual conversion function.
+
+2015-06-04  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (get_shnum): Check alignment of Shdr, not Ehdr before
+	direct access.
+
+2015-06-02  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (file_read_elf): Split checks for ehdr and shdr
+	alignment, drop phdr alignment check.
+
+2015-05-31  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_getshdr.c (load_shdr_wrlock): Allocate shdrs with malloc,
+	not alloca and free after conversion when a copy needs to be made.
+
+2015-05-31  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_getphdr.c (getphdr_wrlock): Allocate phdrs with malloc, not
+	alloca and free after conversion when a copy needs to be made.
+
+2015-05-31  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getarsym.c (elf_getarsym): Allocate temporary file_date with
+	malloc, not alloca also in !ALLOW_UNALIGNED case.
+
+2015-05-30  Mark Wielaard  <mjw@redhat.com>
+
+	* gelf_xlate.c (elf_cvt_Byte): Only call memmove with non-zero size.
+
+2015-05-30  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatefile.c (updatemmap): Only call mempcpy and update
+	last_position when d_size is non-zero.
+
+2015-05-17  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatefile.c (updatefile): Allocate shdr_data and scns
+	with malloc, not alloca. Free after writing section headers.
+
+2015-05-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatefile.c (updatemmap): Allocate temporary shdr storage
+	with malloc, not alloca. Free after writing section header.
+
+2015-05-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getarsym.c (elf_getarsym): Allocate temporary file_date with
+	malloc, not alloca. Call free after out.
+
+2015-05-14  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_update.c (write_file): Use posix_fallocate instead of
+	ftruncate to extend file if necessary.
+
+2015-05-13  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatenull.c (default_ehdr): If e_phnum is zero then set
+	e_phoff also to zero.
+
+2015-05-12  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatenull.c (updatenull_wrlock): Check that sh_addralign
+	is a powerof2.
+	* elf_getdata.c (__libelf_set_rawdata_wrlock): Clamp large d_aligns
+	to the elf image offset.
+
+2015-05-12  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_newphdr.c (newphdr): Call __libelf_seterrno with
+	ELF_E_INVALID_INDEX before failing. Check whether section zero shdr
+	actually exists if we need to put extended phnum in section zero.
+
+2015-05-08  Mark Wielaard  <mjw@redhat.com>
+
+	* nlist.c (nlist): Call gelf_fsize with EV_CURRENT.
+
+2015-01-03  Mark Wielaard  <mjw@redhat.com>
+
+	* version_xlate.h (elf_cvt_Verdef): Use memmove to copy src to dest.
+	(elf_cvt_Verneed): Likewise.
+
+2015-03-28  Mark Wielaard  <mjw@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2015-03-23  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatenull.c (updatenull_wrlock): Don't extend size with
+	SHT_NOBITS sh_offset.
+
+2015-02-18  Mark Wielaard  <mjw@redhat.com>
+
+	* libelfP.h (__libelf_set_data_list_rdlock): Make internal_function.
+
+2015-02-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* elf32_updatenull.c (__elfw2(LIBELFBITS,updatenull_wrlock)): Consider
+	sh_addralign 0 as 1.
+
+2015-01-22  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_strptr (elf_strptr): Make sure returned string is NUL
+	terminated.
+
+2015-01-21  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_strptr.c (elf_strptr): Check data_list_rear == NULL instead
+	of rawdata_base != NULL before using rawdata directly.
+
+2015-01-20  Mark Wielaard  <mjw@redhat.com>
+
+	* libelfP.h (__elf_strptr_internal): New function declaration.
+	* elf_getdata.c (__libelf_set_data_list_rdlock): New internal
+	function extracted from...
+	(__elf_getdata_rdlock): ... here.
+	* elf_newdata.c (elf_newdata): Check scn->rawdata_base and update
+	datalist if necessary.
+
+2015-01-20  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_strptr.c (elf_strptr): Call __elf[32|64]_getshdr_rdlock if
+	necessary.
+
+2014-12-30  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getphdrnum.c (__elf_getphdrnum_chk_rdlock): New function.
+	(elf_getphdrnum): Call __elf_getphdrnum_chk_rdlock.
+	* gelf_getphdr (gelf_getphdr): Call __elf_getphdrnum_chk_rdlock
+	and always check ndx against phnum.
+	* libelfP.h (__elf_getphdrnum_chk_rdlock): New internal function.
+
+2014-12-25  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (__libelf_next_arhdr_wrlock): ar_size cannot be
+	negative. Include start_offset in maxsize.
+
+2014-12-28  Alexander Cherepanov  <cherepan@mccme.ru>
+
+	* elf_begin.c (read_long_names): Don't miss '/' right after
+	another '/'. Fixes a dir traversal vuln in ar extraction.
+
+2014-12-18  Ulrich Drepper  <drepper@gmail.com>
+
+	* Makefile.am: Suppress output of textrel_check command.
+
+2014-12-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (read_long_names): Make sure long_names len fits
+	in mapped ELF file.
+
+2014-12-15  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getarsym.c (elf_getarsym): Check index_size doesn't overflow.
+
+2014-12-15  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (read_long_names): Clear any garbage left in the
+	name table.
+
+2014-12-11  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (file_read_elf): Correct ELF64 section offset check.
+
+2014-12-11  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (read_long_names): Check for offset overflow.
+	(__libelf_next_arhdr_wrlock): Likewise. Sanity check the ar_size.
+	Don't allow it to go beyond end of file.
+
+2014-12-09  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getarsym.c (elf_getarsym): Make sure n * w doesn't overflow.
+
+2014-11-27  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libelf.so): Use textrel_check.
+
+2014-11-23  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getdata_rawchunk.c (elf_getdata_rawchunk): Change signed
+	overflow check to unsigned.
+
+2014-11-23  Mark Wielaard  <mjw@redhat.com>
+
+	* note_xlate.h (elf_cvt_note): Copy over any leftover data if
+	src != dest. The data is probably part of truncated name/desc.
+
+2014-11-22  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getphdrnum.c (elf_getphdrnum): Sanity check the
+	__elf_getphdrnum_rdlock result.
+
+2014-11-18  Mark Wielaard  <mjw@redhat.com>
+
+	* version_xlate.h (elf_cvt_Verdef): Check for overflow.
+	(elf_cvt_Verneed): Likewise.
+
+2014-11-17  Mark Wielaard  <mjw@redhat.com>
+
+	* elf-knowledge.h (SECTION_STRIP_P): Check name is not NULL.
+
+2014-11-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getshdrstrndx.c: Check there are section headers before
+	handling SHN_XINDEX.
+
+2014-11-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_getphdr.c (getphdr_wrlock): Check e_phoff isn't zero.
+	Check for too many pheaders.
+	* elf_getphdrnum.c (__elf_getphdrnum_rdlock): Check section zero
+	actually exists before handling PN_XNUM.
+
+2014-11-16  Mark Wielaard  <mjw@redhat.com>
+
+	* gelf_getnote.c (gelf_getnote): Check padding overflow.
+
+2014-11-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getdata.c (__libelf_set_rawdata_wrlock): Declare offset, size
+	and align as Elf64_Off and Elf64_Xword not size_t.
+
+2014-11-14  Mark Wielaard  <mjw@redhat.com>
+
+	* gelf_getnote.c (gelf_getnote): Check offset overflow.
+
+2014-11-13  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getdata.c (__libelf_set_rawdata_wrlock): Fix unsigned overflow
+	check.
+
+2014-11-08  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (__libelf_next_arhdr_wrlock): Use mempcpy not __mempcpy.
+
+2014-11-07  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (file_read_elf): Correct sh_size check.
+	* elf_getdata.c (__libelf_set_rawdata_wrlock): Check for unsigned
+	overflow.
+
+2014-09-10  Petr Machata  <pmachata@redhat.com>
+
+	* elf_begin (read_unmmaped_file): Call __libelf_seterrno if the
+	file is unreadable.
+
+2014-07-07  Mark Wielaard  <mjw@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2014-04-13  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Remove !MUDFLAP conditions.
+	* elf_begin.c (read_file): Don't clear use_mmap when _MUDFLAP is
+	defined.
+	* elf_update.c (write_file): Remove _MUDFLAP condition.
+
+2014-01-17  Jakub Jelinek  <jakub@redhat.com>
+	    Roland McGrath  <roland@redhat.com>
+
+	* libelfP.h (INVALID_NDX): Define.
+	* gelf_getdyn.c (gelf_getdyn): Use it.  Remove ndx < 0 test if any.
+	* gelf_getlib.c (gelf_getlib): Likewise.
+	* gelf_getmove.c (gelf_getmove): Likewise.
+	* gelf_getrel.c (gelf_getrel): Likewise.
+	* gelf_getrela.c (gelf_getrela): Likewise.
+	* gelf_getsym.c (gelf_getsym): Likewise.
+	* gelf_getsyminfo.c (gelf_getsyminfo): Likewise.
+	* gelf_getsymshndx.c (gelf_getsymshndx): Likewise.
+	* gelf_getversym.c (gelf_getversym): Likewise.
+	* gelf_update_dyn.c (gelf_update_dyn): Likewise.
+	* gelf_update_lib.c (gelf_update_lib): Likewise.
+	* gelf_update_move.c (gelf_update_move): Likewise.
+	* gelf_update_rel.c (gelf_update_rel): Likewise.
+	* gelf_update_rela.c (gelf_update_rela): Likewise.
+	* gelf_update_sym.c (gelf_update_sym): Likewise.
+	* gelf_update_syminfo.c (gelf_update_syminfo): Likewise.
+	* gelf_update_symshndx.c (gelf_update_symshndx): Likewise.
+	* gelf_update_versym.c (gelf_update_versym): Likewise.
+
+2014-01-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* elf32_getphdr.c (elfw2(LIBELFBITS,getphdr)): Check if program header
+	table fits into object's bounds.
+	* elf_getshdrstrndx.c (elf_getshstrndx): Add elf->start_offset to
+	elf->map_address.  Check if first section header fits into object's
+	bounds.
+	* elf32_getshdr.c (elfw2(LIBELFBITS,getshdr)):
+	Check if section header table fits into object's bounds.
+	* elf_begin.c (get_shnum): Ensure section headers fits into
+	object's bounds.
+	(file_read_elf): Make sure scncnt is small enough to allocate both
+	ElfXX_Shdr and Elf_Scn array.  Make sure section and program header
+	tables fit into object's bounds.  Avoid memory leak on failure.
+	* elf_newscn.c (elf_newscn): Check for overflow.
+	* elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Likewise.
+	(__elfw2(LIBELFBITS,updatefile)): Likewise.
+	* elf32_newphdr.c (elfw2(LIBELFBITS,newphdr)): Likewise.
+	* elf_getarsym.c (elf_getarsym): Likewise.
+
+2013-11-08  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatefile.c (elfXX_updatemmap): Only memcpy ehdr when not
+	already directly mmapped.
+
+2013-11-05  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatefile.c (elfXX_updatefile): Copy all section headers
+	if elf->flags dirty.
+
+2013-11-01  Michael Forney  <mforney@mforney.org>
+
+	* Makefile.am: Use READELF.
+
+2013-10-01  Petr Machata  <pmachata@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2013-06-17  Petr Machata  <pmachata@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2013-08-28  Namhyung Kim  <namhyung@gmail.com>
+
+	* gelf.h (gelf_fsize): Fix typo in comment.
+
+2013-08-28  Mark Wielaard  <mjw@redhat.com>
+
+	* gelf_getauxv.c (gelf_getauxv): Add missing whitespace.
+
+2013-08-27  Mark Wielaard  <mjw@redhat.com>
+
+	* gelf_getauxv.c (gelf_getauxv): Remove unnecessary casts to char *.
+
+2013-08-25  Kurt Roeckx  <kurt@roeckx.be>
+
+	* gelf_getauxv.c (gelf_getauxv): Use memcpy instead of pointer
+	dereference to avoid alignment problems.
+
+2013-01-07  Roland McGrath  <roland@hack.frob.com>
+
+	* elf_getarsym.c (elf_getarsym): Copy FILE_DATA into stack space if it
+	would be unaligned and !ALLOW_UNALIGNED.
+
+	* elf_getarsym.c (read_number_entries): Use memcpy instead of pointer
+	dereference so as not to assume the field is naturally aligned.
+
+2012-09-17  Petr Machata  <pmachata@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2012-08-16  Roland McGrath  <roland@hack.frob.com>
+
+	* elf.h: Update from glibc.
+
+2012-08-14  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_checksum.c (ebl_debugscn_p): Removed unused define and
+	confusing outdated comment.
+
+2012-08-01  Petr Machata  <pmachata@redhat.com>
+
+	* elf_getarsym (read_number_entries): New function.
+	(elf_getarsym): Handle 64-bit symbol table, stored in special
+	entry named "/SYM64/".
+	* elf_begin.c (__libelf_next_arhdr_wrlock): Don't reject archive
+	because it contains 64-bit symbol table.
+
+2012-07-19  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_getshdr.c (load_shdr_wrlock): Add elf->flags & ELF_F_MALLOCED
+	to asserts.
+
+2012-07-17  Petr Machata  <pmachata@redhat.com>
+
+	* elf32_xlatetom.c (elfw2(LIBELFBITS, xlatetom)): Do not check for
+	integer number of records in case of ELF_T_NHDR.
+
+2012-04-02  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_offscn.c: Do not match SHT_NOBITS sections at OFFSET unless
+	there are no nonempty sections at that offset.
+
+2012-03-21  Roland McGrath  <roland@hack.frob.com>
+
+	* elf-knowledge.h (SECTION_STRIP_P): Remove < SHT_NUM check.
+
+2011-02-26  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_end.c (elf_end): Call rwlock_unlock before rwlock_fini.
+
+2011-01-05  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* elf_getdata_rawchunk.c (elf_getdata_rawchunk): Fix off64_t overflow
+	when MAXIMUM_SIZE == ~0.
+
+2010-08-18  Roland McGrath  <roland@redhat.com>
+
+	* gelf_fsize.c (__libelf_type_sizes): Add entries for ELF_T_LIB
+	and ELF_T_GNUHASH.
+	Reported by Mark Hatle <mark.hatle@windriver.com>.
+
+	* exttypes.h: Add cases for ElfNN_Lib.
+	Reported by Mark Hatle <mark.hatle@windriver.com>.
+
+2010-06-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* gelf_update_shdr.c: Implicitly set ELF_F_DIRTY bit.
+	* gelf_update_phdr.c: Likewise.
+	* gelf_update_ehdr.c: Likewise.
+
+2010-04-14  Roland McGrath  <roland@redhat.com>
+
+	* elf32_getphdr.c: Check for e_phoff/size outside the file bounds.
+	* elf_begin.c (file_read_elf): Don't set .phdr here.
+
+2010-04-13  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2010-04-06  Roland McGrath  <roland@redhat.com>
+
+	* elf_error.c (ELF_E_FD_MISMATCH_IDX): Avoid nonobvious abbreviation
+	in error message.
+
+2010-04-01  Petr Machata  <pmachata@redhat.com>
+
+	* elf_getdata.c (__elf_getdata_rdlock): Initialize data.s for data
+	that do not need a conversion.
+
+2010-03-11  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2010-03-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2010-02-17  Roland McGrath  <roland@redhat.com>
+
+	* elf_begin.c (file_read_elf): Leave section rawdata_base and
+	data_base pointers null when [sh_offset,sh_size) points outside
+	the mapped file.
+
+2010-02-15  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am: Use config/eu.am for common stuff.
+
+2010-01-07  Roland McGrath  <roland@redhat.com>
+
+	* elf32_getphdr.c: Use __elf_getphdrnum_rdlock.
+	* gelf_getphdr.c: Likewise.
+	* gelf_update_phdr.c: Likewise.
+	* elf32_updatefile.c (__elf32_updatemmap, __elf32_updatefile): Likewise.
+	* elf32_updatenull.c (__elf32_updatenull_wrlock): Likewise.
+	* elf32_newphdr.c: Clear section 0's sh_info when resetting e_phnum.
+	If COUNT is too large, use store PN_XNUM instead and set sh_info.
+	* elf_begin.c (file_read_elf): Always allocate space we can use later
+	for section 0 if doing RDWR.
+
+	* elf_getphdrnum.c: New file.
+	* Makefile.am (libelf_a_SOURCES): Add it.
+	* libelf.h: Declare elf_getphdrnum.
+	* libelfP.h: Declare __elf_getphdrnum_rdlock.
+	* libelf.map (ELFUTILS_1.6): New set, add elf_getphdrnum.
+
+	* elf.h: Update from glibc.
+
+2009-10-23  Lubomir Rintel  <lkundrak@v3.sk>
+
+	* elf32_updatefile.c (fill_mmap): When starting past shdr_end, start
+	filling from section start, not shdr_end.
+
+2009-11-10  Roland McGrath  <roland@redhat.com>
+
+	* elf_readall.c (__libelf_readall): Fetch file size if not yet known.
+
+2009-11-06  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_next.c (elf_next): Mark the archive header as unusable when
+	there is no next ar element.
+
+2009-08-12  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libelf.so): Use -Wl,-z,defs not -defs.
+
+2009-07-26  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2009-07-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c (__elfXX_updatemmap): Fix handling of gaps between
+	sections.  Patch by Lubomir Rintel <lkundrak@v3.sk>.
+
+2009-07-08  Roland McGrath  <roland@redhat.com>
+
+	* libelfP.h (struct Elf): Remove unused ar.has_index field.
+	Reorder various members for optimal packing.
+
+2009-07-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2009-06-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (libelf_a_SOURCES): Replace elf_getshnum.c and
+	elf_getshstrndx.c with elf_getshdrnum.c and elf_getshdrstrndx.c.
+	* elf_getshnum.c: Renamed to...
+	* elf_getshdrnum.c: ...this.  Rename function and add old name as
+	alias.  Likewise for internal functions with derived names.
+	* elf_getshstrndx.c: Renamed to...
+	* elf_getshdrstrndx.c: ...this.  Rename function and add old name as
+	alias.  Likewise for internal functions with derived names.
+	* libelf.h: Add prototypes for new names.  Make old names as
+	deprecated.
+	* libelfP.h: Rename internal function prototypes.
+	* libelf.map: Export for names.
+	* elf32_checksum.c: Don't use deprecated functions.
+	* elf32_getshdr.c: Likewise.
+
+2009-06-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2009-04-14  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2009-04-01  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2009-02-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c (updatefile): For the zeroth section we still
+	have to copy the section header.
+
+2009-02-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_strptr.c: Add comment re possible problem.
+
+2009-01-26  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatenull.c (updatenull_wrlock): Fix comment of
+	ELF_F_LAYOUT behaviour re section header table.
+
+2009-01-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c (__elfXX_updatemmap): Fill the gap between
+	sections even if only the section at the start of the gap has been
+	changed.
+	(__elfXX_updatefile): Likewise.
+
+2009-01-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c (__elfXX_updatemmap): Skip most of the loop to
+	handle sections for NOBITS sections.
+	(elfXX_updatefile): Likewise.
+
+	* elf32_updatefile.c (__elfXX_updatemmap): When skipping non-NOBITS
+	sections we haven't loaded, update last_position based on scn_start,
+	not based on old value.  Don't run the loop for the dummy section 0.
+	(elfXX_updatefile): Don't run the loop for the dummy section 0.
+
+2009-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* libelfP.h (_): We only have one translation domain, elfutils.
+
+	* Makefile.am: Use USE_LOCKS instead of USE_TLS.
+	* elf_error.c: Always use __thread.  Remove all !USE_TLS code.
+
+2009-01-04  Roland McGrath  <roland@redhat.com>
+
+	* note_xlate.h (elf_cvt_note): Don't examine a size too small to
+	container a note header.
+
+2008-12-11  Roland McGrath  <roland@redhat.com>
+
+	* elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Handle
+	placement offset going backwards, for out-of-order or overlapping
+	(bogus) sh_offset layouts.  It's a dumb use, but should not crash.
+	(__elfw2(LIBELFBITS,updatefile)): Likewise.
+	Fixes RHBZ#476136.
+
+	* libelf.h (Elf_Data): Whitespace fix.
+
+2008-12-10  Roland McGrath  <roland@redhat.com>
+
+	* elf_getarhdr.c (elf_getarhdr): Fix missing rename in last change.
+
+2008-10-22  Petr Machata  <pmachata@redhat.com>
+
+	* elf_rawfile.c (elf_rawfile): Lock around elf-> references.
+
+2008-10-21  Petr Machata  <pmachata@redhat.com>
+
+	* libelfP.h: Rename getehdr_rdlock to getehdr_wrlock.
+	* elf32_getehdr.c (getehdr_rdlock): Move the code to new function
+	getehdr_impl and make it a wrapper.  Rename to getehdr_wrlock.
+	(getehdr_impl): Guard elf->class init with wrlock.
+	(getehdr): Also make it a wrapper of getehdr_impl.
+	* elf32_updatenull.c (updatenull_wrlock): Call getehdr_wrlock.
+
+2008-10-20  Petr Machata  <pmachata@redhat.com>
+
+	* elf_getdata_rawchunk.c (elf_getdata_rawchunk): Lock around the
+	code that reads mutable elf state.  Relock to write lock to chain
+	the new chunk on the elf rawchunks list.
+
+2008-10-20  Petr Machata  <pmachata@redhat.com>
+
+	* elf32_checksum.c (checksum): Place a lock around the code that
+	processes data.  Make it wrlock if the code needs to xlate the
+	data before processing.
+
+2008-10-16  Petr Machata  <pmachata@redhat.com>
+
+	* elf_begin.c
+	(__libelf_next_arhdr): Rename to __libelf_next_arhdr_wrlock.
+	(dup_elf): Adjust the call.
+	(elf_begin): New local function lock_dup_elf.  Relocks the elf if
+	necessary before calling dup.  Call this instead of dup_elf.
+	* elf_getarhdr.c
+	(elf_getarhdr): Lock before calling __libelf_next_arhdr_wrlock.
+	* elf_next.c (elf_next): Likewise.
+	* elf_rand.c (elf_rand): Likewise.
+
+2008-10-14  Petr Machata  <pmachata@redhat.com>
+
+	* elf_getdata.c (__elf_getdata_rdlock): Lock before converting.
+
+2008-11-26  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2008-10-06  Roland McGrath  <roland@redhat.com>
+
+	* elf_getarhdr.c (elf_getarhdr): Return NULL when passed NULL.
+
+2008-08-27  Roland McGrath  <roland@redhat.com>
+
+	* elf_begin.c (get_shnum): Avoid misaligned reads for matching endian.
+
+	* libelfP.h [!ALLOW_UNALIGNED] (__libelf_type_align): Fix CLASS index.
+
+2008-08-25  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (libelf_so_LDLIBS): New variable.
+	(libelf.so): Use it in the link.
+
+2008-08-21  Petr Machata  <pmachata@redhat.com>
+
+	* elf_getdata.c, libelfP.h
+	(__elf_getdata_internal): Rename to __elf_getdata_rdlock.
+	(__libelf_set_rawdata_wrlock): New function.
+	(__libelf_set_rawdata): Make it a wrapper that calls *_wrlock.
+	* elf32_updatenull.c, libelfP.h
+	(__elfNN_updatenull): Rename to __elfNN_updatenull_wrlock.
+
+2008-08-21  Petr Machata  <pmachata@redhat.com>
+
+	* elf32_getphdr.c, libelfP.h
+	(__elfNN_getphdr_internal): Drop.  Move __elfNN_getphdr_internal
+	code to __elfNN_getphdr_wrlock.
+	(__elfNN_getphdr_rdlock, __elfNN_getphdr_wrlock): New functions.
+	(__elfNN_getphdr_rdlock, __elfNN_getphdr_wrlock): Make these
+	wrappers of getphdr_impl.
+
+2008-08-21  Petr Machata  <pmachata@redhat.com>
+
+	* elf32_getehdr.c, libelfP.h
+	(__elfNN_getehdr_internal): Rename to __elfNN_getehdr_rdlock.
+	* gelf_getehdr, libelfP.h:
+	(__gelf_getehdr_internal): Rename to __gelf_getehdr_rdlock.
+
+2008-08-21  Petr Machata  <pmachata@redhat.com>
+
+	* elf32_getshdr.c
+	(__elfNN_getshdr_internal): Drop.
+	(load_shdr_wrlock, scn_valid): New functions, contain bits of
+	behaviour from __elfNN_getshdr_internal.
+	(__elfNN_getshdr_rdlock, __elfNN_getshdr_wrlock): Replacements for
+	dropped _internal functions above.
+	* elf_getshnum.c
+	(__elf_getshnum_internal): Rename to __elf_getshnum_rdlock.
+
+2008-08-04  Petr Machata  <pmachata@redhat.com>
+
+	* libelfP.h (RWLOCK_RDLOCK, RWLOCK_WRLOCK, RWLOCK_UNLOCK): New macros.
+
+2008-07-28  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2008-03-31  Roland McGrath  <roland@redhat.com>
+
+	* elf32_offscn.c: Make sure shdrs have been read in.
+
+2008-02-19  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2008-02-08  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2008-01-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_strptr.c (elf_strptr): Don't fail if the ELF file is currently
+	under construction and no raw data can be read from disk.
+
+2008-01-30  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2008-01-26  Roland McGrath  <roland@redhat.com>
+
+	* elf_begin.c (__libelf_next_arhdr): Rewrite conversions using a macro.
+	Fixes various pastos in wrong type in sizeof, wrong string parsed.
+
+2008-01-20  Roland McGrath  <roland@redhat.com>
+
+	* elf_getaroff.c: Calculate from start_offset, instead of using
+	parent's state.ar.offset field.
+
+2008-01-08  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (euinclude): Variable removed.
+	(pkginclude_HEADERS): Set this instead of euinclude_HEADERS.
+
+2008-01-03  Roland McGrath  <roland@redhat.com>
+
+	* common.h: Add __attribute__ ((unused)) to static functions.
+
+2007-12-20  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (libelf_a_SOURCES): Add elf_scnshndx.
+	* libelfP.h (struct Elf_Scn): Add shndx_index field.
+	Declare __elf_scnshndx_internal.
+	* elf32_getshdr.c: Record location of extended section header.
+	* elf_begin.c (file_read_elf): Likewise.
+	* elf_scnshndx.c: New file.
+	* libelf.h: Declare elf_scnshndx.
+	* libelf.map: Add elf_scnshndx to version ELFUTILS_1.4.
+
+2007-11-12  Roland McGrath  <roland@redhat.com>
+
+	* libelf.h: Replace off64_t with loff_t throughout.
+	Only that type name is unconditionally defined by <sys/types.h>
+
+2007-11-03  Roland McGrath  <roland@redhat.com>
+
+	* libelf.h (Elf_Data): Comment fix.
+
+2007-10-18  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2007-10-07  Roland McGrath  <roland@redhat.com>
+
+	* elf_begin.c (__libelf_next_arhdr): Fix fencepost error and wrong
+	member access in terminating name with no trailing /.  Trim trailing
+	spaces when there is no /.
+
+2007-10-04  Roland McGrath  <roland@redhat.com>
+
+	* elf_end.c (elf_end): Don't free ELF->state.ar.ar_sym when it's -1l.
+
+2007-10-03  Roland McGrath  <roland@redhat.com>
+
+	* libelf.h (Elf_Data): Use off64_t for d_off.
+	(Elf_Arhdr): Use off64_t for ar_size.
+	(elf_update, elf_getbase, elf_getaroff): Return off64_t.
+
+	* gelf_rawchunk.c: File removed.
+	* gelf_freechunk.c: File removed.
+	* Makefile.am (libelf_a_SOURCES): Remove them.
+	* libelf.map (ELFUTILS_1.0): Remove exports.
+	* gelf.h: Remove decls.
+
+	* elf_getdata_rawchunk.c: New file.
+	* Makefile.am (libelf_a_SOURCES): Add it.
+	* libelf.map (ELFUTILS_1.3): Add elf_getdata_rawchunk.
+	* libelf.h: Declare it.
+	* libelfP.h (Elf_Data_Chunk): New type.
+	(struct Elf.elf): New member `rawchunks'.
+	* elf_end.c (elf_end): Free recorded rawchunk buffers.
+
+2007-08-24  Roland McGrath  <roland@redhat.com>
+
+	* gelf_getnote.c: New file.
+	* Makefile.am (libelf_a_SOURCES): Add it.
+	* gelf.h: Declare gelf_getnote.
+	* libelf.map (ELFUTILS_1.3): Add gelf_getnote.
+
+	* libelfP.h (NOTE_ALIGN): New macro.
+	* note_xlate.h: New file.
+	* Makefile.am (noinst_HEADERS): Add it.
+	* gelf_xlate.c: Include it.
+	(__elf_xfctstom): Use elf_cvt_note.
+	* elf_getdata.c (shtype_map, __libelf_type_align): Handle SHT_NOTE.
+	(__libelf_set_rawdata): Likewise.
+
+2007-08-19  Roland McGrath  <roland@redhat.com>
+
+	* gelf_update_auxv.c: New file.
+	* gelf_getauxv.c: New file.
+	* Makefile.am (libelf_a_SOURCES): Add them.
+	* gelf.h: Declare gelf_getauxv, gelf_update_auxv.
+	* libelf.map (ELFUTILS_1.3): New set, inherits fom ELFUTILS_1.2.
+	Export gelf_getauxv, gelf_update_auxv.
+
+	* libelf.h (Elf_Type): Add ELF_T_AUXV.
+	* abstract.h: Add auxv_t entries.
+	* exttypes.h: Likewise.
+	* gelf_xlate.h: Likewise.
+	* gelf_xlate.c (__elf_xfctstom): Add ELF_T_AUXV entries.
+	* gelf_fsize.c (__libelf_type_sizes): Likewise.
+
+2007-08-12  Roland McGrath  <roland@redhat.com>
+
+	* elf32_updatefile.c (compare_sections): Sort secondarily on sh_size,
+	and only tertiarily on index.
+
+2007-07-09  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2007-04-22  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2007-03-18  Roland McGrath  <roland@redhat.com>
+
+	* elf_begin.c (get_shnum): Fix test for e_shoff being out of bounds.
+	Return zero when the section headers do not fit within MAXSIZE.
+
+2007-03-09  Roland McGrath  <roland@redhat.com>
+
+	* libelfP.h (LIBELF_EV_IDX): New macro.
+	(__libelf_type_align): New macro.
+	[! ALLOW_UNALIGNED]: Declare __libc_type_aligns array.
+	* elf_getdata.c (shtype_map): Convert to just Elf_Type[][].
+	(convert_data, __libelf_set_rawdata): Use that, __libelf_type_align,
+	and __libelf_type_sizes, in place of old table.
+	(__libc_type_aligns): New const variable.
+
+2007-02-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile (libelf.so): Build with -z relro.
+
+	* elf_begin.c (read_file): When using ELF_C_READ_MMAP use MAP_PRIVATE.
+
+2007-01-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* nlist.c: Close file descriptor before returning.
+
+2007-01-20  Roland McGrath  <roland@redhat.com>
+
+	* gnuhash_xlate.h (elf_cvt_gnuhash): Fix fence-post error so we
+	convert the final word.
+
+	* elf32_getshdr.c: Don't byteswap shdr fields when EI_DATA matches
+	MY_ELFDATA on !ALLOW_UNALIGNED machines.
+
+2007-01-18  Roland McGrath  <roland@redhat.com>
+
+	* gelf_rawchunk.c (gelf_rawchunk): Clear RESULT pointer after freeing
+	it on read error.
+
+2006-10-13  Roland McGrath  <roland@redhat.com>
+
+	* elf32_updatenull.c: Look for and accept phdr also for ET_CORE.
+	* elf_error.c (msgstr): Change ELF_E_INVALID_PHDR string.
+
+2006-08-29  Roland McGrath  <roland@redhat.com>
+
+	* elf32_getphdr.c: Don't byteswap phdr fields when EI_DATA matches
+	MY_ELFDATA on !ALLOW_UNALIGNED machines.
+	Reported by Christian Aichinger <Greek0@gmx.net>.
+
+	* Makefile.am (CLEANFILES): Add libelf.so.$(VERSION).
+
+2006-08-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h (DT_VALNUM): Update.
+	(DT_ADDRNUM): Likewise.
+
+2006-07-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c: Adjust for internal_function_def removal.
+	* elf32_updatenull.c: Likewise.
+	* elf_begin.c: Likewise.
+	* elf_getdata.c: Likewise.
+
+2006-07-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* libelf.h: Define ELF_T_GNUHASH.
+	* elf_getdata.c (TYPEIDX): Handle SHT_GNU_HASH.
+	(shtype_map): Add SHT_GNU_HASH entries.
+	* gelf_xlate.c (__elf_xfctstom): Add ELF_T_GNUHASH entries.
+	* gnuhash_xlate.h: New file.
+	* Makefile.am (noinst_HEADERS): Add gnuhash_xlate.h.
+
+2006-07-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_gnu_hash.c: New file.
+	* libelf.h: Declare elf_gnu_hash.
+	* Makefile.am (libelf_a_SOURCES): Add elf_gnu_hash.
+	* libelf.map: Add elf_gnu_map for version ELFUTILS_1.2.
+
+2006-06-15  Roland McGrath  <roland@redhat.com>
+
+	* libelf.h (elf_getarsym): Fix comment typo.
+	Rename second parameter to be more explanatory.
+	(elf_getident, elf_rawhide): Likewise.
+
+2006-05-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c (updatemmap): Preserve section content if
+	copying would overwrite them.
+	Fix msync paramters.
+
+2006-04-04  Roland McGrath  <roland@redhat.com>
+
+	* elf32_updatefile.c (updatemmap): Handle other-endian case.
+
+2006-04-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c (updatemmap): Cleanups.  Remove shdr_dest
+	variable.  Before writing sections, make a copy of the section
+	header data if necessary.  Don't write section header while
+	writing the section constent, it might overwrite some sections.
+	Restore the pointer afterwards.
+	* elf32_updatenull.c (updatenull): If the offset of a section in a
+	file changed make sure we read the section so that it'll be written
+	out.
+
+	* elf_update.c: Remove debug message.
+
+2005-12-07  Roland McGrath  <roland@redhat.com>
+
+	* gelf_xlate.c [! ALLOW_UNALIGNED] (union unaligned): New type.
+	(FETCH, STORE): New macros.
+	(INLINE3): Use those to do alignment-friendly conversion.
+
+	* elf32_getshdr.c: Include map_address and start_offset in alignment
+	calculations.
+	* elf32_getphdr.c: Likewise.
+
+2005-11-19  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2005-11-17  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2005-11-10  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2005-09-09  Roland McGrath  <roland@redhat.com>
+
+	* elf_update.c (write_file): Stat the file and fchmod it after update
+	if its mode had S_ISUID or S_ISGID bits set.
+
+2005-08-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_getphdr.c: Include <system.h>.  Use pread_retry instead of
+	pread.  And branch prediction where useful.
+	* elf_begin.c: Likewise.
+	* elf_getdata.c: Likewise.
+	* elf_getshstrndx.c: Likewise.
+	* elf_readall.c: Likewise.
+	* gelf_rawchunk.c: Likewise.
+	* elf32_updatefile.c: Include <system.h>.  Use pread_retry instead of
+	pread.  And branch prediction where useful.
+	* elf_getarsym.c: Don't define pread_retry here.
+
+	* Makefile.am: Use $(LINK) not $(CC) when creating DSO.
+	(%.os): Use COMPILE.os.
+	(COMPILE.os): Filter out gconv options.
+
+2005-08-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_begin.c (file_read_elf): Avoid reading ELF header from file
+	again.  Instead accept additional parameter which points to it if we
+	don't use mmap.
+	(get_shnum): Use passed in e_ident value as source of ELF header.
+
+2005-08-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_begin.c (__libelf_next_arhdr): Use TEMP_FAILURE_RETRY.
+
+	* Makefile (libelf_a_SOURCES): Add elf_getaroff.c.
+	* libelf.map: Export elf_getaroff.
+	* libelf.h: Declare elf_getaroff.
+	* elf_getaroff.c: New file.
+
+2005-08-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_begin.c (get_shnum): Optimize memory handling.  Always read from
+	mapped file if available.  Fix access to 64-bit sh_size.  Recognize
+	overflow.
+	(file_read_elf): Likewise.
+
+2005-08-12  Roland McGrath  <roland@redhat.com>
+
+	* elf32_offscn.c: Do not match empty sections at OFFSET unless
+	there are no nonempty sections at that offset.
+
+2005-08-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2005-08-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (AM_CFLAGS): Add -fpic when BUILD_STATIC.
+
+2005-08-03  Ulrich Drepper  <drepper@redhat.com>
+
+	* libelf.map: Move elf32_offscn, elf64_offscn, and gelf_offscn in
+	new version ELFUTILS_1.1.1.
+
+2005-08-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_error.c: Add handling of ELF_E_INVALID_OFFSET.
+	* elf32_offscn.c: New file.
+	* elf64_offscn.c: New file.
+	* gelf_offscn.c: New file.
+	* Makefile.am (libelf_a_SOURCES): Add elf32_offscn.c, elf64_offscn.c,
+	and gelf_offscn.c.
+	* libelf.sym: Export new symbols.
+
+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..ddaeaa2
--- /dev/null
+++ b/libelf/Makefile.am
@@ -0,0 +1,131 @@
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 1996-2010, 2015 Red Hat, Inc.
+## This file is part of elfutils.
+##
+## This file is free software; you can redistribute it and/or modify
+## it under the terms of either
+##
+##   * the GNU Lesser General Public License as published by the Free
+##     Software Foundation; either version 3 of the License, or (at
+##     your option) any later version
+##
+## or
+##
+##   * the GNU General Public License as published by the Free
+##     Software Foundation; either version 2 of the License, or (at
+##     your option) any later version
+##
+## or both in parallel, as here.
+##
+## elfutils 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 copies of the GNU General Public License and
+## the GNU Lesser General Public License along with this program.  If
+## not, see <http://www.gnu.org/licenses/>.
+##
+include $(top_srcdir)/config/eu.am
+if BUILD_STATIC
+AM_CFLAGS += $(fpic_CFLAGS)
+endif
+GCC_INCLUDE = -I$(shell $(CC) -print-file-name=include)
+VERSION = 1
+
+lib_LIBRARIES = libelf.a
+noinst_LIBRARIES = libelf_pic.a
+noinst_PROGRAMS = $(noinst_LIBRARIES:_pic.a=.so)
+include_HEADERS = libelf.h gelf.h nlist.h
+
+pkginclude_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_getdata_rawchunk.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_getauxv.c gelf_update_auxv.c \
+		   gelf_getnote.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_getphdrnum.c elf_getshdrnum.c elf_getshdrstrndx.c \
+		   gelf_checksum.c elf32_checksum.c elf64_checksum.c \
+		   libelf_crc32.c libelf_next_prime.c \
+		   elf_clone.c \
+		   gelf_getlib.c gelf_update_lib.c \
+		   elf32_offscn.c elf64_offscn.c gelf_offscn.c \
+		   elf_getaroff.c \
+		   elf_gnu_hash.c \
+		   elf_scnshndx.c \
+		   elf32_getchdr.c elf64_getchdr.c gelf_getchdr.c \
+		   elf_compress.c elf_compress_gnu.c
+
+libelf_pic_a_SOURCES =
+am_libelf_pic_a_OBJECTS = $(libelf_a_SOURCES:.c=.os)
+
+libelf_so_DEPS = ../lib/libeu.a
+libelf_so_LDLIBS = $(libelf_so_DEPS) -lz
+if USE_LOCKS
+libelf_so_LDLIBS += -lpthread
+endif
+
+libelf_so_LIBS = libelf_pic.a
+libelf_so_SOURCES =
+libelf.so$(EXEEXT): $(srcdir)/libelf.map $(libelf_so_LIBS) $(libelf_so_DEPS)
+	$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
+		-Wl,--soname,$@.$(VERSION) \
+		-Wl,--version-script,$<,--no-undefined \
+		-Wl,--whole-archive $(libelf_so_LIBS) -Wl,--no-whole-archive \
+		$(libelf_so_LDLIBS)
+	@$(textrel_check)
+	$(AM_V_at)ln -fs $@ $@.$(VERSION)
+
+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
+
+noinst_HEADERS = elf.h abstract.h common.h exttypes.h gelf_xlate.h libelfP.h \
+		 version_xlate.h gnuhash_xlate.h note_xlate.h dl-hash.h \
+		 chdr_xlate.h
+EXTRA_DIST = libelf.map
+
+CLEANFILES += $(am_libelf_pic_a_OBJECTS) libelf.so.$(VERSION)
diff --git a/libelf/abstract.h b/libelf/abstract.h
new file mode 100644
index 0000000..d4515f2
--- /dev/null
+++ b/libelf/abstract.h
@@ -0,0 +1,330 @@
+/* Abstract description of component ELF types.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2007, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/* 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)
+
+#define auxv_t32(Ext) \
+START (32, auxv_t, Ext##auxv_t)						      \
+  TYPE_NAME (ElfW2(32, Ext##Word), a_type)				      \
+  TYPE_EXTRA (union {)							      \
+  TYPE_EXTRA (ElfW2(32, Ext##Word) a_val;)				      \
+  TYPE_XLATE (Elf32_cvt_Addr1 (&tdest->a_un.a_val, &tsrc->a_un.a_val);)	      \
+  TYPE_EXTRA (} a_un;)							      \
+END (32, Ext##auxv_t)
+#define auxv_t64(Ext) \
+START (64, auxv_t, Ext##auxv_t)						      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), a_type)				      \
+  TYPE_EXTRA (union {)							      \
+  TYPE_EXTRA (ElfW2(64, Ext##Xword) a_val;)				      \
+  TYPE_XLATE (Elf64_cvt_Addr1 (&tdest->a_un.a_val, &tsrc->a_un.a_val);)	      \
+  TYPE_EXTRA (} a_un;)							      \
+END (64, Ext##auxv_t)
+
+/* Note that there is actual compression data right after the Chdr.
+   So we also have a separate conversion function for the whole
+   section.  */
+#define Chdr32(Ext) \
+START (32, Chdr, Ext##Chdr)						\
+  TYPE_NAME (ElfW2(32, Ext##Word), ch_type)				\
+  TYPE_NAME (ElfW2(32, Ext##Word), ch_size)				\
+  TYPE_NAME (ElfW2(32, Ext##Word), ch_addralign)			\
+END (32, Ext##Chdr)
+
+#define Chdr64(Ext) \
+START (64, Chdr, Ext##Chdr)						\
+  TYPE_NAME (ElfW2(64, Ext##Word), ch_type)				\
+  TYPE_NAME (ElfW2(64, Ext##Word), ch_reserved)				\
+  TYPE_NAME (ElfW2(64, Ext##Xword), ch_size)				\
+  TYPE_NAME (ElfW2(64, Ext##Xword), ch_addralign)			\
+END (64, Ext##Chdr)
diff --git a/libelf/chdr_xlate.h b/libelf/chdr_xlate.h
new file mode 100644
index 0000000..70782b4
--- /dev/null
+++ b/libelf/chdr_xlate.h
@@ -0,0 +1,33 @@
+#include "common.h"
+
+/* These functions convert a while section, one Chdr plus compression data.  */
+
+static void
+Elf32_cvt_chdr (void *dest, const void *src, size_t len, int encode)
+{
+  if (len == 0)
+    return;
+
+  /* Move everything over, if necessary, we only need to xlate the
+     header, not the compressed data following it.  */
+  if (dest != src)
+    memmove (dest, src, len);
+
+  if (len >= sizeof (Elf32_Chdr))
+    Elf32_cvt_Chdr (dest, src, sizeof (Elf32_Chdr), encode);
+}
+
+static void
+Elf64_cvt_chdr (void *dest, const void *src, size_t len, int encode)
+{
+  if (len == 0)
+    return;
+
+  /* Move everything over, if necessary, we only need to xlate the
+     header, not the compressed data following it.  */
+  if (dest != src)
+    memmove (dest, src, len);
+
+  if (len >= sizeof (Elf64_Chdr))
+    Elf64_cvt_Chdr (dest, src, sizeof (Elf64_Chdr), encode);
+}
diff --git a/libelf/common.h b/libelf/common.h
new file mode 100644
index 0000000..744f1bb
--- /dev/null
+++ b/libelf/common.h
@@ -0,0 +1,163 @@
+/* Common definitions for handling files in memory or only on disk.
+   Copyright (C) 1998, 1999, 2000, 2002, 2005, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _COMMON_H
+#define _COMMON_H       1
+
+#include <ar.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+static inline Elf_Kind
+__attribute__ ((unused))
+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 *
+__attribute__ ((unused))
+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
+__attribute__ ((unused))
+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
+__attribute__ ((unused))
+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..6ee5d1a
--- /dev/null
+++ b/libelf/dl-hash.h
@@ -0,0 +1,75 @@
+/* Compute hash value for given string according to ELF standard.
+   Copyright (C) 1995-2015 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#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 unsigned int
+__attribute__ ((unused))
+_dl_elf_hash (const char *name_arg)
+{
+  const unsigned char *name = (const unsigned char *) name_arg;
+  unsigned long int hash = *name;
+  if (hash != 0 && name[1] != '\0')
+    {
+      hash = (hash << 4) + name[1];
+      if (name[2] != '\0')
+	{
+	  hash = (hash << 4) + name[2];
+	  if (name[3] != '\0')
+	    {
+	      hash = (hash << 4) + name[3];
+	      if (name[4] != '\0')
+		{
+		  hash = (hash << 4) + name[4];
+		  name += 5;
+		  while (*name != '\0')
+		    {
+		      unsigned long int hi;
+		      hash = (hash << 4) + *name++;
+		      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 >> 24;
+		    }
+
+		  /* Second part of the modified formula.  This
+		     operation can be lifted outside the loop.  */
+		  hash &= 0x0fffffff;
+		}
+	    }
+	}
+    }
+  return hash;
+}
+
+#endif /* dl-hash.h */
diff --git a/libelf/elf-knowledge.h b/libelf/elf-knowledge.h
new file mode 100644
index 0000000..64f5887
--- /dev/null
+++ b/libelf/elf-knowledge.h
@@ -0,0 +1,80 @@
+/* Accumulation of various pieces of knowledge about ELF.
+   Copyright (C) 2000-2012, 2014, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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.  */			      \
+       || (name != NULL							      \
+	   && 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))))
+
+
+/* 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)
+
+
+/* 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..84a7126
--- /dev/null
+++ b/libelf/elf.h
@@ -0,0 +1,3778 @@
+/* This file defines standard ELF types, structures, and macros.
+   Copyright (C) 1995-2017 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#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_GNU		3	/* Object uses GNU ELF extensions.  */
+#define ELFOSABI_LINUX		ELFOSABI_GNU /* Compatibility alias.  */
+#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_AEABI	64	/* ARM EABI */
+#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_IAMCU	 6	/* Intel MCU */
+#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 */
+				/* reserved 11-14 */
+#define EM_PARISC	15	/* HPPA */
+				/* reserved 16 */
+#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_SPU		23	/* IBM SPU/SPC */
+				/* reserved 24-35 */
+#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_PDP10	64	/* Digital PDP-10 */
+#define EM_PDP11	65	/* Digital PDP-11 */
+#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 emb.proc */
+#define EM_JAVELIN	77	/* Infineon Technologies 32-bit emb.proc */
+#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 proc */
+#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_COMPACT	93	/* ARC International ARCompact */
+#define EM_XTENSA	94	/* Tensilica Xtensa Architecture */
+#define EM_VIDEOCORE	95	/* Alphamosaic VideoCore */
+#define EM_TMM_GPP	96	/* Thompson Multimedia General Purpose Proc */
+#define EM_NS32K	97	/* National Semi. 32000 */
+#define EM_TPC		98	/* Tenor Network TPC */
+#define EM_SNP1K	99	/* Trebia SNP 1000 */
+#define EM_ST200	100	/* STMicroelectronics ST200 */
+#define EM_IP2K		101	/* Ubicom IP2xxx */
+#define EM_MAX		102	/* MAX processor */
+#define EM_CR		103	/* National Semi. CompactRISC */
+#define EM_F2MC16	104	/* Fujitsu F2MC16 */
+#define EM_MSP430	105	/* Texas Instruments msp430 */
+#define EM_BLACKFIN	106	/* Analog Devices Blackfin DSP */
+#define EM_SE_C33	107	/* Seiko Epson S1C33 family */
+#define EM_SEP		108	/* Sharp embedded microprocessor */
+#define EM_ARCA		109	/* Arca RISC */
+#define EM_UNICORE	110	/* PKU-Unity & MPRC Peking Uni. mc series */
+#define EM_EXCESS	111	/* eXcess configurable cpu */
+#define EM_DXP		112	/* Icera Semi. Deep Execution Processor */
+#define EM_ALTERA_NIOS2 113	/* Altera Nios II */
+#define EM_CRX		114	/* National Semi. CompactRISC CRX */
+#define EM_XGATE	115	/* Motorola XGATE */
+#define EM_C166		116	/* Infineon C16x/XC16x */
+#define EM_M16C		117	/* Renesas M16C */
+#define EM_DSPIC30F	118	/* Microchip Technology dsPIC30F */
+#define EM_CE		119	/* Freescale Communication Engine RISC */
+#define EM_M32C		120	/* Renesas M32C */
+				/* reserved 121-130 */
+#define EM_TSK3000	131	/* Altium TSK3000 */
+#define EM_RS08		132	/* Freescale RS08 */
+#define EM_SHARC	133	/* Analog Devices SHARC family */
+#define EM_ECOG2	134	/* Cyan Technology eCOG2 */
+#define EM_SCORE7	135	/* Sunplus S+core7 RISC */
+#define EM_DSP24	136	/* New Japan Radio (NJR) 24-bit DSP */
+#define EM_VIDEOCORE3	137	/* Broadcom VideoCore III */
+#define EM_LATTICEMICO32 138	/* RISC for Lattice FPGA */
+#define EM_SE_C17	139	/* Seiko Epson C17 */
+#define EM_TI_C6000	140	/* Texas Instruments TMS320C6000 DSP */
+#define EM_TI_C2000	141	/* Texas Instruments TMS320C2000 DSP */
+#define EM_TI_C5500	142	/* Texas Instruments TMS320C55x DSP */
+#define EM_TI_ARP32	143	/* Texas Instruments App. Specific RISC */
+#define EM_TI_PRU	144	/* Texas Instruments Prog. Realtime Unit */
+				/* reserved 145-159 */
+#define EM_MMDSP_PLUS	160	/* STMicroelectronics 64bit VLIW DSP */
+#define EM_CYPRESS_M8C	161	/* Cypress M8C */
+#define EM_R32C		162	/* Renesas R32C */
+#define EM_TRIMEDIA	163	/* NXP Semi. TriMedia */
+#define EM_QDSP6	164	/* QUALCOMM DSP6 */
+#define EM_8051		165	/* Intel 8051 and variants */
+#define EM_STXP7X	166	/* STMicroelectronics STxP7x */
+#define EM_NDS32	167	/* Andes Tech. compact code emb. RISC */
+#define EM_ECOG1X	168	/* Cyan Technology eCOG1X */
+#define EM_MAXQ30	169	/* Dallas Semi. MAXQ30 mc */
+#define EM_XIMO16	170	/* New Japan Radio (NJR) 16-bit DSP */
+#define EM_MANIK	171	/* M2000 Reconfigurable RISC */
+#define EM_CRAYNV2	172	/* Cray NV2 vector architecture */
+#define EM_RX		173	/* Renesas RX */
+#define EM_METAG	174	/* Imagination Tech. META */
+#define EM_MCST_ELBRUS	175	/* MCST Elbrus */
+#define EM_ECOG16	176	/* Cyan Technology eCOG16 */
+#define EM_CR16		177	/* National Semi. CompactRISC CR16 */
+#define EM_ETPU		178	/* Freescale Extended Time Processing Unit */
+#define EM_SLE9X	179	/* Infineon Tech. SLE9X */
+#define EM_L10M		180	/* Intel L10M */
+#define EM_K10M		181	/* Intel K10M */
+				/* reserved 182 */
+#define EM_AARCH64	183	/* ARM AARCH64 */
+				/* reserved 184 */
+#define EM_AVR32	185	/* Amtel 32-bit microprocessor */
+#define EM_STM8		186	/* STMicroelectronics STM8 */
+#define EM_TILE64	187	/* Tileta TILE64 */
+#define EM_TILEPRO	188	/* Tilera TILEPro */
+#define EM_MICROBLAZE	189	/* Xilinx MicroBlaze */
+#define EM_CUDA		190	/* NVIDIA CUDA */
+#define EM_TILEGX	191	/* Tilera TILE-Gx */
+#define EM_CLOUDSHIELD	192	/* CloudShield */
+#define EM_COREA_1ST	193	/* KIPO-KAIST Core-A 1st gen. */
+#define EM_COREA_2ND	194	/* KIPO-KAIST Core-A 2nd gen. */
+#define EM_ARC_COMPACT2	195	/* Synopsys ARCompact V2 */
+#define EM_OPEN8	196	/* Open8 RISC */
+#define EM_RL78		197	/* Renesas RL78 */
+#define EM_VIDEOCORE5	198	/* Broadcom VideoCore V */
+#define EM_78KOR	199	/* Renesas 78KOR */
+#define EM_56800EX	200	/* Freescale 56800EX DSC */
+#define EM_BA1		201	/* Beyond BA1 */
+#define EM_BA2		202	/* Beyond BA2 */
+#define EM_XCORE	203	/* XMOS xCORE */
+#define EM_MCHP_PIC	204	/* Microchip 8-bit PIC(r) */
+				/* reserved 205-209 */
+#define EM_KM32		210	/* KM211 KM32 */
+#define EM_KMX32	211	/* KM211 KMX32 */
+#define EM_EMX16	212	/* KM211 KMX16 */
+#define EM_EMX8		213	/* KM211 KMX8 */
+#define EM_KVARC	214	/* KM211 KVARC */
+#define EM_CDP		215	/* Paneve CDP */
+#define EM_COGE		216	/* Cognitive Smart Memory Processor */
+#define EM_COOL		217	/* Bluechip CoolEngine */
+#define EM_NORC		218	/* Nanoradio Optimized RISC */
+#define EM_CSR_KALIMBA	219	/* CSR Kalimba */
+#define EM_Z80		220	/* Zilog Z80 */
+#define EM_VISIUM	221	/* Controls and Data Services VISIUMcore */
+#define EM_FT32		222	/* FTDI Chip FT32 */
+#define EM_MOXIE	223	/* Moxie processor */
+#define EM_AMDGPU	224	/* AMD GPU */
+				/* reserved 225-242 */
+#define EM_RISCV	243	/* RISC-V */
+
+#define EM_BPF		247	/* Linux BPF -- in-kernel virtual machine */
+
+#define EM_NUM		248
+
+/* Old spellings/synonyms.  */
+
+#define EM_ARC_A5	EM_ARC_COMPACT
+
+/* 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_ATTRIBUTES 0x6ffffff5	/* Object attributes.  */
+#define SHT_GNU_HASH	  0x6ffffff6	/* GNU-style hash table.  */
+#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_COMPRESSED	     (1 << 11)	/* Section with compressed 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	     (1U << 31)	/* Section is excluded unless
+					   referenced or allocated (Solaris).*/
+
+/* Section compression header.  Used when SHF_COMPRESSED is set.  */
+
+typedef struct
+{
+  Elf32_Word	ch_type;	/* Compression format.  */
+  Elf32_Word	ch_size;	/* Uncompressed data size.  */
+  Elf32_Word	ch_addralign;	/* Uncompressed data alignment.  */
+} Elf32_Chdr;
+
+typedef struct
+{
+  Elf64_Word	ch_type;	/* Compression format.  */
+  Elf64_Word	ch_reserved;
+  Elf64_Xword	ch_size;	/* Uncompressed data size.  */
+  Elf64_Xword	ch_addralign;	/* Uncompressed data alignment.  */
+} Elf64_Chdr;
+
+/* Legal values for ch_type (compression algorithm).  */
+#define ELFCOMPRESS_ZLIB	1	   /* ZLIB/DEFLATE algorithm.  */
+#define ELFCOMPRESS_LOOS	0x60000000 /* Start of OS-specific.  */
+#define ELFCOMPRESS_HIOS	0x6fffffff /* End of OS-specific.  */
+#define ELFCOMPRESS_LOPROC	0x70000000 /* Start of processor-specific.  */
+#define ELFCOMPRESS_HIPROC	0x7fffffff /* End of processor-specific.  */
+
+/* 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_GNU_UNIQUE	10		/* Unique symbol.  */
+#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_GNU_IFUNC	10		/* Symbol is indirect code object */
+#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;
+
+/* Special value for e_phnum.  This indicates that the real number of
+   program headers is too large to fit into e_phnum.  Instead the real
+   value is in the field sh_info of section 0.  */
+
+#define PN_XNUM		0xffff
+
+/* 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 */
+#define NT_SIGINFO	0x53494749	/* Contains copy of siginfo_t,
+					   size might increase */
+#define NT_FILE		0x46494c45	/* Contains information about mapped
+					   files */
+#define NT_PRXFPREG	0x46e62b7f	/* Contains copy of user_fxsr_struct */
+#define NT_PPC_VMX	0x100		/* PowerPC Altivec/VMX registers */
+#define NT_PPC_SPE	0x101		/* PowerPC SPE/EVR registers */
+#define NT_PPC_VSX	0x102		/* PowerPC VSX registers */
+#define NT_PPC_TAR	0x103		/* Target Address Register */
+#define NT_PPC_PPR	0x104		/* Program Priority Register */
+#define NT_PPC_DSCR	0x105		/* Data Stream Control Register */
+#define NT_PPC_EBB	0x106		/* Event Based Branch Registers */
+#define NT_PPC_PMU	0x107		/* Performance Monitor Registers */
+#define NT_PPC_TM_CGPR	0x108		/* TM checkpointed GPR Registers */
+#define NT_PPC_TM_CFPR	0x109		/* TM checkpointed FPR Registers */
+#define NT_PPC_TM_CVMX	0x10a		/* TM checkpointed VMX Registers */
+#define NT_PPC_TM_CVSX	0x10b		/* TM checkpointed VSX Registers */
+#define NT_PPC_TM_SPR	0x10c		/* TM Special Purpose Registers */
+#define NT_PPC_TM_CTAR	0x10d		/* TM checkpointed Target Address
+					   Register */
+#define NT_PPC_TM_CPPR	0x10e		/* TM checkpointed Program Priority
+					   Register */
+#define NT_PPC_TM_CDSCR	0x10f		/* TM checkpointed Data Stream Control
+					   Register */
+#define NT_386_TLS	0x200		/* i386 TLS slots (struct user_desc) */
+#define NT_386_IOPERM	0x201		/* x86 io permission bitmap (1=deny) */
+#define NT_X86_XSTATE	0x202		/* x86 extended state using xsave */
+#define NT_S390_HIGH_GPRS	0x300	/* s390 upper register halves */
+#define NT_S390_TIMER	0x301		/* s390 timer register */
+#define NT_S390_TODCMP	0x302		/* s390 TOD clock comparator register */
+#define NT_S390_TODPREG	0x303		/* s390 TOD programmable register */
+#define NT_S390_CTRS	0x304		/* s390 control registers */
+#define NT_S390_PREFIX	0x305		/* s390 prefix register */
+#define NT_S390_LAST_BREAK	0x306	/* s390 breaking event address */
+#define NT_S390_SYSTEM_CALL	0x307	/* s390 system call restart data */
+#define NT_S390_TDB	0x308		/* s390 transaction diagnostic block */
+#define NT_ARM_VFP	0x400		/* ARM VFP/NEON registers */
+#define NT_ARM_TLS	0x401		/* ARM TLS register */
+#define NT_ARM_HW_BREAK	0x402		/* ARM hardware breakpoint registers */
+#define NT_ARM_HW_WATCH	0x403		/* ARM hardware watchpoint registers */
+#define NT_ARM_SYSTEM_CALL	0x404	/* ARM system call number */
+
+/* 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_HASH	0x6ffffef5	/* GNU-style hash table.  */
+#define DT_TLSDESC_PLT	0x6ffffef6
+#define DT_TLSDESC_GOT	0x6ffffef7
+#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 11
+
+/* 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.  */
+#define	DF_1_NODIRECT	0x00020000	/* Object has no-direct binding. */
+#define	DF_1_IGNMULDEF	0x00040000
+#define	DF_1_NOKSYMS	0x00080000
+#define	DF_1_NOHDR	0x00100000
+#define	DF_1_EDITED	0x00200000	/* Object is modified after built.  */
+#define	DF_1_NORELOC	0x00400000
+#define	DF_1_SYMINTPOSE	0x00800000	/* Object has individual interposers.  */
+#define	DF_1_GLOBAUDIT	0x01000000	/* Global auditing required.  */
+#define	DF_1_SINGLETON	0x02000000	/* Singleton symbols are used.  */
+
+/* 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?  */
+
+#define AT_BASE_PLATFORM 24		/* String identifying real platforms.*/
+
+#define AT_RANDOM	25		/* Address of 16 random bytes.  */
+
+#define AT_HWCAP2	26		/* More machine-dependent hints about
+					   processor capabilities.  */
+
+#define AT_EXECFN	31		/* Filename of executable.  */
+
+/* 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
+
+/* Shapes of the caches, with more room to describe them.
+   *GEOMETRY are comprised of cache line size in bytes in the bottom 16 bits
+   and the cache associativity in the next 16 bits.  */
+#define AT_L1I_CACHESIZE	40
+#define AT_L1I_CACHEGEOMETRY	41
+#define AT_L1D_CACHESIZE	42
+#define AT_L1D_CACHEGEOMETRY	43
+#define AT_L2_CACHESIZE		44
+#define AT_L2_CACHEGEOMETRY	45
+#define AT_L3_CACHESIZE		46
+#define AT_L3_CACHEGEOMETRY	47
+
+/* 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 NT_GNU_ABI_TAG	1
+#define ELF_NOTE_ABI	NT_GNU_ABI_TAG /* Old name.  */
+
+/* Known OSes.  These values can appear in word 0 of an
+   NT_GNU_ABI_TAG 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
+
+/* Synthetic hwcap information.  The descriptor begins with two words:
+   word 0: number of entries
+   word 1: bitmask of enabled entries
+   Then follow variable-length entries, one byte followed by a
+   '\0'-terminated hwcap name string.  The byte gives the bit
+   number to test if enabled, (1U << bit) & bitmask.  */
+#define NT_GNU_HWCAP	2
+
+/* Build ID bits as generated by ld --build-id.
+   The descriptor consists of any nonzero number of bytes.  */
+#define NT_GNU_BUILD_ID	3
+
+/* Version note generated by GNU gold containing a version string.  */
+#define NT_GNU_GOLD_VERSION	4
+
+
+/* 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 */
+#define R_68K_TLS_GD32      25          /* 32 bit GOT offset for GD */
+#define R_68K_TLS_GD16      26          /* 16 bit GOT offset for GD */
+#define R_68K_TLS_GD8       27          /* 8 bit GOT offset for GD */
+#define R_68K_TLS_LDM32     28          /* 32 bit GOT offset for LDM */
+#define R_68K_TLS_LDM16     29          /* 16 bit GOT offset for LDM */
+#define R_68K_TLS_LDM8      30          /* 8 bit GOT offset for LDM */
+#define R_68K_TLS_LDO32     31          /* 32 bit module-relative offset */
+#define R_68K_TLS_LDO16     32          /* 16 bit module-relative offset */
+#define R_68K_TLS_LDO8      33          /* 8 bit module-relative offset */
+#define R_68K_TLS_IE32      34          /* 32 bit GOT offset for IE */
+#define R_68K_TLS_IE16      35          /* 16 bit GOT offset for IE */
+#define R_68K_TLS_IE8       36          /* 8 bit GOT offset for IE */
+#define R_68K_TLS_LE32      37          /* 32 bit offset relative to
+					   static TLS block */
+#define R_68K_TLS_LE16      38          /* 16 bit offset relative to
+					   static TLS block */
+#define R_68K_TLS_LE8       39          /* 8 bit offset relative to
+					   static TLS block */
+#define R_68K_TLS_DTPMOD32  40          /* 32 bit module number */
+#define R_68K_TLS_DTPREL32  41          /* 32 bit module-relative offset */
+#define R_68K_TLS_TPREL32   42          /* 32 bit TP-relative offset */
+/* Keep this the last entry.  */
+#define R_68K_NUM	43
+
+/* 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 */
+#define R_386_SIZE32	   38 		/* 32-bit symbol size */
+#define R_386_TLS_GOTDESC  39		/* GOT offset for TLS descriptor.  */
+#define R_386_TLS_DESC_CALL 40		/* Marker of call through TLS
+					   descriptor for
+					   relaxation.  */
+#define R_386_TLS_DESC     41		/* TLS descriptor containing
+					   pointer to code and to
+					   argument, returning the TLS
+					   offset for the symbol.  */
+#define R_386_IRELATIVE	   42		/* Adjust indirectly by program base */
+#define R_386_GOT32X	   43		/* Load from 32 bit GOT entry,
+					   relaxable. */
+/* Keep this the last entry.  */
+#define R_386_NUM	   44
+
+/* 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_GLOB_JMP	42	/* was part of v9 ABI but was removed */
+#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
+#define R_SPARC_GOTDATA_HIX22	80
+#define R_SPARC_GOTDATA_LOX10	81
+#define R_SPARC_GOTDATA_OP_HIX22	82
+#define R_SPARC_GOTDATA_OP_LOX10	83
+#define R_SPARC_GOTDATA_OP	84
+#define R_SPARC_H34		85
+#define R_SPARC_SIZE32		86
+#define R_SPARC_SIZE64		87
+#define R_SPARC_WDISP10		88
+#define R_SPARC_JMP_IREL	248
+#define R_SPARC_IRELATIVE	249
+#define R_SPARC_GNU_VTINHERIT	250
+#define R_SPARC_GNU_VTENTRY	251
+#define R_SPARC_REV32		252
+/* Keep this the last entry.  */
+#define R_SPARC_NUM		253
+
+/* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
+
+#define DT_SPARC_REGISTER	0x70000001
+#define DT_SPARC_NUM		2
+
+/* 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_FP64		512  /* Uses FP64 (12 callee-saved).  */
+#define EF_MIPS_NAN2008	1024  /* Uses IEEE 754-2008 NaN encoding.  */
+#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		0x50000000 /* MIPS32 code.  */
+#define EF_MIPS_ARCH_64		0x60000000 /* MIPS64 code.  */
+#define EF_MIPS_ARCH_32R2	0x70000000 /* MIPS32r2 code.  */
+#define EF_MIPS_ARCH_64R2	0x80000000 /* MIPS64r2 code.  */
+
+/* The following are unofficial names and should not be used.  */
+
+#define E_MIPS_ARCH_1		EF_MIPS_ARCH_1
+#define E_MIPS_ARCH_2		EF_MIPS_ARCH_2
+#define E_MIPS_ARCH_3		EF_MIPS_ARCH_3
+#define E_MIPS_ARCH_4		EF_MIPS_ARCH_4
+#define E_MIPS_ARCH_5		EF_MIPS_ARCH_5
+#define E_MIPS_ARCH_32		EF_MIPS_ARCH_32
+#define E_MIPS_ARCH_64		EF_MIPS_ARCH_64
+
+/* 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 info.  */
+#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 in 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_PLT			0x8
+#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 */
+#define R_MIPS_GLOB_DAT		51
+#define R_MIPS_COPY		126
+#define R_MIPS_JUMP_SLOT        127
+/* Keep this the last entry.  */
+#define R_MIPS_NUM		128
+
+/* 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
+#define PT_MIPS_ABIFLAGS  0x70000003	/* FP mode requirement. */
+
+/* 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.  */
+/* The address of .got.plt in an executable using the new non-PIC ABI.  */
+#define DT_MIPS_PLTGOT	     0x70000032
+/* The base of the PLT in an executable using the new non-PIC ABI if that
+   PLT is writable.  For a non-writable PLT, this is omitted or has a zero
+   value.  */
+#define DT_MIPS_RWPLT        0x70000034
+/* An alternative description of the classic MIPS RLD_MAP that is usable
+   in a PIE as it stores a relative offset from the address of the tag
+   rather than an absolute address.  */
+#define DT_MIPS_RLD_MAP_REL  0x70000035
+#define DT_MIPS_NUM	     0x36
+
+/* 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;
+
+typedef struct
+{
+  /* Version of flags structure.  */
+  Elf32_Half version;
+  /* The level of the ISA: 1-5, 32, 64.  */
+  unsigned char isa_level;
+  /* The revision of ISA: 0 for MIPS V and below, 1-n otherwise.  */
+  unsigned char isa_rev;
+  /* The size of general purpose registers.  */
+  unsigned char gpr_size;
+  /* The size of co-processor 1 registers.  */
+  unsigned char cpr1_size;
+  /* The size of co-processor 2 registers.  */
+  unsigned char cpr2_size;
+  /* The floating-point ABI.  */
+  unsigned char fp_abi;
+  /* Processor-specific extension.  */
+  Elf32_Word isa_ext;
+  /* Mask of ASEs used.  */
+  Elf32_Word ases;
+  /* Mask of general flags.  */
+  Elf32_Word flags1;
+  Elf32_Word flags2;
+} Elf_MIPS_ABIFlags_v0;
+
+/* Values for the register size bytes of an abi flags structure.  */
+
+#define MIPS_AFL_REG_NONE	0x00	 /* No registers.  */
+#define MIPS_AFL_REG_32		0x01	 /* 32-bit registers.  */
+#define MIPS_AFL_REG_64		0x02	 /* 64-bit registers.  */
+#define MIPS_AFL_REG_128	0x03	 /* 128-bit registers.  */
+
+/* Masks for the ases word of an ABI flags structure.  */
+
+#define MIPS_AFL_ASE_DSP	0x00000001 /* DSP ASE.  */
+#define MIPS_AFL_ASE_DSPR2	0x00000002 /* DSP R2 ASE.  */
+#define MIPS_AFL_ASE_EVA	0x00000004 /* Enhanced VA Scheme.  */
+#define MIPS_AFL_ASE_MCU	0x00000008 /* MCU (MicroController) ASE.  */
+#define MIPS_AFL_ASE_MDMX	0x00000010 /* MDMX ASE.  */
+#define MIPS_AFL_ASE_MIPS3D	0x00000020 /* MIPS-3D ASE.  */
+#define MIPS_AFL_ASE_MT		0x00000040 /* MT ASE.  */
+#define MIPS_AFL_ASE_SMARTMIPS	0x00000080 /* SmartMIPS ASE.  */
+#define MIPS_AFL_ASE_VIRT	0x00000100 /* VZ ASE.  */
+#define MIPS_AFL_ASE_MSA	0x00000200 /* MSA ASE.  */
+#define MIPS_AFL_ASE_MIPS16	0x00000400 /* MIPS16 ASE.  */
+#define MIPS_AFL_ASE_MICROMIPS	0x00000800 /* MICROMIPS ASE.  */
+#define MIPS_AFL_ASE_XPA	0x00001000 /* XPA ASE.  */
+#define MIPS_AFL_ASE_MASK	0x00001fff /* All ASEs.  */
+
+/* Values for the isa_ext word of an ABI flags structure.  */
+
+#define MIPS_AFL_EXT_XLR	  1   /* RMI Xlr instruction.  */
+#define MIPS_AFL_EXT_OCTEON2	  2   /* Cavium Networks Octeon2.  */
+#define MIPS_AFL_EXT_OCTEONP	  3   /* Cavium Networks OcteonP.  */
+#define MIPS_AFL_EXT_LOONGSON_3A  4   /* Loongson 3A.  */
+#define MIPS_AFL_EXT_OCTEON	  5   /* Cavium Networks Octeon.  */
+#define MIPS_AFL_EXT_5900	  6   /* MIPS R5900 instruction.  */
+#define MIPS_AFL_EXT_4650	  7   /* MIPS R4650 instruction.  */
+#define MIPS_AFL_EXT_4010	  8   /* LSI R4010 instruction.  */
+#define MIPS_AFL_EXT_4100	  9   /* NEC VR4100 instruction.  */
+#define MIPS_AFL_EXT_3900	  10  /* Toshiba R3900 instruction.  */
+#define MIPS_AFL_EXT_10000	  11  /* MIPS R10000 instruction.  */
+#define MIPS_AFL_EXT_SB1	  12  /* Broadcom SB-1 instruction.  */
+#define MIPS_AFL_EXT_4111	  13  /* NEC VR4111/VR4181 instruction.  */
+#define MIPS_AFL_EXT_4120	  14  /* NEC VR4120 instruction.  */
+#define MIPS_AFL_EXT_5400	  15  /* NEC VR5400 instruction.  */
+#define MIPS_AFL_EXT_5500	  16  /* NEC VR5500 instruction.  */
+#define MIPS_AFL_EXT_LOONGSON_2E  17  /* ST Microelectronics Loongson 2E.  */
+#define MIPS_AFL_EXT_LOONGSON_2F  18  /* ST Microelectronics Loongson 2F.  */
+
+/* Masks for the flags1 word of an ABI flags structure.  */
+#define MIPS_AFL_FLAGS1_ODDSPREG  1  /* Uses odd single-precision registers.  */
+
+/* Object attribute values.  */
+enum
+{
+  /* Not tagged or not using any ABIs affected by the differences.  */
+  Val_GNU_MIPS_ABI_FP_ANY = 0,
+  /* Using hard-float -mdouble-float.  */
+  Val_GNU_MIPS_ABI_FP_DOUBLE = 1,
+  /* Using hard-float -msingle-float.  */
+  Val_GNU_MIPS_ABI_FP_SINGLE = 2,
+  /* Using soft-float.  */
+  Val_GNU_MIPS_ABI_FP_SOFT = 3,
+  /* Using -mips32r2 -mfp64.  */
+  Val_GNU_MIPS_ABI_FP_OLD_64 = 4,
+  /* Using -mfpxx.  */
+  Val_GNU_MIPS_ABI_FP_XX = 5,
+  /* Using -mips32r2 -mfp64.  */
+  Val_GNU_MIPS_ABI_FP_64 = 6,
+  /* Using -mips32r2 -mfp64 -mno-odd-spreg.  */
+  Val_GNU_MIPS_ABI_FP_64A = 7,
+  /* Maximum allocated FP ABI value.  */
+  Val_GNU_MIPS_ABI_FP_MAX = 7
+};
+
+/* 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_PLABEL21L	66	/* Left 21 bits of fdesc address.  */
+#define R_PARISC_PLABEL14R	70	/* Right 14 bits of fdesc 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_GNU_VTENTRY	232
+#define R_PARISC_GNU_VTINHERIT	233
+#define R_PARISC_TLS_GD21L	234	/* GD 21-bit left.  */
+#define R_PARISC_TLS_GD14R	235	/* GD 14-bit right.  */
+#define R_PARISC_TLS_GDCALL	236	/* GD call to __t_g_a.  */
+#define R_PARISC_TLS_LDM21L	237	/* LD module 21-bit left.  */
+#define R_PARISC_TLS_LDM14R	238	/* LD module 14-bit right.  */
+#define R_PARISC_TLS_LDMCALL	239	/* LD module call to __t_g_a.  */
+#define R_PARISC_TLS_LDO21L	240	/* LD offset 21-bit left.  */
+#define R_PARISC_TLS_LDO14R	241	/* LD offset 14-bit right.  */
+#define R_PARISC_TLS_DTPMOD32	242	/* DTP module 32-bit.  */
+#define R_PARISC_TLS_DTPMOD64	243	/* DTP module 64-bit.  */
+#define R_PARISC_TLS_DTPOFF32	244	/* DTP offset 32-bit.  */
+#define R_PARISC_TLS_DTPOFF64	245	/* DTP offset 32-bit.  */
+#define R_PARISC_TLS_LE21L	R_PARISC_TPREL21L
+#define R_PARISC_TLS_LE14R	R_PARISC_TPREL14R
+#define R_PARISC_TLS_IE21L	R_PARISC_LTOFF_TP21L
+#define R_PARISC_TLS_IE14R	R_PARISC_LTOFF_TP14R
+#define R_PARISC_TLS_TPREL32	R_PARISC_TPREL32
+#define R_PARISC_TLS_TPREL64	R_PARISC_TPREL64
+#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
+
+/* Legal values for d_tag of Elf64_Dyn.  */
+#define DT_ALPHA_PLTRO		(DT_LOPROC + 0)
+#define DT_ALPHA_NUM		1
+
+/* 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 */
+#define R_PPC_TLSGD		95 /* none	(sym+add)@tlsgd */
+#define R_PPC_TLSLD		96 /* none	(sym+add)@tlsld */
+
+/* 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 */
+
+/* GNU extension to support local ifunc.  */
+#define R_PPC_IRELATIVE		248
+
+/* GNU relocs used in PIC code sequences.  */
+#define R_PPC_REL16		249	/* half16   (sym+add-.) */
+#define R_PPC_REL16_LO		250	/* half16   (sym+add-.)@l */
+#define R_PPC_REL16_HI		251	/* half16   (sym+add-.)@h */
+#define R_PPC_REL16_HA		252	/* half16   (sym+add-.)@ha */
+
+/* This is a phony reloc to handle any old fashioned TOC16 references
+   that may still be in object files.  */
+#define R_PPC_TOC16		255
+
+/* PowerPC specific values for the Dyn d_tag field.  */
+#define DT_PPC_GOT		(DT_LOPROC + 0)
+#define DT_PPC_OPT		(DT_LOPROC + 1)
+#define DT_PPC_NUM		2
+
+/* PowerPC specific values for the DT_PPC_OPT Dyn entry.  */
+#define PPC_OPT_TLS		1
+
+/* 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 */
+#define R_PPC64_TLSGD		107 /* none	(sym+add)@tlsgd */
+#define R_PPC64_TLSLD		108 /* none	(sym+add)@tlsld */
+#define R_PPC64_TOCSAVE		109 /* none */
+
+/* Added when HA and HI relocs were changed to report overflows.  */
+#define R_PPC64_ADDR16_HIGH	110
+#define R_PPC64_ADDR16_HIGHA	111
+#define R_PPC64_TPREL16_HIGH	112
+#define R_PPC64_TPREL16_HIGHA	113
+#define R_PPC64_DTPREL16_HIGH	114
+#define R_PPC64_DTPREL16_HIGHA	115
+
+/* GNU extension to support local ifunc.  */
+#define R_PPC64_JMP_IREL	247
+#define R_PPC64_IRELATIVE	248
+#define R_PPC64_REL16		249	/* half16   (sym+add-.) */
+#define R_PPC64_REL16_LO	250	/* half16   (sym+add-.)@l */
+#define R_PPC64_REL16_HI	251	/* half16   (sym+add-.)@h */
+#define R_PPC64_REL16_HA	252	/* half16   (sym+add-.)@ha */
+
+/* e_flags bits specifying ABI.
+   1 for original function descriptor using ABI,
+   2 for revised ABI without function descriptors,
+   0 for unspecified or not using any features affected by the differences.  */
+#define EF_PPC64_ABI	3
+
+/* 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_OPT	(DT_LOPROC + 3)
+#define DT_PPC64_NUM    4
+
+/* PowerPC64 specific bits in the DT_PPC64_OPT Dyn entry.  */
+#define PPC64_OPT_TLS		1
+#define PPC64_OPT_MULTI_TOC	2
+#define PPC64_OPT_LOCALENTRY	4
+
+/* PowerPC64 specific values for the Elf64_Sym st_other field.  */
+#define STO_PPC64_LOCAL_BIT	5
+#define STO_PPC64_LOCAL_MASK	(7 << STO_PPC64_LOCAL_BIT)
+#define PPC64_LOCAL_ENTRY_OFFSET(other)				\
+ (((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2)
+
+
+/* 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
+#define EF_ARM_SOFT_FLOAT	0x200
+#define EF_ARM_VFP_FLOAT	0x400
+#define EF_ARM_MAVERICK_FLOAT	0x800
+
+#define EF_ARM_ABI_FLOAT_SOFT	0x200   /* NB conflicts with EF_ARM_SOFT_FLOAT */
+#define EF_ARM_ABI_FLOAT_HARD	0x400   /* NB conflicts with EF_ARM_VFP_FLOAT */
+
+
+/* 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
+
+/* Constants defined in AAELF.  */
+#define EF_ARM_BE8	    0x00800000
+#define EF_ARM_LE8	    0x00400000
+
+#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
+#define EF_ARM_EABI_VER3	0x03000000
+#define EF_ARM_EABI_VER4	0x04000000
+#define EF_ARM_EABI_VER5	0x05000000
+
+/* Additional symbol types for Thumb.  */
+#define STT_ARM_TFUNC		STT_LOPROC /* A Thumb function.  */
+#define STT_ARM_16BIT		STT_HIPROC /* A Thumb label.  */
+
+/* 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. */
+#define PF_ARM_PI		0x20000000 /* Position-independent segment.  */
+#define PF_ARM_ABS		0x40000000 /* Absolute segment.  */
+
+/* Processor specific values for the Phdr p_type field.  */
+#define PT_ARM_EXIDX		(PT_LOPROC + 1)	/* ARM unwind segment.  */
+
+/* Processor specific values for the Shdr sh_type field.  */
+#define SHT_ARM_EXIDX		(SHT_LOPROC + 1) /* ARM unwind section.  */
+#define SHT_ARM_PREEMPTMAP	(SHT_LOPROC + 2) /* Preemption details.  */
+#define SHT_ARM_ATTRIBUTES	(SHT_LOPROC + 3) /* ARM attributes section.  */
+
+
+/* AArch64 relocs.  */
+
+#define R_AARCH64_NONE            0	/* No relocation.  */
+
+/* ILP32 AArch64 relocs.  */
+#define R_AARCH64_P32_ABS32		  1	/* Direct 32 bit.  */
+#define R_AARCH64_P32_COPY		180	/* Copy symbol at runtime.  */
+#define R_AARCH64_P32_GLOB_DAT		181	/* Create GOT entry.  */
+#define R_AARCH64_P32_JUMP_SLOT		182	/* Create PLT entry.  */
+#define R_AARCH64_P32_RELATIVE		183	/* Adjust by program base.  */
+#define R_AARCH64_P32_TLS_DTPMOD	184	/* Module number, 32 bit.  */
+#define R_AARCH64_P32_TLS_DTPREL	185	/* Module-relative offset, 32 bit.  */
+#define R_AARCH64_P32_TLS_TPREL		186	/* TP-relative offset, 32 bit.  */
+#define R_AARCH64_P32_TLSDESC		187	/* TLS Descriptor.  */
+#define R_AARCH64_P32_IRELATIVE		188	/* STT_GNU_IFUNC relocation. */
+
+/* LP64 AArch64 relocs.  */
+#define R_AARCH64_ABS64         257	/* Direct 64 bit. */
+#define R_AARCH64_ABS32         258	/* Direct 32 bit.  */
+#define R_AARCH64_ABS16		259	/* Direct 16-bit.  */
+#define R_AARCH64_PREL64	260	/* PC-relative 64-bit.	*/
+#define R_AARCH64_PREL32	261	/* PC-relative 32-bit.	*/
+#define R_AARCH64_PREL16	262	/* PC-relative 16-bit.	*/
+#define R_AARCH64_MOVW_UABS_G0	263	/* Dir. MOVZ imm. from bits 15:0.  */
+#define R_AARCH64_MOVW_UABS_G0_NC 264	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_UABS_G1	265	/* Dir. MOVZ imm. from bits 31:16.  */
+#define R_AARCH64_MOVW_UABS_G1_NC 266	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_UABS_G2	267	/* Dir. MOVZ imm. from bits 47:32.  */
+#define R_AARCH64_MOVW_UABS_G2_NC 268	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_UABS_G3	269	/* Dir. MOV{K,Z} imm. from 63:48.  */
+#define R_AARCH64_MOVW_SABS_G0	270	/* Dir. MOV{N,Z} imm. from 15:0.  */
+#define R_AARCH64_MOVW_SABS_G1	271	/* Dir. MOV{N,Z} imm. from 31:16.  */
+#define R_AARCH64_MOVW_SABS_G2	272	/* Dir. MOV{N,Z} imm. from 47:32.  */
+#define R_AARCH64_LD_PREL_LO19	273	/* PC-rel. LD imm. from bits 20:2.  */
+#define R_AARCH64_ADR_PREL_LO21	274	/* PC-rel. ADR imm. from bits 20:0.  */
+#define R_AARCH64_ADR_PREL_PG_HI21 275	/* Page-rel. ADRP imm. from 32:12.  */
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check.  */
+#define R_AARCH64_ADD_ABS_LO12_NC 277	/* Dir. ADD imm. from bits 11:0.  */
+#define R_AARCH64_LDST8_ABS_LO12_NC 278	/* Likewise for LD/ST; no check. */
+#define R_AARCH64_TSTBR14	279	/* PC-rel. TBZ/TBNZ imm. from 15:2.  */
+#define R_AARCH64_CONDBR19	280	/* PC-rel. cond. br. imm. from 20:2. */
+#define R_AARCH64_JUMP26	282	/* PC-rel. B imm. from bits 27:2.  */
+#define R_AARCH64_CALL26	283	/* Likewise for CALL.  */
+#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1.  */
+#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2.  */
+#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3.  */
+#define R_AARCH64_MOVW_PREL_G0	287	/* PC-rel. MOV{N,Z} imm. from 15:0.  */
+#define R_AARCH64_MOVW_PREL_G0_NC 288	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_PREL_G1	289	/* PC-rel. MOV{N,Z} imm. from 31:16. */
+#define R_AARCH64_MOVW_PREL_G1_NC 290	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_PREL_G2	291	/* PC-rel. MOV{N,Z} imm. from 47:32. */
+#define R_AARCH64_MOVW_PREL_G2_NC 292	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_PREL_G3	293	/* PC-rel. MOV{N,Z} imm. from 63:48. */
+#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4.  */
+#define R_AARCH64_MOVW_GOTOFF_G0 300	/* GOT-rel. off. MOV{N,Z} imm. 15:0. */
+#define R_AARCH64_MOVW_GOTOFF_G0_NC 301	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_GOTOFF_G1 302	/* GOT-rel. o. MOV{N,Z} imm. 31:16.  */
+#define R_AARCH64_MOVW_GOTOFF_G1_NC 303	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_GOTOFF_G2 304	/* GOT-rel. o. MOV{N,Z} imm. 47:32.  */
+#define R_AARCH64_MOVW_GOTOFF_G2_NC 305	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_GOTOFF_G3 306	/* GOT-rel. o. MOV{N,Z} imm. 63:48.  */
+#define R_AARCH64_GOTREL64	307	/* GOT-relative 64-bit.  */
+#define R_AARCH64_GOTREL32	308	/* GOT-relative 32-bit.  */
+#define R_AARCH64_GOT_LD_PREL19	309	/* PC-rel. GOT off. load imm. 20:2.  */
+#define R_AARCH64_LD64_GOTOFF_LO15 310	/* GOT-rel. off. LD/ST imm. 14:3.  */
+#define R_AARCH64_ADR_GOT_PAGE	311	/* P-page-rel. GOT off. ADRP 32:12.  */
+#define R_AARCH64_LD64_GOT_LO12_NC 312	/* Dir. GOT off. LD/ST imm. 11:3.  */
+#define R_AARCH64_LD64_GOTPAGE_LO15 313	/* GOT-page-rel. GOT off. LD/ST 14:3 */
+#define R_AARCH64_TLSGD_ADR_PREL21 512	/* PC-relative ADR imm. 20:0.  */
+#define R_AARCH64_TLSGD_ADR_PAGE21 513	/* page-rel. ADRP imm. 32:12.  */
+#define R_AARCH64_TLSGD_ADD_LO12_NC 514	/* direct ADD imm. from 11:0.  */
+#define R_AARCH64_TLSGD_MOVW_G1	515	/* GOT-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSGD_MOVW_G0_NC 516	/* GOT-rel. MOVK imm. 15:0.  */
+#define R_AARCH64_TLSLD_ADR_PREL21 517	/* Like 512; local dynamic model.  */
+#define R_AARCH64_TLSLD_ADR_PAGE21 518	/* Like 513; local dynamic model.  */
+#define R_AARCH64_TLSLD_ADD_LO12_NC 519	/* Like 514; local dynamic model.  */
+#define R_AARCH64_TLSLD_MOVW_G1	520	/* Like 515; local dynamic model.  */
+#define R_AARCH64_TLSLD_MOVW_G0_NC 521	/* Like 516; local dynamic model.  */
+#define R_AARCH64_TLSLD_LD_PREL19 522	/* TLS PC-rel. load imm. 20:2.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0.  */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check.  */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0.  */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1.  */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2.  */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3.  */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check.  */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0.  */
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12.  */
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3.  */
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12.  */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0.  */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check.  */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0.  */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1.  */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check.  */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2.  */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check.  */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3.  */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check.  */
+#define R_AARCH64_TLSDESC_LD_PREL19 560	/* PC-rel. load immediate 20:2.  */
+#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0.  */
+#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12.  */
+#define R_AARCH64_TLSDESC_LD64_LO12 563	/* Direct LD off. from 11:3.  */
+#define R_AARCH64_TLSDESC_ADD_LO12 564	/* Direct ADD imm. from 11:0.  */
+#define R_AARCH64_TLSDESC_OFF_G1 565	/* GOT-rel. MOV{N,Z} imm. 31:16.  */
+#define R_AARCH64_TLSDESC_OFF_G0_NC 566	/* GOT-rel. MOVK imm. 15:0; no ck.  */
+#define R_AARCH64_TLSDESC_LDR	567	/* Relax LDR.  */
+#define R_AARCH64_TLSDESC_ADD	568	/* Relax ADD.  */
+#define R_AARCH64_TLSDESC_CALL	569	/* Relax BLR.  */
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4.  */
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check.  */
+#define R_AARCH64_COPY         1024	/* Copy symbol at runtime.  */
+#define R_AARCH64_GLOB_DAT     1025	/* Create GOT entry.  */
+#define R_AARCH64_JUMP_SLOT    1026	/* Create PLT entry.  */
+#define R_AARCH64_RELATIVE     1027	/* Adjust by program base.  */
+#define R_AARCH64_TLS_DTPMOD   1028	/* Module number, 64 bit.  */
+#define R_AARCH64_TLS_DTPREL   1029	/* Module-relative offset, 64 bit.  */
+#define R_AARCH64_TLS_TPREL    1030	/* TP-relative offset, 64 bit.  */
+#define R_AARCH64_TLSDESC      1031	/* TLS Descriptor.  */
+#define R_AARCH64_IRELATIVE	1032	/* STT_GNU_IFUNC relocation.  */
+
+/* ARM relocs.  */
+
+#define R_ARM_NONE		0	/* No reloc */
+#define R_ARM_PC24		1	/* Deprecated 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	/* Direct & 0x7C (LDR, STR).  */
+#define R_ARM_ABS8		8	/* Direct 8 bit */
+#define R_ARM_SBREL32		9
+#define R_ARM_THM_PC22		10	/* PC relative 24 bit (Thumb32 BL).  */
+#define R_ARM_THM_PC8		11	/* PC relative & 0x3FC
+					   (Thumb16 LDR, ADD, ADR).  */
+#define R_ARM_AMP_VCALL9	12
+#define R_ARM_SWI24		13	/* Obsolete static relocation.  */
+#define R_ARM_TLS_DESC		13      /* Dynamic relocation.  */
+#define R_ARM_THM_SWI8		14	/* Reserved.  */
+#define R_ARM_XPC25		15	/* Reserved.  */
+#define R_ARM_THM_XPC22		16	/* Reserved.  */
+#define R_ARM_TLS_DTPMOD32	17	/* ID of module containing symbol */
+#define R_ARM_TLS_DTPOFF32	18	/* Offset in TLS block */
+#define R_ARM_TLS_TPOFF32	19	/* Offset in static TLS block */
+#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	/* Deprecated, 32 bit PLT address.  */
+#define R_ARM_CALL		28	/* PC relative 24 bit (BL, BLX).  */
+#define R_ARM_JUMP24		29	/* PC relative 24 bit
+					   (B, BL<cond>).  */
+#define R_ARM_THM_JUMP24	30	/* PC relative 24 bit (Thumb32 B.W).  */
+#define R_ARM_BASE_ABS		31	/* Adjust by program base.  */
+#define R_ARM_ALU_PCREL_7_0	32	/* Obsolete.  */
+#define R_ARM_ALU_PCREL_15_8	33	/* Obsolete.  */
+#define R_ARM_ALU_PCREL_23_15	34	/* Obsolete.  */
+#define R_ARM_LDR_SBREL_11_0	35	/* Deprecated, prog. base relative.  */
+#define R_ARM_ALU_SBREL_19_12	36	/* Deprecated, prog. base relative.  */
+#define R_ARM_ALU_SBREL_27_20	37	/* Deprecated, prog. base relative.  */
+#define R_ARM_TARGET1		38
+#define R_ARM_SBREL31		39	/* Program base relative.  */
+#define R_ARM_V4BX		40
+#define R_ARM_TARGET2		41
+#define R_ARM_PREL31		42	/* 32 bit PC relative.  */
+#define R_ARM_MOVW_ABS_NC	43	/* Direct 16-bit (MOVW).  */
+#define R_ARM_MOVT_ABS		44	/* Direct high 16-bit (MOVT).  */
+#define R_ARM_MOVW_PREL_NC	45	/* PC relative 16-bit (MOVW).  */
+#define R_ARM_MOVT_PREL		46	/* PC relative (MOVT).  */
+#define R_ARM_THM_MOVW_ABS_NC	47	/* Direct 16 bit (Thumb32 MOVW).  */
+#define R_ARM_THM_MOVT_ABS	48	/* Direct high 16 bit
+					   (Thumb32 MOVT).  */
+#define R_ARM_THM_MOVW_PREL_NC	49	/* PC relative 16 bit
+					   (Thumb32 MOVW).  */
+#define R_ARM_THM_MOVT_PREL	50	/* PC relative high 16 bit
+					   (Thumb32 MOVT).  */
+#define R_ARM_THM_JUMP19	51	/* PC relative 20 bit
+					   (Thumb32 B<cond>.W).  */
+#define R_ARM_THM_JUMP6		52	/* PC relative X & 0x7E
+					   (Thumb16 CBZ, CBNZ).  */
+#define R_ARM_THM_ALU_PREL_11_0	53	/* PC relative 12 bit
+					   (Thumb32 ADR.W).  */
+#define R_ARM_THM_PC12		54	/* PC relative 12 bit
+					   (Thumb32 LDR{D,SB,H,SH}).  */
+#define R_ARM_ABS32_NOI		55	/* Direct 32-bit.  */
+#define R_ARM_REL32_NOI		56	/* PC relative 32-bit.  */
+#define R_ARM_ALU_PC_G0_NC	57	/* PC relative (ADD, SUB).  */
+#define R_ARM_ALU_PC_G0		58	/* PC relative (ADD, SUB).  */
+#define R_ARM_ALU_PC_G1_NC	59	/* PC relative (ADD, SUB).  */
+#define R_ARM_ALU_PC_G1		60	/* PC relative (ADD, SUB).  */
+#define R_ARM_ALU_PC_G2		61	/* PC relative (ADD, SUB).  */
+#define R_ARM_LDR_PC_G1		62	/* PC relative (LDR,STR,LDRB,STRB).  */
+#define R_ARM_LDR_PC_G2		63	/* PC relative (LDR,STR,LDRB,STRB).  */
+#define R_ARM_LDRS_PC_G0	64	/* PC relative (STR{D,H},
+					   LDR{D,SB,H,SH}).  */
+#define R_ARM_LDRS_PC_G1	65	/* PC relative (STR{D,H},
+					   LDR{D,SB,H,SH}).  */
+#define R_ARM_LDRS_PC_G2	66	/* PC relative (STR{D,H},
+					   LDR{D,SB,H,SH}).  */
+#define R_ARM_LDC_PC_G0		67	/* PC relative (LDC, STC).  */
+#define R_ARM_LDC_PC_G1		68	/* PC relative (LDC, STC).  */
+#define R_ARM_LDC_PC_G2		69	/* PC relative (LDC, STC).  */
+#define R_ARM_ALU_SB_G0_NC	70	/* Program base relative (ADD,SUB).  */
+#define R_ARM_ALU_SB_G0		71	/* Program base relative (ADD,SUB).  */
+#define R_ARM_ALU_SB_G1_NC	72	/* Program base relative (ADD,SUB).  */
+#define R_ARM_ALU_SB_G1		73	/* Program base relative (ADD,SUB).  */
+#define R_ARM_ALU_SB_G2		74	/* Program base relative (ADD,SUB).  */
+#define R_ARM_LDR_SB_G0		75	/* Program base relative (LDR,
+					   STR, LDRB, STRB).  */
+#define R_ARM_LDR_SB_G1		76	/* Program base relative
+					   (LDR, STR, LDRB, STRB).  */
+#define R_ARM_LDR_SB_G2		77	/* Program base relative
+					   (LDR, STR, LDRB, STRB).  */
+#define R_ARM_LDRS_SB_G0	78	/* Program base relative
+					   (LDR, STR, LDRB, STRB).  */
+#define R_ARM_LDRS_SB_G1	79	/* Program base relative
+					   (LDR, STR, LDRB, STRB).  */
+#define R_ARM_LDRS_SB_G2	80	/* Program base relative
+					   (LDR, STR, LDRB, STRB).  */
+#define R_ARM_LDC_SB_G0		81	/* Program base relative (LDC,STC).  */
+#define R_ARM_LDC_SB_G1		82	/* Program base relative (LDC,STC).  */
+#define R_ARM_LDC_SB_G2		83	/* Program base relative (LDC,STC).  */
+#define R_ARM_MOVW_BREL_NC	84	/* Program base relative 16
+					   bit (MOVW).  */
+#define R_ARM_MOVT_BREL		85	/* Program base relative high
+					   16 bit (MOVT).  */
+#define R_ARM_MOVW_BREL		86	/* Program base relative 16
+					   bit (MOVW).  */
+#define R_ARM_THM_MOVW_BREL_NC	87	/* Program base relative 16
+					   bit (Thumb32 MOVW).  */
+#define R_ARM_THM_MOVT_BREL	88	/* Program base relative high
+					   16 bit (Thumb32 MOVT).  */
+#define R_ARM_THM_MOVW_BREL	89	/* Program base relative 16
+					   bit (Thumb32 MOVW).  */
+#define R_ARM_TLS_GOTDESC	90
+#define R_ARM_TLS_CALL		91
+#define R_ARM_TLS_DESCSEQ	92	/* TLS relaxation.  */
+#define R_ARM_THM_TLS_CALL	93
+#define R_ARM_PLT32_ABS		94
+#define R_ARM_GOT_ABS		95	/* GOT entry.  */
+#define R_ARM_GOT_PREL		96	/* PC relative GOT entry.  */
+#define R_ARM_GOT_BREL12	97	/* GOT entry relative to GOT
+					   origin (LDR).  */
+#define R_ARM_GOTOFF12		98	/* 12 bit, GOT entry relative
+					   to GOT origin (LDR, STR).  */
+#define R_ARM_GOTRELAX		99
+#define R_ARM_GNU_VTENTRY	100
+#define R_ARM_GNU_VTINHERIT	101
+#define R_ARM_THM_PC11		102	/* PC relative & 0xFFE (Thumb16 B).  */
+#define R_ARM_THM_PC9		103	/* PC relative & 0x1FE
+					   (Thumb16 B/B<cond>).  */
+#define R_ARM_TLS_GD32		104	/* PC-rel 32 bit for global dynamic
+					   thread local data */
+#define R_ARM_TLS_LDM32		105	/* PC-rel 32 bit for local dynamic
+					   thread local data */
+#define R_ARM_TLS_LDO32		106	/* 32 bit offset relative to TLS
+					   block */
+#define R_ARM_TLS_IE32		107	/* PC-rel 32 bit for GOT entry of
+					   static TLS block offset */
+#define R_ARM_TLS_LE32		108	/* 32 bit offset relative to static
+					   TLS block */
+#define R_ARM_TLS_LDO12		109	/* 12 bit relative to TLS
+					   block (LDR, STR).  */
+#define R_ARM_TLS_LE12		110	/* 12 bit relative to static
+					   TLS block (LDR, STR).  */
+#define R_ARM_TLS_IE12GP	111	/* 12 bit GOT entry relative
+					   to GOT origin (LDR).  */
+#define R_ARM_ME_TOO		128	/* Obsolete.  */
+#define R_ARM_THM_TLS_DESCSEQ	129
+#define R_ARM_THM_TLS_DESCSEQ16	129
+#define R_ARM_THM_TLS_DESCSEQ32	130
+#define R_ARM_THM_GOT_BREL12	131	/* GOT entry relative to GOT
+					   origin, 12 bit (Thumb32 LDR).  */
+#define R_ARM_IRELATIVE		160
+#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 */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+#define EF_SH_MACH_MASK		0x1f
+#define EF_SH_UNKNOWN		0x0
+#define EF_SH1			0x1
+#define EF_SH2			0x2
+#define EF_SH3			0x3
+#define EF_SH_DSP		0x4
+#define EF_SH3_DSP		0x5
+#define EF_SH4AL_DSP		0x6
+#define EF_SH3E			0x8
+#define EF_SH4			0x9
+#define EF_SH2E			0xb
+#define EF_SH4A			0xc
+#define EF_SH2A			0xd
+#define EF_SH4_NOFPU		0x10
+#define EF_SH4A_NOFPU		0x11
+#define EF_SH4_NOMMU_NOFPU	0x12
+#define EF_SH2A_NOFPU		0x13
+#define EF_SH3_NOMMU		0x14
+#define EF_SH2A_SH4_NOFPU	0x15
+#define EF_SH2A_SH3_NOFPU	0x16
+#define EF_SH2A_SH4		0x17
+#define EF_SH2A_SH3E		0x18
+
+/* 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
+
+/* S/390 specific definitions.  */
+
+/* Valid values for the e_flags field.  */
+
+#define EF_S390_HIGH_GPRS    0x00000001  /* High GPRs kernel facility needed.  */
+
+/* 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.  */
+#define R_390_IRELATIVE         61      /* STT_GNU_IFUNC relocation.  */
+/* Keep this the last entry.  */
+#define R_390_NUM		62
+
+
+/* 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_PC64		24	/* PC relative 64 bit */
+#define R_X86_64_GOTOFF64	25	/* 64 bit offset to GOT */
+#define R_X86_64_GOTPC32	26	/* 32 bit signed pc relative
+					   offset to GOT */
+#define R_X86_64_GOT64		27	/* 64-bit GOT entry offset */
+#define R_X86_64_GOTPCREL64	28	/* 64-bit PC relative offset
+					   to GOT entry */
+#define R_X86_64_GOTPC64	29	/* 64-bit PC relative offset to GOT */
+#define R_X86_64_GOTPLT64	30 	/* like GOT64, says PLT entry needed */
+#define R_X86_64_PLTOFF64	31	/* 64-bit GOT relative offset
+					   to PLT entry */
+#define R_X86_64_SIZE32		32	/* Size of symbol plus 32-bit addend */
+#define R_X86_64_SIZE64		33	/* Size of symbol plus 64-bit addend */
+#define R_X86_64_GOTPC32_TLSDESC 34	/* GOT offset for TLS descriptor.  */
+#define R_X86_64_TLSDESC_CALL   35	/* Marker for call through TLS
+					   descriptor.  */
+#define R_X86_64_TLSDESC        36	/* TLS descriptor.  */
+#define R_X86_64_IRELATIVE	37	/* Adjust indirectly by program base */
+#define R_X86_64_RELATIVE64	38	/* 64-bit adjust by program base */
+					/* 39 Reserved was R_X86_64_PC32_BND */
+					/* 40 Reserved was R_X86_64_PLT32_BND */
+#define R_X86_64_GOTPCRELX	41	/* Load from 32 bit signed pc relative
+					   offset to GOT entry without REX
+					   prefix, relaxable.  */
+#define R_X86_64_REX_GOTPCRELX	42	/* Load from 32 bit signed pc relative
+					   offset to GOT entry with REX prefix,
+					   relaxable.  */
+#define R_X86_64_NUM		43
+
+
+/* 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_TLS_GD	24	/* 32-bit offset for global dynamic.  */
+#define R_MN10300_TLS_LD	25	/* 32-bit offset for local dynamic.  */
+#define R_MN10300_TLS_LDO	26	/* Module-relative offset.  */
+#define R_MN10300_TLS_GOTIE	27	/* GOT offset for static TLS block
+					   offset.  */
+#define R_MN10300_TLS_IE	28	/* GOT address for static TLS block
+					   offset.  */
+#define R_MN10300_TLS_LE	29	/* Offset relative to static TLS
+					   block.  */
+#define R_MN10300_TLS_DTPMOD	30	/* ID of module containing symbol.  */
+#define R_MN10300_TLS_DTPOFF	31	/* Offset in module TLS block.  */
+#define R_MN10300_TLS_TPOFF	32	/* Offset in static TLS block.  */
+#define R_MN10300_SYM_DIFF	33	/* Adjustment for next reloc as needed
+					   by linker relaxation.  */
+#define R_MN10300_ALIGN		34	/* Alignment requirement for linker
+					   relaxation.  */
+#define R_MN10300_NUM		35
+
+
+/* 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_REL32		45	/* PC relative 32 bit.  */
+
+#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. */
+
+/* MicroBlaze relocations */
+#define R_MICROBLAZE_NONE		0	/* No reloc. */
+#define R_MICROBLAZE_32 		1	/* Direct 32 bit. */
+#define R_MICROBLAZE_32_PCREL		2	/* PC relative 32 bit. */
+#define R_MICROBLAZE_64_PCREL		3	/* PC relative 64 bit. */
+#define R_MICROBLAZE_32_PCREL_LO	4	/* Low 16 bits of PCREL32. */
+#define R_MICROBLAZE_64 		5	/* Direct 64 bit. */
+#define R_MICROBLAZE_32_LO		6	/* Low 16 bit. */
+#define R_MICROBLAZE_SRO32		7	/* Read-only small data area. */
+#define R_MICROBLAZE_SRW32		8	/* Read-write small data area. */
+#define R_MICROBLAZE_64_NONE		9	/* No reloc. */
+#define R_MICROBLAZE_32_SYM_OP_SYM	10	/* Symbol Op Symbol relocation. */
+#define R_MICROBLAZE_GNU_VTINHERIT	11	/* GNU C++ vtable hierarchy. */
+#define R_MICROBLAZE_GNU_VTENTRY	12	/* GNU C++ vtable member usage. */
+#define R_MICROBLAZE_GOTPC_64		13	/* PC-relative GOT offset.  */
+#define R_MICROBLAZE_GOT_64		14	/* GOT entry offset.  */
+#define R_MICROBLAZE_PLT_64		15	/* PLT offset (PC-relative).  */
+#define R_MICROBLAZE_REL		16	/* Adjust by program base.  */
+#define R_MICROBLAZE_JUMP_SLOT		17	/* Create PLT entry.  */
+#define R_MICROBLAZE_GLOB_DAT		18	/* Create GOT entry.  */
+#define R_MICROBLAZE_GOTOFF_64		19	/* 64 bit offset to GOT. */
+#define R_MICROBLAZE_GOTOFF_32		20	/* 32 bit offset to GOT. */
+#define R_MICROBLAZE_COPY		21	/* Runtime copy.  */
+#define R_MICROBLAZE_TLS		22	/* TLS Reloc. */
+#define R_MICROBLAZE_TLSGD		23	/* TLS General Dynamic. */
+#define R_MICROBLAZE_TLSLD		24	/* TLS Local Dynamic. */
+#define R_MICROBLAZE_TLSDTPMOD32	25	/* TLS Module ID. */
+#define R_MICROBLAZE_TLSDTPREL32	26	/* TLS Offset Within TLS Block. */
+#define R_MICROBLAZE_TLSDTPREL64	27	/* TLS Offset Within TLS Block. */
+#define R_MICROBLAZE_TLSGOTTPREL32	28	/* TLS Offset From Thread Pointer. */
+#define R_MICROBLAZE_TLSTPREL32 	29	/* TLS Offset From Thread Pointer. */
+
+/* Legal values for d_tag (dynamic entry type).  */
+#define DT_NIOS2_GP             0x70000002 /* Address of _gp.  */
+
+/* Nios II relocations.  */
+#define R_NIOS2_NONE		0	/* No reloc.  */
+#define R_NIOS2_S16		1	/* Direct signed 16 bit.  */
+#define R_NIOS2_U16		2	/* Direct unsigned 16 bit.  */
+#define R_NIOS2_PCREL16		3	/* PC relative 16 bit.  */
+#define R_NIOS2_CALL26		4	/* Direct call.  */
+#define R_NIOS2_IMM5		5	/* 5 bit constant expression.  */
+#define R_NIOS2_CACHE_OPX	6	/* 5 bit expression, shift 22.  */
+#define R_NIOS2_IMM6		7	/* 6 bit constant expression.  */
+#define R_NIOS2_IMM8		8	/* 8 bit constant expression.  */
+#define R_NIOS2_HI16		9	/* High 16 bit.  */
+#define R_NIOS2_LO16		10	/* Low 16 bit.  */
+#define R_NIOS2_HIADJ16		11	/* High 16 bit, adjusted.  */
+#define R_NIOS2_BFD_RELOC_32	12	/* 32 bit symbol value + addend.  */
+#define R_NIOS2_BFD_RELOC_16	13	/* 16 bit symbol value + addend.  */
+#define R_NIOS2_BFD_RELOC_8	14	/* 8 bit symbol value + addend.  */
+#define R_NIOS2_GPREL		15	/* 16 bit GP pointer offset.  */
+#define R_NIOS2_GNU_VTINHERIT	16	/* GNU C++ vtable hierarchy.  */
+#define R_NIOS2_GNU_VTENTRY	17	/* GNU C++ vtable member usage.  */
+#define R_NIOS2_UJMP		18	/* Unconditional branch.  */
+#define R_NIOS2_CJMP		19	/* Conditional branch.  */
+#define R_NIOS2_CALLR		20	/* Indirect call through register.  */
+#define R_NIOS2_ALIGN		21	/* Alignment requirement for
+					   linker relaxation.  */
+#define R_NIOS2_GOT16		22	/* 16 bit GOT entry.  */
+#define R_NIOS2_CALL16		23	/* 16 bit GOT entry for function.  */
+#define R_NIOS2_GOTOFF_LO	24	/* %lo of offset to GOT pointer.  */
+#define R_NIOS2_GOTOFF_HA	25	/* %hiadj of offset to GOT pointer.  */
+#define R_NIOS2_PCREL_LO	26	/* %lo of PC relative offset.  */
+#define R_NIOS2_PCREL_HA	27	/* %hiadj of PC relative offset.  */
+#define R_NIOS2_TLS_GD16	28	/* 16 bit GOT offset for TLS GD.  */
+#define R_NIOS2_TLS_LDM16	29	/* 16 bit GOT offset for TLS LDM.  */
+#define R_NIOS2_TLS_LDO16	30	/* 16 bit module relative offset.  */
+#define R_NIOS2_TLS_IE16	31	/* 16 bit GOT offset for TLS IE.  */
+#define R_NIOS2_TLS_LE16	32	/* 16 bit LE TP-relative offset.  */
+#define R_NIOS2_TLS_DTPMOD	33	/* Module number.  */
+#define R_NIOS2_TLS_DTPREL	34	/* Module-relative offset.  */
+#define R_NIOS2_TLS_TPREL	35	/* TP-relative offset.  */
+#define R_NIOS2_COPY		36	/* Copy symbol at runtime.  */
+#define R_NIOS2_GLOB_DAT	37	/* Create GOT entry.  */
+#define R_NIOS2_JUMP_SLOT	38	/* Create PLT entry.  */
+#define R_NIOS2_RELATIVE	39	/* Adjust by program base.  */
+#define R_NIOS2_GOTOFF		40	/* 16 bit offset to GOT pointer.  */
+#define R_NIOS2_CALL26_NOAT	41	/* Direct call in .noat section.  */
+#define R_NIOS2_GOT_LO		42	/* %lo() of GOT entry.  */
+#define R_NIOS2_GOT_HA		43	/* %hiadj() of GOT entry.  */
+#define R_NIOS2_CALL_LO		44	/* %lo() of function GOT entry.  */
+#define R_NIOS2_CALL_HA		45	/* %hiadj() of function GOT entry.  */
+
+/* TILEPro relocations.  */
+#define R_TILEPRO_NONE		0	/* No reloc */
+#define R_TILEPRO_32		1	/* Direct 32 bit */
+#define R_TILEPRO_16		2	/* Direct 16 bit */
+#define R_TILEPRO_8		3	/* Direct 8 bit */
+#define R_TILEPRO_32_PCREL	4	/* PC relative 32 bit */
+#define R_TILEPRO_16_PCREL	5	/* PC relative 16 bit */
+#define R_TILEPRO_8_PCREL	6	/* PC relative 8 bit */
+#define R_TILEPRO_LO16		7	/* Low 16 bit */
+#define R_TILEPRO_HI16		8	/* High 16 bit */
+#define R_TILEPRO_HA16		9	/* High 16 bit, adjusted */
+#define R_TILEPRO_COPY		10	/* Copy relocation */
+#define R_TILEPRO_GLOB_DAT	11	/* Create GOT entry */
+#define R_TILEPRO_JMP_SLOT	12	/* Create PLT entry */
+#define R_TILEPRO_RELATIVE	13	/* Adjust by program base */
+#define R_TILEPRO_BROFF_X1	14	/* X1 pipe branch offset */
+#define R_TILEPRO_JOFFLONG_X1	15	/* X1 pipe jump offset */
+#define R_TILEPRO_JOFFLONG_X1_PLT 16	/* X1 pipe jump offset to PLT */
+#define R_TILEPRO_IMM8_X0	17	/* X0 pipe 8-bit */
+#define R_TILEPRO_IMM8_Y0	18	/* Y0 pipe 8-bit */
+#define R_TILEPRO_IMM8_X1	19	/* X1 pipe 8-bit */
+#define R_TILEPRO_IMM8_Y1	20	/* Y1 pipe 8-bit */
+#define R_TILEPRO_MT_IMM15_X1	21	/* X1 pipe mtspr */
+#define R_TILEPRO_MF_IMM15_X1	22	/* X1 pipe mfspr */
+#define R_TILEPRO_IMM16_X0	23	/* X0 pipe 16-bit */
+#define R_TILEPRO_IMM16_X1	24	/* X1 pipe 16-bit */
+#define R_TILEPRO_IMM16_X0_LO	25	/* X0 pipe low 16-bit */
+#define R_TILEPRO_IMM16_X1_LO	26	/* X1 pipe low 16-bit */
+#define R_TILEPRO_IMM16_X0_HI	27	/* X0 pipe high 16-bit */
+#define R_TILEPRO_IMM16_X1_HI	28	/* X1 pipe high 16-bit */
+#define R_TILEPRO_IMM16_X0_HA	29	/* X0 pipe high 16-bit, adjusted */
+#define R_TILEPRO_IMM16_X1_HA	30	/* X1 pipe high 16-bit, adjusted */
+#define R_TILEPRO_IMM16_X0_PCREL 31	/* X0 pipe PC relative 16 bit */
+#define R_TILEPRO_IMM16_X1_PCREL 32	/* X1 pipe PC relative 16 bit */
+#define R_TILEPRO_IMM16_X0_LO_PCREL 33	/* X0 pipe PC relative low 16 bit */
+#define R_TILEPRO_IMM16_X1_LO_PCREL 34	/* X1 pipe PC relative low 16 bit */
+#define R_TILEPRO_IMM16_X0_HI_PCREL 35	/* X0 pipe PC relative high 16 bit */
+#define R_TILEPRO_IMM16_X1_HI_PCREL 36	/* X1 pipe PC relative high 16 bit */
+#define R_TILEPRO_IMM16_X0_HA_PCREL 37	/* X0 pipe PC relative ha() 16 bit */
+#define R_TILEPRO_IMM16_X1_HA_PCREL 38	/* X1 pipe PC relative ha() 16 bit */
+#define R_TILEPRO_IMM16_X0_GOT	39	/* X0 pipe 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT	40	/* X1 pipe 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_LO 41	/* X0 pipe low 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_LO 42	/* X1 pipe low 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_HI 43	/* X0 pipe high 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_HI 44	/* X1 pipe high 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_HA 45	/* X0 pipe ha() 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_HA 46	/* X1 pipe ha() 16-bit GOT offset */
+#define R_TILEPRO_MMSTART_X0	47	/* X0 pipe mm "start" */
+#define R_TILEPRO_MMEND_X0	48	/* X0 pipe mm "end" */
+#define R_TILEPRO_MMSTART_X1	49	/* X1 pipe mm "start" */
+#define R_TILEPRO_MMEND_X1	50	/* X1 pipe mm "end" */
+#define R_TILEPRO_SHAMT_X0	51	/* X0 pipe shift amount */
+#define R_TILEPRO_SHAMT_X1	52	/* X1 pipe shift amount */
+#define R_TILEPRO_SHAMT_Y0	53	/* Y0 pipe shift amount */
+#define R_TILEPRO_SHAMT_Y1	54	/* Y1 pipe shift amount */
+#define R_TILEPRO_DEST_IMM8_X1	55	/* X1 pipe destination 8-bit */
+/* Relocs 56-59 are currently not defined.  */
+#define R_TILEPRO_TLS_GD_CALL	60	/* "jal" for TLS GD */
+#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61	/* X0 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62	/* X1 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63	/* Y0 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64	/* Y1 pipe "addi" for TLS GD */
+#define R_TILEPRO_TLS_IE_LOAD	65	/* "lw_tls" for TLS IE */
+#define R_TILEPRO_IMM16_X0_TLS_GD 66	/* X0 pipe 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD 67	/* X1 pipe 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68	/* X0 pipe low 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69	/* X1 pipe low 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70	/* X0 pipe high 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71	/* X1 pipe high 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72	/* X0 pipe ha() 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73	/* X1 pipe ha() 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE 74	/* X0 pipe 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE 75	/* X1 pipe 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76	/* X0 pipe low 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77	/* X1 pipe low 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78	/* X0 pipe high 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79	/* X1 pipe high 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80	/* X0 pipe ha() 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81	/* X1 pipe ha() 16-bit TLS IE offset */
+#define R_TILEPRO_TLS_DTPMOD32	82	/* ID of module containing symbol */
+#define R_TILEPRO_TLS_DTPOFF32	83	/* Offset in TLS block */
+#define R_TILEPRO_TLS_TPOFF32	84	/* Offset in static TLS block */
+#define R_TILEPRO_IMM16_X0_TLS_LE 85	/* X0 pipe 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE 86	/* X1 pipe 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87	/* X0 pipe low 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88	/* X1 pipe low 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89	/* X0 pipe high 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90	/* X1 pipe high 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91	/* X0 pipe ha() 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92	/* X1 pipe ha() 16-bit TLS LE offset */
+
+#define R_TILEPRO_GNU_VTINHERIT	128	/* GNU C++ vtable hierarchy */
+#define R_TILEPRO_GNU_VTENTRY	129	/* GNU C++ vtable member usage */
+
+#define R_TILEPRO_NUM		130
+
+
+/* TILE-Gx relocations.  */
+#define R_TILEGX_NONE		0	/* No reloc */
+#define R_TILEGX_64		1	/* Direct 64 bit */
+#define R_TILEGX_32		2	/* Direct 32 bit */
+#define R_TILEGX_16		3	/* Direct 16 bit */
+#define R_TILEGX_8		4	/* Direct 8 bit */
+#define R_TILEGX_64_PCREL	5	/* PC relative 64 bit */
+#define R_TILEGX_32_PCREL	6	/* PC relative 32 bit */
+#define R_TILEGX_16_PCREL	7	/* PC relative 16 bit */
+#define R_TILEGX_8_PCREL	8	/* PC relative 8 bit */
+#define R_TILEGX_HW0		9	/* hword 0 16-bit */
+#define R_TILEGX_HW1		10	/* hword 1 16-bit */
+#define R_TILEGX_HW2		11	/* hword 2 16-bit */
+#define R_TILEGX_HW3		12	/* hword 3 16-bit */
+#define R_TILEGX_HW0_LAST	13	/* last hword 0 16-bit */
+#define R_TILEGX_HW1_LAST	14	/* last hword 1 16-bit */
+#define R_TILEGX_HW2_LAST	15	/* last hword 2 16-bit */
+#define R_TILEGX_COPY		16	/* Copy relocation */
+#define R_TILEGX_GLOB_DAT	17	/* Create GOT entry */
+#define R_TILEGX_JMP_SLOT	18	/* Create PLT entry */
+#define R_TILEGX_RELATIVE	19	/* Adjust by program base */
+#define R_TILEGX_BROFF_X1	20	/* X1 pipe branch offset */
+#define R_TILEGX_JUMPOFF_X1	21	/* X1 pipe jump offset */
+#define R_TILEGX_JUMPOFF_X1_PLT	22	/* X1 pipe jump offset to PLT */
+#define R_TILEGX_IMM8_X0	23	/* X0 pipe 8-bit */
+#define R_TILEGX_IMM8_Y0	24	/* Y0 pipe 8-bit */
+#define R_TILEGX_IMM8_X1	25	/* X1 pipe 8-bit */
+#define R_TILEGX_IMM8_Y1	26	/* Y1 pipe 8-bit */
+#define R_TILEGX_DEST_IMM8_X1	27	/* X1 pipe destination 8-bit */
+#define R_TILEGX_MT_IMM14_X1	28	/* X1 pipe mtspr */
+#define R_TILEGX_MF_IMM14_X1	29	/* X1 pipe mfspr */
+#define R_TILEGX_MMSTART_X0	30	/* X0 pipe mm "start" */
+#define R_TILEGX_MMEND_X0	31	/* X0 pipe mm "end" */
+#define R_TILEGX_SHAMT_X0	32	/* X0 pipe shift amount */
+#define R_TILEGX_SHAMT_X1	33	/* X1 pipe shift amount */
+#define R_TILEGX_SHAMT_Y0	34	/* Y0 pipe shift amount */
+#define R_TILEGX_SHAMT_Y1	35	/* Y1 pipe shift amount */
+#define R_TILEGX_IMM16_X0_HW0	36	/* X0 pipe hword 0 */
+#define R_TILEGX_IMM16_X1_HW0	37	/* X1 pipe hword 0 */
+#define R_TILEGX_IMM16_X0_HW1	38	/* X0 pipe hword 1 */
+#define R_TILEGX_IMM16_X1_HW1	39	/* X1 pipe hword 1 */
+#define R_TILEGX_IMM16_X0_HW2	40	/* X0 pipe hword 2 */
+#define R_TILEGX_IMM16_X1_HW2	41	/* X1 pipe hword 2 */
+#define R_TILEGX_IMM16_X0_HW3	42	/* X0 pipe hword 3 */
+#define R_TILEGX_IMM16_X1_HW3	43	/* X1 pipe hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_LAST 44	/* X0 pipe last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST 45	/* X1 pipe last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST 46	/* X0 pipe last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST 47	/* X1 pipe last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST 48	/* X0 pipe last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST 49	/* X1 pipe last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_PCREL 50	/* X0 pipe PC relative hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_PCREL 51	/* X1 pipe PC relative hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_PCREL 52	/* X0 pipe PC relative hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_PCREL 53	/* X1 pipe PC relative hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_PCREL 54	/* X0 pipe PC relative hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_PCREL 55	/* X1 pipe PC relative hword 2 */
+#define R_TILEGX_IMM16_X0_HW3_PCREL 56	/* X0 pipe PC relative hword 3 */
+#define R_TILEGX_IMM16_X1_HW3_PCREL 57	/* X1 pipe PC relative hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_GOT 64	/* X0 pipe hword 0 GOT offset */
+#define R_TILEGX_IMM16_X1_HW0_GOT 65	/* X1 pipe hword 0 GOT offset */
+#define R_TILEGX_IMM16_X0_HW0_PLT_PCREL 66 /* X0 pipe PC-rel PLT hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_PLT_PCREL 67 /* X1 pipe PC-rel PLT hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_PLT_PCREL 68 /* X0 pipe PC-rel PLT hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_PLT_PCREL 69 /* X1 pipe PC-rel PLT hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_PLT_PCREL 70 /* X0 pipe PC-rel PLT hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_PLT_PCREL 71 /* X1 pipe PC-rel PLT hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */
+#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */
+#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */
+#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */
+#define R_TILEGX_IMM16_X0_HW3_PLT_PCREL 76 /* X0 pipe PC-rel PLT hword 3 */
+#define R_TILEGX_IMM16_X1_HW3_PLT_PCREL 77 /* X1 pipe PC-rel PLT hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78	/* X0 pipe hword 0 TLS GD offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79	/* X1 pipe hword 0 TLS GD offset */
+#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80	/* X0 pipe hword 0 TLS LE offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81	/* X1 pipe hword 0 TLS LE offset */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */
+/* Relocs 90-91 are currently not defined.  */
+#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92	/* X0 pipe hword 0 TLS IE offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93	/* X1 pipe hword 0 TLS IE offset */
+#define R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 94 /* X0 pipe PC-rel PLT last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 95 /* X1 pipe PC-rel PLT last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 96 /* X0 pipe PC-rel PLT last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 97 /* X1 pipe PC-rel PLT last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 98 /* X0 pipe PC-rel PLT last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 99 /* X1 pipe PC-rel PLT last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */
+/* Relocs 104-105 are currently not defined.  */
+#define R_TILEGX_TLS_DTPMOD64	106	/* 64-bit ID of symbol's module */
+#define R_TILEGX_TLS_DTPOFF64	107	/* 64-bit offset in TLS block */
+#define R_TILEGX_TLS_TPOFF64	108	/* 64-bit offset in static TLS block */
+#define R_TILEGX_TLS_DTPMOD32	109	/* 32-bit ID of symbol's module */
+#define R_TILEGX_TLS_DTPOFF32	110	/* 32-bit offset in TLS block */
+#define R_TILEGX_TLS_TPOFF32	111	/* 32-bit offset in static TLS block */
+#define R_TILEGX_TLS_GD_CALL	112	/* "jal" for TLS GD */
+#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113	/* X0 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114	/* X1 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115	/* Y0 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116	/* Y1 pipe "addi" for TLS GD */
+#define R_TILEGX_TLS_IE_LOAD	117	/* "ld_tls" for TLS IE */
+#define R_TILEGX_IMM8_X0_TLS_ADD 118	/* X0 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_X1_TLS_ADD 119	/* X1 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_Y0_TLS_ADD 120	/* Y0 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_Y1_TLS_ADD 121	/* Y1 pipe "addi" for TLS GD/IE */
+
+#define R_TILEGX_GNU_VTINHERIT	128	/* GNU C++ vtable hierarchy */
+#define R_TILEGX_GNU_VTENTRY	129	/* GNU C++ vtable member usage */
+
+#define R_TILEGX_NUM		130
+
+/* BPF specific declarations.  */
+
+#define R_BPF_NONE		0	/* No reloc */
+#define R_BPF_MAP_FD		1	/* Map fd to pointer */
+
+/* Imagination Meta specific relocations. */
+
+#define R_METAG_HIADDR16	0
+#define R_METAG_LOADDR16	1
+#define R_METAG_ADDR32		2	/* 32bit absolute address */
+#define R_METAG_NONE		3	/* No reloc */
+#define R_METAG_RELBRANCH	4
+#define R_METAG_GETSETOFF	5
+
+/* Backward compatability */
+#define R_METAG_REG32OP1	6
+#define R_METAG_REG32OP2	7
+#define R_METAG_REG32OP3	8
+#define R_METAG_REG16OP1	9
+#define R_METAG_REG16OP2	10
+#define R_METAG_REG16OP3	11
+#define R_METAG_REG32OP4	12
+
+#define R_METAG_HIOG		13
+#define R_METAG_LOOG		14
+
+#define R_METAG_REL8		15
+#define R_METAG_REL16		16
+
+/* GNU */
+#define R_METAG_GNU_VTINHERIT	30
+#define R_METAG_GNU_VTENTRY	31
+
+/* PIC relocations */
+#define R_METAG_HI16_GOTOFF	32
+#define R_METAG_LO16_GOTOFF	33
+#define R_METAG_GETSET_GOTOFF	34
+#define R_METAG_GETSET_GOT	35
+#define R_METAG_HI16_GOTPC	36
+#define R_METAG_LO16_GOTPC	37
+#define R_METAG_HI16_PLT	38
+#define R_METAG_LO16_PLT	39
+#define R_METAG_RELBRANCH_PLT	40
+#define R_METAG_GOTOFF		41
+#define R_METAG_PLT		42
+#define R_METAG_COPY		43
+#define R_METAG_JMP_SLOT	44
+#define R_METAG_RELATIVE	45
+#define R_METAG_GLOB_DAT	46
+
+/* TLS relocations */
+#define R_METAG_TLS_GD		47
+#define R_METAG_TLS_LDM		48
+#define R_METAG_TLS_LDO_HI16	49
+#define R_METAG_TLS_LDO_LO16	50
+#define R_METAG_TLS_LDO		51
+#define R_METAG_TLS_IE		52
+#define R_METAG_TLS_IENONPIC	53
+#define R_METAG_TLS_IENONPIC_HI16 54
+#define R_METAG_TLS_IENONPIC_LO16 55
+#define R_METAG_TLS_TPOFF	56
+#define R_METAG_TLS_DTPMOD	57
+#define R_METAG_TLS_DTPOFF	58
+#define R_METAG_TLS_LE		59
+#define R_METAG_TLS_LE_HI16	60
+#define R_METAG_TLS_LE_LO16	61
+
+__END_DECLS
+
+#endif	/* elf.h */
diff --git a/libelf/elf32_checksum.c b/libelf/elf32_checksum.c
new file mode 100644
index 0000000..f9dfccb
--- /dev/null
+++ b/libelf/elf32_checksum.c
@@ -0,0 +1,168 @@
+/* Compute simple checksum from permanent parts of the ELF file.
+   Copyright (C) 2002, 2003, 2004, 2005, 2009, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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
+
+
+#define process_block(crc, data) \
+  __libelf_crc32 (crc, data->d_buf, data->d_size)
+
+
+long int
+elfw2(LIBELFBITS,checksum) (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_getshdrstrndx) (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));
+
+  /* If we don't have native byte order, we will likely need to
+     convert the data with xlate functions.  We do it upfront instead
+     of relocking mid-iteration. */
+  if (!likely (same_byte_order))
+    rwlock_wrlock (elf->lock);
+  else
+    rwlock_rdlock (elf->lock);
+
+  /* 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);
+	  result = -1l;
+	  goto out;
+	}
+
+      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)
+	      {
+		result = -1l;
+		goto out;
+	      }
+
+	    result = process_block (result, data);
+
+	    /* And convert it back.  */
+	    if (INTUSE(elfw2(LIBELFBITS,xlatetom)) (data, data, ident[EI_DATA])
+		== NULL)
+	      {
+		result = -1l;
+		goto out;
+	      }
+	  }
+    }
+
+ out:
+  rwlock_unlock (elf->lock);
+  return result;
+}
+INTDEF(elfw2(LIBELFBITS,checksum))
diff --git a/libelf/elf32_fsize.c b/libelf/elf32_fsize.c
new file mode 100644
index 0000000..fddae91
--- /dev/null
+++ b/libelf/elf32_fsize.c
@@ -0,0 +1,68 @@
+/* Return the size of an object file type.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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) (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_getchdr.c b/libelf/elf32_getchdr.c
new file mode 100644
index 0000000..982a614
--- /dev/null
+++ b/libelf/elf32_getchdr.c
@@ -0,0 +1,83 @@
+/* Return section compression header.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include "libelfP.h"
+#include "common.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+ElfW2(LIBELFBITS,Chdr) *
+elfw2(LIBELFBITS,getchdr) (Elf_Scn *scn)
+{
+  ElfW2(LIBELFBITS,Shdr) *shdr = elfw2(LIBELFBITS,getshdr) (scn);
+  if (shdr == NULL)
+    return NULL;
+
+  /* Must have SHF_COMPRESSED flag set.  Allocated or no bits sections
+     can never be compressed.  */
+  if ((shdr->sh_flags & SHF_ALLOC) != 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS);
+      return NULL;
+    }
+
+  if (shdr->sh_type == SHT_NULL
+      || shdr->sh_type == SHT_NOBITS)
+    {
+      __libelf_seterrno (ELF_E_INVALID_SECTION_TYPE);
+      return NULL;
+    }
+
+  if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
+    {
+      __libelf_seterrno (ELF_E_NOT_COMPRESSED);
+      return NULL;
+    }
+
+  /* This makes sure the data is in the correct format, so we don't
+     need to swap fields. */
+  Elf_Data *d  = elf_getdata (scn, NULL);
+  if (d == NULL)
+    return NULL;
+
+  if (d->d_size < sizeof (ElfW2(LIBELFBITS,Chdr)) || d->d_buf == NULL)
+    {
+      __libelf_seterrno (ELF_E_INVALID_DATA);
+      return NULL;
+    }
+
+  return (ElfW2(LIBELFBITS,Chdr) *) d->d_buf;
+}
diff --git a/libelf/elf32_getehdr.c b/libelf/elf32_getehdr.c
new file mode 100644
index 0000000..89e3c40
--- /dev/null
+++ b/libelf/elf32_getehdr.c
@@ -0,0 +1,96 @@
+/* Get ELF header.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+static ElfW2(LIBELFBITS,Ehdr) *
+getehdr_impl (Elf *elf, int wrlock)
+{
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+ again:
+  if (elf->class == 0)
+    {
+      if (!wrlock)
+	{
+	  rwlock_unlock (elf->lock);
+	  rwlock_wrlock (elf->lock);
+	  wrlock = 1;
+	  goto again;
+	}
+      elf->class = ELFW(ELFCLASS,LIBELFBITS);
+    }
+  else if (unlikely (elf->class != ELFW(ELFCLASS,LIBELFBITS)))
+    {
+      __libelf_seterrno (ELF_E_INVALID_CLASS);
+      return NULL;
+    }
+
+  return elf->state.ELFW(elf,LIBELFBITS).ehdr;
+}
+
+ElfW2(LIBELFBITS,Ehdr) *
+internal_function
+__elfw2(LIBELFBITS,getehdr_wrlock) (Elf *elf)
+{
+  return getehdr_impl (elf, 1);
+}
+
+ElfW2(LIBELFBITS,Ehdr) *
+elfw2(LIBELFBITS,getehdr) (Elf *elf)
+{
+  ElfW2(LIBELFBITS,Ehdr) *result;
+  if (elf == NULL)
+    return NULL;
+
+  rwlock_rdlock (elf->lock);
+  result = getehdr_impl (elf, 0);
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/libelf/elf32_getphdr.c b/libelf/elf32_getphdr.c
new file mode 100644
index 0000000..99b4ac0
--- /dev/null
+++ b/libelf/elf32_getphdr.c
@@ -0,0 +1,265 @@
+/* Get ELF program header table.
+   Copyright (C) 1998-2010, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <system.h>
+#include "libelfP.h"
+#include "common.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+ElfW2(LIBELFBITS,Phdr) *
+__elfw2(LIBELFBITS,getphdr_wrlock) (Elf *elf)
+{
+  ElfW2(LIBELFBITS,Phdr) *result;
+
+  /* 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;
+
+  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;
+      if (__elf_getphdrnum_rdlock (elf, &phnum) != 0)
+	goto out;
+      if (phnum == 0 || ehdr->e_phoff == 0)
+	{
+	  __libelf_seterrno (ELF_E_NO_PHDR);
+	  goto out;
+	}
+
+      /* Check this doesn't overflow.  */
+      size_t size = phnum * sizeof (ElfW2(LIBELFBITS,Phdr));
+
+      if (phnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr))
+	  || ehdr->e_phoff > elf->maximum_size
+	  || elf->maximum_size - ehdr->e_phoff < size)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      if (elf->map_address != NULL)
+	{
+	  /* First see whether the information in the ELF header is
+	     valid and it does not ask for too much.  */
+	  if (unlikely (ehdr->e_phoff >= elf->maximum_size)
+	      || unlikely (elf->maximum_size - ehdr->e_phoff < size))
+	    {
+	      /* Something is wrong.  */
+	      __libelf_seterrno (ELF_E_INVALID_PHDR);
+	      goto out;
+	    }
+
+	  /* All the data is already mapped.  Use it.  */
+	  void *file_phdr = ((char *) elf->map_address
+			     + elf->start_offset + ehdr->e_phoff);
+	  if (ehdr->e_ident[EI_DATA] == MY_ELFDATA
+	      && (ALLOW_UNALIGNED
+		  || ((uintptr_t) file_phdr
+		      & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0))
+	    /* Simply use the mapped data.  */
+	    elf->state.ELFW(elf,LIBELFBITS).phdr = file_phdr;
+	  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 (ehdr->e_ident[EI_DATA] == MY_ELFDATA)
+		{
+		  assert (! ALLOW_UNALIGNED);
+		  memcpy (phdr, file_phdr, size);
+		}
+	      else
+		{
+		  bool copy = ! (ALLOW_UNALIGNED
+				 || ((uintptr_t) file_phdr
+				     & (__alignof__ (ElfW2(LIBELFBITS,Phdr))
+					- 1)) == 0);
+		  if (! copy)
+		    notcvt = file_phdr;
+		  else
+		    {
+		      notcvt = (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
+		      if (unlikely (notcvt == NULL))
+			{
+			  __libelf_seterrno (ELF_E_NOMEM);
+			  goto out;
+			}
+		      memcpy (notcvt, file_phdr, 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);
+		    }
+
+		  if (copy)
+		    free (notcvt);
+		}
+	    }
+	}
+      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.  */
+	  ssize_t n = pread_retry (elf->fildes,
+				   elf->state.ELFW(elf,LIBELFBITS).phdr, size,
+				   elf->start_offset + ehdr->e_phoff);
+	  if (unlikely ((size_t) n != 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:
+  return result;
+}
+
+ElfW2(LIBELFBITS,Phdr) *
+elfw2(LIBELFBITS,getphdr) (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
+   * in getphdr_wrlock 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);
+  result = __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
+  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..237d912
--- /dev/null
+++ b/libelf/elf32_getshdr.c
@@ -0,0 +1,299 @@
+/* Return section header.
+   Copyright (C) 1998-2002, 2005, 2007, 2009, 2012, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+#include <system.h>
+#include "libelfP.h"
+#include "common.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+static ElfW2(LIBELFBITS,Shdr) *
+load_shdr_wrlock (Elf_Scn *scn)
+{
+  ElfW2(LIBELFBITS,Shdr) *result;
+
+  /* Read the section header table.  */
+  Elf *elf = scn->elf;
+  ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
+
+  /* Try again, maybe the data is there now.  */
+  result = scn->shdr.ELFW(e,LIBELFBITS);
+  if (result != NULL)
+    goto out;
+
+  size_t shnum;
+  if (__elf_getshdrnum_rdlock (elf, &shnum) != 0
+      || shnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Shdr)))
+    goto out;
+  size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr));
+
+  /* Allocate memory for the section 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)
+    {
+      /* First see whether the information in the ELF header is
+	 valid and it does not ask for too much.  */
+      if (unlikely (ehdr->e_shoff >= elf->maximum_size)
+	  || unlikely (elf->maximum_size - ehdr->e_shoff < size))
+	{
+	  /* Something is wrong.  */
+	  __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+	  goto free_and_out;
+	}
+
+      ElfW2(LIBELFBITS,Shdr) *notcvt;
+
+      /* All the data is already mapped.  If we could use it
+	 directly this would already have happened.  Unless
+	 we allocated the memory ourselves and the ELF_F_MALLOCED
+	 flag is set.  */
+      void *file_shdr = ((char *) elf->map_address
+			 + elf->start_offset + ehdr->e_shoff);
+
+      assert ((elf->flags & ELF_F_MALLOCED)
+	      || ehdr->e_ident[EI_DATA] != MY_ELFDATA
+	      || elf->cmd == ELF_C_READ_MMAP
+	      || (! ALLOW_UNALIGNED
+		  && ((uintptr_t) file_shdr
+		      & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0));
+
+      /* Now copy the data and at the same time convert the byte order.  */
+      if (ehdr->e_ident[EI_DATA] == MY_ELFDATA)
+	{
+	  assert ((elf->flags & ELF_F_MALLOCED)
+		  || elf->cmd == ELF_C_READ_MMAP
+		  || ! ALLOW_UNALIGNED);
+	  memcpy (shdr, file_shdr, size);
+	}
+      else
+	{
+	  bool copy = ! (ALLOW_UNALIGNED
+			 || ((uintptr_t) file_shdr
+			     & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1))
+			     == 0);
+	  if (! copy)
+	    notcvt = (ElfW2(LIBELFBITS,Shdr) *)
+	      ((char *) elf->map_address
+	       + elf->start_offset + ehdr->e_shoff);
+	  else
+	    {
+	      notcvt = (ElfW2(LIBELFBITS,Shdr) *) malloc (size);
+	      if (unlikely (notcvt == NULL))
+		{
+		  __libelf_seterrno (ELF_E_NOMEM);
+		  goto out;
+		}
+	      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);
+
+	      /* If this is a section with an extended index add a
+		 reference in the section which uses the extended
+		 index.  */
+	      if (shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
+		  && shdr[cnt].sh_link < shnum)
+		elf->state.ELFW(elf,LIBELFBITS).scns.data[shdr[cnt].sh_link].shndx_index
+		  = cnt;
+
+	      /* Set the own shndx_index field in case it has not yet
+		 been set.  */
+	      if (elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index == 0)
+		elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index
+		  = -1;
+	    }
+
+	  if (copy)
+	    free (notcvt);
+	}
+    }
+  else if (likely (elf->fildes != -1))
+    {
+      /* Read the header.  */
+      ssize_t n = pread_retry (elf->fildes,
+			       elf->state.ELFW(elf,LIBELFBITS).shdr, size,
+			       elf->start_offset + ehdr->e_shoff);
+      if (unlikely ((size_t) n != 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:
+  return result;
+}
+
+static bool
+scn_valid (Elf_Scn *scn)
+{
+  if (scn == NULL)
+    return false;
+
+  if (unlikely (scn->elf->state.elf.ehdr == NULL))
+    {
+      __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+      return false;
+    }
+
+  if (unlikely (scn->elf->class != ELFW(ELFCLASS,LIBELFBITS)))
+    {
+      __libelf_seterrno (ELF_E_INVALID_CLASS);
+      return false;
+    }
+
+  return true;
+}
+
+ElfW2(LIBELFBITS,Shdr) *
+internal_function
+__elfw2(LIBELFBITS,getshdr_rdlock) (Elf_Scn *scn)
+{
+  ElfW2(LIBELFBITS,Shdr) *result;
+
+  if (!scn_valid (scn))
+    return NULL;
+
+  result = scn->shdr.ELFW(e,LIBELFBITS);
+  if (result == NULL)
+    {
+      rwlock_unlock (scn->elf->lock);
+      rwlock_wrlock (scn->elf->lock);
+      result = scn->shdr.ELFW(e,LIBELFBITS);
+      if (result == NULL)
+	result = load_shdr_wrlock (scn);
+    }
+
+  return result;
+}
+
+ElfW2(LIBELFBITS,Shdr) *
+internal_function
+__elfw2(LIBELFBITS,getshdr_wrlock) (Elf_Scn *scn)
+{
+  ElfW2(LIBELFBITS,Shdr) *result;
+
+  if (!scn_valid (scn))
+    return NULL;
+
+  result = scn->shdr.ELFW(e,LIBELFBITS);
+  if (result == NULL)
+    result = load_shdr_wrlock (scn);
+
+  return result;
+}
+
+ElfW2(LIBELFBITS,Shdr) *
+elfw2(LIBELFBITS,getshdr) (Elf_Scn *scn)
+{
+  ElfW2(LIBELFBITS,Shdr) *result;
+
+  if (!scn_valid (scn))
+    return NULL;
+
+  rwlock_rdlock (scn->elf->lock);
+  result = __elfw2(LIBELFBITS,getshdr_rdlock) (scn);
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/libelf/elf32_newehdr.c b/libelf/elf32_newehdr.c
new file mode 100644
index 0000000..775d115
--- /dev/null
+++ b/libelf/elf32_newehdr.c
@@ -0,0 +1,91 @@
+/* Create new ELF header.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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)
+{
+  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..4aa7213
--- /dev/null
+++ b/libelf/elf32_newphdr.c
@@ -0,0 +1,190 @@
+/* Create new ELF program header table.
+   Copyright (C) 1999-2010, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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 *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;
+    }
+
+  if (unlikely ((ElfW2(LIBELFBITS,Word)) count != count))
+    {
+      __libelf_seterrno (ELF_E_INVALID_OPERAND);
+      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 clear any old PN_XNUM extended value.  */
+	  if (elf->state.ELFW(elf,LIBELFBITS).scns.cnt > 0)
+	    elf->state.ELFW(elf,LIBELFBITS).scns.data[0]
+	      .shdr.ELFW(e,LIBELFBITS)->sh_info = 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
+	   || count == PN_XNUM
+	   || elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
+    {
+      if (unlikely (count > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr))))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  result = NULL;
+	  goto out;
+	}
+
+      Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0];
+      if (unlikely (count >= PN_XNUM && scn0->shdr.ELFW(e,LIBELFBITS) == NULL))
+	{
+	  /* Something is wrong with section zero, but we need it to write
+	     the extended phdr count.  */
+	  __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+	  result = NULL;
+	  goto out;
+	}
+
+      /* 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;
+	  if (count >= PN_XNUM)
+	    {
+	      /* We have to write COUNT into the zeroth section's sh_info.  */
+	      if (elf->state.ELFW(elf,LIBELFBITS).scns.cnt == 0)
+		{
+		  assert (elf->state.ELFW(elf,LIBELFBITS).scns.max > 0);
+		  elf->state.ELFW(elf,LIBELFBITS).scns.cnt = 1;
+		}
+	      scn0->shdr.ELFW(e,LIBELFBITS)->sh_info = count;
+	      scn0->shdr_flags |= ELF_F_DIRTY;
+	      elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = PN_XNUM;
+	    }
+	  else
+	    /* Set the `e_phnum' member to the new value.  */
+	    elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = count;
+	  /* Clear the whole memory.  */
+	  memset (result, '\0', count * sizeof (ElfW2(LIBELFBITS,Phdr)));
+	  /* 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;
+      memset (result, '\0', count * sizeof (ElfW2(LIBELFBITS,Phdr)));
+    }
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elfw2(LIBELFBITS,newphdr))
diff --git a/libelf/elf32_offscn.c b/libelf/elf32_offscn.c
new file mode 100644
index 0000000..9e757c8
--- /dev/null
+++ b/libelf/elf32_offscn.c
@@ -0,0 +1,99 @@
+/* Get section at specific index.
+   Copyright (C) 2005, 2008, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+Elf_Scn *
+elfw2(LIBELFBITS,offscn) (Elf *elf, ElfW2(LIBELFBITS,Off) offset)
+{
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  Elf_ScnList *runp = &elf->state.ELFW(elf,LIBELFBITS).scns;
+
+  /* If we have not looked at section headers before,
+     we might need to read them in first.  */
+  if (runp->cnt > 0
+      && unlikely (runp->data[0].shdr.ELFW(e,LIBELFBITS) == NULL)
+      && unlikely (elfw2(LIBELFBITS,getshdr) (&runp->data[0]) == NULL))
+    return NULL;
+
+  rwlock_rdlock (elf->lock);
+
+  Elf_Scn *result = NULL;
+
+  /* Find the section in the list.  */
+  while (1)
+    {
+      for (unsigned int i = 0; i < runp->cnt; ++i)
+	if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_offset == offset)
+	  {
+	    result = &runp->data[i];
+
+	    /* If this section is empty, the following one has the same
+	       sh_offset.  We presume the caller is looking for a nonempty
+	       section, so keep looking if this one is empty.  */
+	    if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_size != 0
+		&& runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_type != SHT_NOBITS)
+	      goto out;
+	  }
+
+      runp = runp->next;
+      if (runp == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_OFFSET);
+	  break;
+	}
+    }
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elfw2(LIBELFBITS,offscn))
diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c
new file mode 100644
index 0000000..7ac9951
--- /dev/null
+++ b/libelf/elf32_updatefile.c
@@ -0,0 +1,850 @@
+/* Write changed data structures.
+   Copyright (C) 2000-2010, 2014, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <libelf.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <system.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)->shdr.ELFW(e,LIBELFBITS)->sh_size
+      < (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_size)
+    return -1;
+
+  if ((*scna)->shdr.ELFW(e,LIBELFBITS)->sh_size
+      > (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_size)
+    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 size is used; for sections with equal start
+   offsets and sizes, the section index is used.  Sorting by size
+   ensures that zero-length sections are processed first, which
+   is what we want since they do not advance our file writing position.  */
+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);
+}
+
+
+static inline void
+fill_mmap (size_t offset, char *last_position, char *scn_start,
+           char *const shdr_start, char *const shdr_end)
+{
+  size_t written = 0;
+
+  if (last_position < shdr_start)
+    {
+      written = MIN (scn_start + offset - last_position,
+                     shdr_start - last_position);
+
+      memset (last_position, __libelf_fill_byte, written);
+    }
+
+  if (last_position + written != scn_start + offset
+      && shdr_end < scn_start + offset)
+    {
+      char *fill_start = MAX (shdr_end, scn_start);
+      memset (fill_start, __libelf_fill_byte,
+              scn_start + offset - fill_start);
+    }
+}
+
+int
+internal_function
+__elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
+{
+  bool previous_scn_changed = false;
+
+  /* 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)
+    {
+      /* 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
+	  xfct_t fctp;
+	  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 if (elf->map_address + elf->start_offset != ehdr)
+	memcpy (elf->map_address + elf->start_offset, ehdr,
+		sizeof (ElfW2(LIBELFBITS,Ehdr)));
+
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags &= ~ELF_F_DIRTY;
+
+      /* We start writing sections after the ELF header only if there is
+	 no program header.  */
+      previous_scn_changed = elf->state.ELFW(elf,LIBELFBITS).phdr == NULL;
+    }
+
+  size_t phnum;
+  if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0))
+    return -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))
+    {
+      /* 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
+	  xfct_t fctp;
+	  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)) * phnum, 1);
+	}
+      else
+	memcpy (elf->map_address + elf->start_offset + ehdr->e_phoff,
+		elf->state.ELFW(elf,LIBELFBITS).phdr,
+		sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum);
+
+      elf->state.ELFW(elf,LIBELFBITS).phdr_flags &= ~ELF_F_DIRTY;
+
+      /* We modified the program header.  Maybe this created a gap so
+	 we have to write fill bytes, if necessary.  */
+      previous_scn_changed = true;
+    }
+
+  /* From now on we have to keep track of the last position to eventually
+     fill the gaps with the prescribed fill byte.  */
+  char *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, phnum));
+
+  /* Write all the sections.  Well, only those which are modified.  */
+  if (shnum > 0)
+    {
+      if (unlikely (shnum > SIZE_MAX / sizeof (Elf_Scn *)))
+	return 1;
+
+      Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns;
+      Elf_Scn **scns = (Elf_Scn **) malloc (shnum * sizeof (Elf_Scn *));
+      if (unlikely (scns == NULL))
+	{
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  return -1;
+	}
+      char *const shdr_start = ((char *) elf->map_address + elf->start_offset
+				+ ehdr->e_shoff);
+      char *const 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
+#define shdr_dest ((ElfW2(LIBELFBITS,Shdr) *) shdr_start)
+
+      /* Get all sections into the array and sort them.  */
+      sort_sections (scns, list);
+
+      /* We possibly have to copy the section header data because moving
+	 the sections might overwrite the data.  */
+      for (size_t cnt = 0; cnt < shnum; ++cnt)
+	{
+	  Elf_Scn *scn = scns[cnt];
+
+	  if (!elf->state.ELFW(elf,LIBELFBITS).shdr_malloced
+	      && (scn->shdr_flags & ELF_F_MALLOCED) == 0
+	      && scn->shdr.ELFW(e,LIBELFBITS) != &shdr_dest[scn->index])
+	    {
+	      assert ((char *) elf->map_address + elf->start_offset
+		      < (char *) scn->shdr.ELFW(e,LIBELFBITS));
+	      assert ((char *) scn->shdr.ELFW(e,LIBELFBITS)
+		      < ((char *) elf->map_address + elf->start_offset
+			 + elf->maximum_size));
+
+	      void *p = malloc (sizeof (ElfW2(LIBELFBITS,Shdr)));
+	      if (unlikely (p == NULL))
+		{
+		  free (scns);
+		  __libelf_seterrno (ELF_E_NOMEM);
+		  return -1;
+		}
+	      scn->shdr.ELFW(e,LIBELFBITS)
+		= memcpy (p, scn->shdr.ELFW(e,LIBELFBITS),
+			  sizeof (ElfW2(LIBELFBITS,Shdr)));
+	    }
+
+	  /* If the file is mmaped and the original position of the
+	     section in the file is lower than the new position we
+	     need to save the section content since otherwise it is
+	     overwritten before it can be copied.  If there are
+	     multiple data segments in the list only the first can be
+	     from the file.  */
+	  if (((char *) elf->map_address + elf->start_offset
+	       <= (char  *) scn->data_list.data.d.d_buf)
+	      && ((char *) scn->data_list.data.d.d_buf
+		  < ((char *) elf->map_address + elf->start_offset
+		     + elf->maximum_size))
+	      && (((char *) elf->map_address + elf->start_offset
+		   + scn->shdr.ELFW(e,LIBELFBITS)->sh_offset)
+		  > (char *) scn->data_list.data.d.d_buf))
+	    {
+	      void *p = malloc (scn->data_list.data.d.d_size);
+	      if (unlikely (p == NULL))
+		{
+		  free (scns);
+		  __libelf_seterrno (ELF_E_NOMEM);
+		  return -1;
+		}
+	      scn->data_list.data.d.d_buf = scn->data_base
+		= memcpy (p, scn->data_list.data.d.d_buf,
+			  scn->data_list.data.d.d_size);
+	    }
+	}
+
+      /* 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];
+	  if (scn->index == 0)
+	    {
+	      /* The dummy section header entry.  It should not be
+		 possible to mark this "section" as dirty.  */
+	      assert ((scn->flags & ELF_F_DIRTY) == 0);
+	      continue;
+	    }
+
+	  ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS);
+	  if (shdr->sh_type == SHT_NOBITS)
+	    goto next;
+
+	  char *scn_start = ((char *) elf->map_address
+			     + elf->start_offset + shdr->sh_offset);
+	  Elf_Data_List *dl = &scn->data_list;
+	  bool scn_changed = false;
+
+	  if (scn->data_list_rear != NULL)
+	    do
+	      {
+		assert (dl->data.d.d_off >= 0);
+		assert ((GElf_Off) dl->data.d.d_off <= shdr->sh_size);
+		assert (dl->data.d.d_size <= (shdr->sh_size
+					      - (GElf_Off) dl->data.d.d_off));
+
+		/* If there is a gap, fill it.  */
+		if (scn_start + dl->data.d.d_off > last_position
+		    && (dl->data.d.d_off == 0
+			|| ((scn->flags | dl->flags | elf->flags)
+			    & ELF_F_DIRTY) != 0))
+		  {
+		    fill_mmap (dl->data.d.d_off, last_position, scn_start,
+		               shdr_start, shdr_end);
+		  }
+
+		last_position = scn_start + dl->data.d.d_off;
+
+		if ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY)
+		  {
+		    /* Let it go backward if the sections use a bogus
+		       layout with overlaps.  We'll overwrite the stupid
+		       user's section data with the latest one, rather than
+		       crashing.  */
+
+		    if (unlikely (change_bo))
+		      {
+#if EV_NUM != 2
+			xfct_t fctp;
+			fctp = __elf_xfctstom[__libelf_version - 1][dl->data.d.d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][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 if (dl->data.d.d_size != 0)
+		      last_position = mempcpy (last_position,
+					       dl->data.d.d_buf,
+					       dl->data.d.d_size);
+
+		    scn_changed = true;
+		  }
+		else
+		  last_position += dl->data.d.d_size;
+
+		assert (scn_start + dl->data.d.d_off + dl->data.d.d_size
+			== last_position);
+
+		dl->flags &= ~ELF_F_DIRTY;
+
+		dl = dl->next;
+	      }
+	    while (dl != NULL);
+	  else
+	    {
+	      /* If the previous section (or the ELF/program
+		 header) changed we might have to fill the gap.  */
+	      if (scn_start > last_position && previous_scn_changed)
+		fill_mmap (0, last_position, scn_start,
+		           shdr_start, shdr_end);
+
+	      /* We have to trust the existing section header information.  */
+	      last_position = scn_start + shdr->sh_size;
+	    }
+
+
+	  previous_scn_changed = scn_changed;
+	next:
+	  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);
+
+      /* Write the section header table entry if necessary.  */
+      for (size_t cnt = 0; cnt < shnum; ++cnt)
+	{
+	  Elf_Scn *scn = scns[cnt];
+
+	  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)));
+
+	      /* If we previously made a copy of the section header
+		 entry we now have to adjust the pointer again so
+		 point to new place in the mapping.  */
+	      if (!elf->state.ELFW(elf,LIBELFBITS).shdr_malloced
+		  && (scn->shdr_flags & ELF_F_MALLOCED) == 0
+		  && scn->shdr.ELFW(e,LIBELFBITS) != &shdr_dest[scn->index])
+		{
+		  free (scn->shdr.ELFW(e,LIBELFBITS));
+		  scn->shdr.ELFW(e,LIBELFBITS) = &shdr_dest[scn->index];
+		}
+
+	      scn->shdr_flags &= ~ELF_F_DIRTY;
+	    }
+	}
+      free (scns);
+    }
+
+  /* That was the last part.  Clear the overall flag.  */
+  elf->flags &= ~ELF_F_DIRTY;
+
+  /* Make sure the content hits the disk.  */
+  char *msync_start = ((char *) elf->map_address
+		       + (elf->start_offset & ~(sysconf (_SC_PAGESIZE) - 1)));
+  char *msync_end = ((char *) elf->map_address
+		     + elf->start_offset + ehdr->e_shoff
+		     + ehdr->e_shentsize * shnum);
+  (void) msync (msync_start, msync_end - msync_start, MS_SYNC);
+
+  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_retry (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
+__elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
+{
+  char fillbuf[FILLBUFSIZE];
+  size_t filled = 0;
+  bool previous_scn_changed = false;
+
+  /* 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
+	  xfct_t fctp;
+	  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_retry (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;
+
+      /* We start writing sections after the ELF header only if there is
+	 no program header.  */
+      previous_scn_changed = elf->state.ELFW(elf,LIBELFBITS).phdr == NULL;
+    }
+
+  /* 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));
+
+  size_t phnum;
+  if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0))
+    return -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
+	  xfct_t fctp;
+	  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)) * phnum);
+	  if (unlikely (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)) * phnum, 1);
+
+	  /* This is the buffer we want to write.  */
+	  out_phdr = tmp_phdr;
+	}
+
+      /* Write out the ELF header.  */
+      size_t phdr_size = sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum;
+      if (unlikely ((size_t) pwrite_retry (elf->fildes, out_phdr,
+					   phdr_size, ehdr->e_phoff)
+		    != phdr_size))
+	{
+	  __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;
+
+      /* We modified the program header.  Maybe this created a gap so
+	 we have to write fill bytes, if necessary.  */
+      previous_scn_changed = true;
+    }
+
+  /* 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)) * phnum);
+
+  /* Write all the sections.  Well, only those which are modified.  */
+  if (shnum > 0)
+    {
+      if (unlikely (shnum > SIZE_MAX / (sizeof (Elf_Scn *)
+					+ sizeof (ElfW2(LIBELFBITS,Shdr)))))
+	return 1;
+
+      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;
+      ElfW2(LIBELFBITS,Shdr) *shdr_data_mem = NULL;
+      if (change_bo || elf->state.ELFW(elf,LIBELFBITS).shdr == NULL
+	  || (elf->flags & ELF_F_DIRTY))
+	{
+	  shdr_data_mem = (ElfW2(LIBELFBITS,Shdr) *)
+	    malloc (shnum * sizeof (ElfW2(LIBELFBITS,Shdr)));
+	  if (unlikely (shdr_data_mem == NULL))
+	    {
+	      __libelf_seterrno (ELF_E_NOMEM);
+	      return -1;
+	    }
+	  shdr_data = shdr_data_mem;
+	}
+      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 **) malloc (shnum * sizeof (Elf_Scn *));
+      if (unlikely (scns == NULL))
+	{
+	  free (shdr_data_mem);
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  return -1;
+	}
+      sort_sections (scns, list);
+
+      for (size_t cnt = 0; cnt < shnum; ++cnt)
+	{
+	  Elf_Scn *scn = scns[cnt];
+	  if (scn->index == 0)
+	    {
+	      /* The dummy section header entry.  It should not be
+		 possible to mark this "section" as dirty.  */
+	      assert ((scn->flags & ELF_F_DIRTY) == 0);
+	      goto next;
+	    }
+
+	  ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS);
+	  if (shdr->sh_type == SHT_NOBITS)
+	    goto next;
+
+	  off_t scn_start = elf->start_offset + shdr->sh_offset;
+	  Elf_Data_List *dl = &scn->data_list;
+	  bool scn_changed = false;
+
+	  if (scn->data_list_rear != NULL)
+	    do
+	      {
+		/* If there is a gap, fill it.  */
+		if (scn_start + dl->data.d.d_off > last_offset
+		    && ((previous_scn_changed && dl->data.d.d_off == 0)
+			|| ((scn->flags | dl->flags | elf->flags)
+			    & ELF_F_DIRTY) != 0))
+		  {
+		    if (unlikely (fill (elf->fildes, last_offset,
+					(scn_start + dl->data.d.d_off)
+					- last_offset, fillbuf,
+					&filled) != 0))
+		      {
+		      fail_free:
+			free (shdr_data_mem);
+			free (scns);
+			return 1;
+		      }
+		  }
+
+		last_offset = scn_start + dl->data.d.d_off;
+
+		if ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY)
+		  {
+		    char tmpbuf[MAX_TMPBUF];
+		    void *buf = dl->data.d.d_buf;
+
+		    /* Let it go backward if the sections use a bogus
+		       layout with overlaps.  We'll overwrite the stupid
+		       user's section data with the latest one, rather than
+		       crashing.  */
+
+		    if (unlikely (change_bo))
+		      {
+#if EV_NUM != 2
+			xfct_t fctp;
+			fctp = __elf_xfctstom[__libelf_version - 1][dl->data.d.d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][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 (unlikely (buf == NULL))
+			      {
+				__libelf_seterrno (ELF_E_NOMEM);
+				goto fail_free;
+			      }
+			  }
+
+			/* Do the real work.  */
+			(*fctp) (buf, dl->data.d.d_buf, dl->data.d.d_size, 1);
+		      }
+
+		    ssize_t n = pwrite_retry (elf->fildes, buf,
+					      dl->data.d.d_size,
+					      last_offset);
+		    if (unlikely ((size_t) n != dl->data.d.d_size))
+		      {
+			if (buf != dl->data.d.d_buf && buf != tmpbuf)
+			  free (buf);
+
+			__libelf_seterrno (ELF_E_WRITE_ERROR);
+			goto fail_free;
+		      }
+
+		    if (buf != dl->data.d.d_buf && buf != tmpbuf)
+		      free (buf);
+
+		    scn_changed = true;
+		  }
+
+		last_offset += dl->data.d.d_size;
+
+		dl->flags &= ~ELF_F_DIRTY;
+
+		dl = dl->next;
+	      }
+	    while (dl != NULL);
+	  else
+	    {
+	      /* If the previous section (or the ELF/program
+		 header) changed we might have to fill the gap.  */
+	      if (scn_start > last_offset && previous_scn_changed)
+		{
+		  if (unlikely (fill (elf->fildes, last_offset,
+				      scn_start - last_offset, fillbuf,
+				      &filled) != 0))
+		    goto fail_free;
+		}
+
+	      last_offset = scn_start + shdr->sh_size;
+	    }
+
+	  previous_scn_changed = scn_changed;
+	next:
+	  /* 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
+		   || (elf->flags & ELF_F_DIRTY))
+	    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))
+	goto fail_free;
+
+      /* Write out the section header table.  */
+      if (shdr_flags & ELF_F_DIRTY
+	  && unlikely ((size_t) pwrite_retry (elf->fildes, shdr_data,
+					      sizeof (ElfW2(LIBELFBITS,Shdr))
+					      * shnum, shdr_offset)
+		       != sizeof (ElfW2(LIBELFBITS,Shdr)) * shnum))
+	{
+	  __libelf_seterrno (ELF_E_WRITE_ERROR);
+	  goto fail_free;
+	}
+
+      free (shdr_data_mem);
+      free (scns);
+    }
+
+  /* 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..3e9ef61
--- /dev/null
+++ b/libelf/elf32_updatenull.c
@@ -0,0 +1,443 @@
+/* Update data structures for changes.
+   Copyright (C) 2000-2010, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <endian.h>
+#include <libelf.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <system.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))
+    {
+      ehdr->e_version = EV_CURRENT;
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
+    }
+  else if (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;
+    }
+
+  /* If phnum is zero make sure e_phoff is also zero and not some random
+     value.  That would cause trouble in update_file.  */
+  if (ehdr->e_phnum == 0 && ehdr->e_phoff != 0)
+    {
+      ehdr->e_phoff = 0;
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
+    }
+
+  return 0;
+}
+
+
+off_t
+internal_function
+__elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
+{
+  ElfW2(LIBELFBITS,Ehdr) *ehdr;
+  int changed = 0;
+  int ehdr_flags = 0;
+
+  ehdr = __elfw2(LIBELFBITS,getehdr_wrlock) (elf);
+
+  /* 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)
+    (void) __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
+  if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL)
+    {
+      size_t phnum;
+      if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0))
+	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, 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, phnum);
+	}
+    }
+
+  if (shnum > 0)
+    {
+      struct Elf_Scn *scn1 = NULL;
+      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;
+
+      /* Find the first section. */
+      if (list->cnt > 1)
+	scn1 = &list->data[1];
+      else if (list->next != NULL)
+	scn1 = &list->next->data[0];
+
+      /* Load the section headers if necessary.  This loads the
+	 headers for all sections.  */
+      if (scn1 != NULL && scn1->shdr.ELFW(e,LIBELFBITS) == NULL)
+	(void) __elfw2(LIBELFBITS,getshdr_wrlock) (scn1);
+
+      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;
+	      if (unlikely (! powerof2 (sh_align)))
+		{
+		  __libelf_seterrno (ELF_E_INVALID_ALIGN);
+		  return -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_wrlock (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_type != SHT_NOBITS
+			       ? shdr->sh_offset + 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 ?: 1) < 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);
+		  int offset_changed = 0;
+		  update_if_changed (shdr->sh_offset, (GElf_Word) size,
+				     offset_changed);
+		  changed |= offset_changed;
+
+		  if (offset_changed && scn->data_list_rear == NULL)
+		    {
+		      /* The position of the section in the file
+			 changed.  Create the section data list.  */
+		      if (__elf_getdata_rdlock (scn, NULL) == NULL)
+			return -1;
+		    }
+
+		  /* 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 && shdr->sh_entsize != 1
+		  && (elf->flags & ELF_F_PERMISSIVE) == 0)
+		{
+		  /* For compressed sections check the uncompressed size.  */
+		  ElfW2(LIBELFBITS,Word) sh_size;
+		  if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
+		    sh_size = shdr->sh_size;
+		  else
+		    {
+		      ElfW2(LIBELFBITS,Chdr) *chdr;
+		      chdr = elfw2(LIBELFBITS,getchdr) (scn);
+		      if (unlikely (chdr == NULL))
+			return -1;
+		      sh_size = chdr->ch_size;
+		    }
+
+		  if (unlikely (sh_size % shdr->sh_entsize != 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.  */
+      update_if_changed (ehdr->e_shentsize,
+			 elf_typesize (LIBELFBITS, ELF_T_SHDR, 1), ehdr_flags);
+      if (elf->flags & ELF_F_LAYOUT)
+	{
+	  /* The user is supposed to fill out e_shoff.  Use it and
+	     e_shnum (or sh_size of the dummy, first section header)
+	     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);
+
+	  /* 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..ac4eaf4
--- /dev/null
+++ b/libelf/elf32_xlatetof.c
@@ -0,0 +1,121 @@
+/* Convert from memory to file representation.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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) (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..13cd485
--- /dev/null
+++ b/libelf/elf32_xlatetom.c
@@ -0,0 +1,126 @@
+/* Convert from file to memory representation.
+   Copyright (C) 1998, 1999, 2000, 2002, 2012, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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) (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
+
+
+  /* We shouldn't require integer number of records when processing
+     notes.  Payload bytes follow the header immediately, it's not an
+     array of records as is the case otherwise.  */
+  if (src->d_type != ELF_T_NHDR
+      && 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..1802240
--- /dev/null
+++ b/libelf/elf64_checksum.c
@@ -0,0 +1,31 @@
+/* Compute simple checksum from permanent parts of the ELF file.
+   Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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..1ee1067
--- /dev/null
+++ b/libelf/elf64_fsize.c
@@ -0,0 +1,31 @@
+/* Return the size of an object file type.
+   Copyright (C) 1998, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_fsize.c"
diff --git a/libelf/elf64_getchdr.c b/libelf/elf64_getchdr.c
new file mode 100644
index 0000000..6588b79
--- /dev/null
+++ b/libelf/elf64_getchdr.c
@@ -0,0 +1,30 @@
+/* Return section compression header.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_getchdr.c"
diff --git a/libelf/elf64_getehdr.c b/libelf/elf64_getehdr.c
new file mode 100644
index 0000000..b35e7f6
--- /dev/null
+++ b/libelf/elf64_getehdr.c
@@ -0,0 +1,31 @@
+/* Return program header table.
+   Copyright (C) 1998, 1999, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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..c1ee60f
--- /dev/null
+++ b/libelf/elf64_getphdr.c
@@ -0,0 +1,31 @@
+/* Return program header table.
+   Copyright (C) 1998, 1999, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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..c50cc71
--- /dev/null
+++ b/libelf/elf64_getshdr.c
@@ -0,0 +1,31 @@
+/* Return section header.
+   Copyright (C) 1998, 1999, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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..65dd0f7
--- /dev/null
+++ b/libelf/elf64_newehdr.c
@@ -0,0 +1,31 @@
+/* Create new program header table.
+   Copyright (C) 1999, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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..58bfc73
--- /dev/null
+++ b/libelf/elf64_newphdr.c
@@ -0,0 +1,31 @@
+/* Create new program header table.
+   Copyright (C) 1999, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_newphdr.c"
diff --git a/libelf/elf64_offscn.c b/libelf/elf64_offscn.c
new file mode 100644
index 0000000..1b37b36
--- /dev/null
+++ b/libelf/elf64_offscn.c
@@ -0,0 +1,31 @@
+/* Return program header table.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_offscn.c"
diff --git a/libelf/elf64_updatefile.c b/libelf/elf64_updatefile.c
new file mode 100644
index 0000000..6941fe9a
--- /dev/null
+++ b/libelf/elf64_updatefile.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2000, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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..8333b5b
--- /dev/null
+++ b/libelf/elf64_updatenull.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2000, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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..aacf5b0
--- /dev/null
+++ b/libelf/elf64_xlatetof.c
@@ -0,0 +1,31 @@
+/* Convert from memory to file representation.
+   Copyright (C) 1998, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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..034262c
--- /dev/null
+++ b/libelf/elf64_xlatetom.c
@@ -0,0 +1,31 @@
+/* Convert from file to memory representation.
+   Copyright (C) 1998, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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..b20ab4f
--- /dev/null
+++ b/libelf/elf_begin.c
@@ -0,0 +1,1180 @@
+/* Create descriptor for processing file.
+   Copyright (C) 1998-2010, 2012, 2014, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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/stat.h>
+
+#include <system.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;
+  union
+  {
+    Elf32_Ehdr e32;
+    Elf64_Ehdr e64;
+  } ehdr_mem;
+  bool is32 = e_ident[EI_CLASS] == ELFCLASS32;
+
+  /* Make the ELF header available.  */
+  if (e_ident[EI_DATA] == MY_ELFDATA
+      && (ALLOW_UNALIGNED
+	  || (((size_t) e_ident
+	       & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr))
+		  - 1)) == 0)))
+    ehdr.p = e_ident;
+  else
+    {
+      /* We already read the ELF header.  We have to copy the header
+	 since we possibly modify the data here and the caller
+	 expects the memory it passes in to be preserved.  */
+      ehdr.p = &ehdr_mem;
+
+      if (is32)
+	{
+	  if (ALLOW_UNALIGNED)
+	    {
+	      ehdr_mem.e32.e_shnum = ((Elf32_Ehdr *) e_ident)->e_shnum;
+	      ehdr_mem.e32.e_shoff = ((Elf32_Ehdr *) e_ident)->e_shoff;
+	    }
+	  else
+	    memcpy (&ehdr_mem, e_ident, sizeof (Elf32_Ehdr));
+
+	  if (e_ident[EI_DATA] != MY_ELFDATA)
+	    {
+	      CONVERT (ehdr_mem.e32.e_shnum);
+	      CONVERT (ehdr_mem.e32.e_shoff);
+	    }
+	}
+      else
+	{
+	  if (ALLOW_UNALIGNED)
+	    {
+	      ehdr_mem.e64.e_shnum = ((Elf64_Ehdr *) e_ident)->e_shnum;
+	      ehdr_mem.e64.e_shoff = ((Elf64_Ehdr *) e_ident)->e_shoff;
+	    }
+	  else
+	    memcpy (&ehdr_mem, e_ident, sizeof (Elf64_Ehdr));
+
+	  if (e_ident[EI_DATA] != MY_ELFDATA)
+	    {
+	      CONVERT (ehdr_mem.e64.e_shnum);
+	      CONVERT (ehdr_mem.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 (unlikely (ehdr.e32->e_shoff >= maxsize)
+	      || unlikely (maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr)))
+	    /* Cannot read the first section header.  */
+	    return 0;
+
+	  if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
+	      && (ALLOW_UNALIGNED
+		  || (((size_t) ((char *) map_address + ehdr.e32->e_shoff))
+		      & (__alignof__ (Elf32_Shdr) - 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;
+	      ssize_t r;
+
+	      if (likely (map_address != NULL))
+		/* gcc will optimize the memcpy to a simple memory
+		   access while taking care of alignment issues.  */
+		memcpy (&size, &((Elf32_Shdr *) ((char *) map_address
+						 + ehdr.e32->e_shoff
+						 + offset))->sh_size,
+			sizeof (Elf32_Word));
+	      else
+		if (unlikely ((r = pread_retry (fildes, &size,
+						sizeof (Elf32_Word),
+						offset + ehdr.e32->e_shoff
+						+ offsetof (Elf32_Shdr,
+							    sh_size)))
+			      != sizeof (Elf32_Word)))
+		  {
+		    if (r < 0)
+		      __libelf_seterrno (ELF_E_INVALID_FILE);
+		    else
+		      __libelf_seterrno (ELF_E_INVALID_ELF);
+		    return (size_t) -1l;
+		  }
+
+	      if (e_ident[EI_DATA] != MY_ELFDATA)
+		CONVERT (size);
+
+	      result = size;
+	    }
+	}
+
+      /* If the section headers were truncated, pretend none were there.  */
+      if (ehdr.e32->e_shoff > maxsize
+	  || maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr) * result)
+	result = 0;
+    }
+  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 (unlikely (ehdr.e64->e_shoff >= maxsize)
+	      || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize))
+	    /* Cannot read the first section header.  */
+	    return 0;
+
+	  Elf64_Xword size;
+	  if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
+	      && (ALLOW_UNALIGNED
+		  || (((size_t) ((char *) map_address + ehdr.e64->e_shoff))
+		      & (__alignof__ (Elf64_Shdr) - 1)) == 0))
+	    /* We can directly access the memory.  */
+	    size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff
+				    + offset))->sh_size;
+	  else
+	    {
+	      ssize_t r;
+	      if (likely (map_address != NULL))
+		/* gcc will optimize the memcpy to a simple memory
+		   access while taking care of alignment issues.  */
+		memcpy (&size, &((Elf64_Shdr *) ((char *) map_address
+						 + ehdr.e64->e_shoff
+						 + offset))->sh_size,
+			sizeof (Elf64_Xword));
+	      else
+		if (unlikely ((r = pread_retry (fildes, &size,
+						sizeof (Elf64_Xword),
+						offset + ehdr.e64->e_shoff
+						+ offsetof (Elf64_Shdr,
+							    sh_size)))
+			      != sizeof (Elf64_Xword)))
+		  {
+		    if (r < 0)
+		      __libelf_seterrno (ELF_E_INVALID_FILE);
+		    else
+		      __libelf_seterrno (ELF_E_INVALID_ELF);
+		    return (size_t) -1l;
+		  }
+
+	      if (e_ident[EI_DATA] != MY_ELFDATA)
+		CONVERT (size);
+	    }
+
+	  if (size > ~((GElf_Word) 0))
+	    {
+	      /* Invalid value, it is too large.  */
+	      __libelf_seterrno (ELF_E_INVALID_ELF);
+	      return (size_t) -1l;
+	    }
+
+	  result = size;
+	}
+
+      /* If the section headers were truncated, pretend none were there.  */
+      if (ehdr.e64->e_shoff > maxsize
+	  || maxsize - ehdr.e64->e_shoff < sizeof (Elf64_Shdr) * result)
+	result = 0;
+    }
+
+  return result;
+}
+
+
+/* Create descriptor for ELF file in memory.  */
+static Elf *
+file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
+	       off_t offset, size_t maxsize, Elf_Cmd cmd, Elf *parent)
+{
+  /* Verify the binary is of the class we can handle.  */
+  if (unlikely ((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_ELF);
+      return NULL;
+    }
+
+  /* Determine the number of sections.  Returns -1 and sets libelf errno
+     if the file handle or elf file is invalid.  Returns zero if there
+     are no section headers (or they cannot be read).  */
+  size_t scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize);
+  if (scncnt == (size_t) -1l)
+    /* Could not determine the number of sections.  */
+    return NULL;
+
+  /* Check for too many sections.  */
+  if (e_ident[EI_CLASS] == ELFCLASS32)
+    {
+      if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr)))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_ELF);
+	  return NULL;
+	}
+    }
+  else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr)))
+    {
+      __libelf_seterrno (ELF_E_INVALID_ELF);
+      return NULL;
+    }
+
+  /* We can now allocate the memory.  Even if there are no section headers,
+     we allocate space for a zeroth section in case we need it later.  */
+  const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP)
+			 ? 1 : 0);
+  Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
+			   ELF_K_ELF, scnmax * sizeof (Elf_Scn));
+  if (elf == NULL)
+    /* Not enough memory.  allocate_elf will have set libelf errno.  */
+    return NULL;
+
+  assert ((unsigned int) scncnt == scncnt);
+  assert (offsetof (struct Elf, state.elf32.scns)
+	  == offsetof (struct Elf, state.elf64.scns));
+  elf->state.elf32.scns.cnt = scncnt;
+  elf->state.elf32.scns.max = scnmax;
+
+  /* Some more or less arbitrary value.  */
+  elf->state.elf.scnincr = 10;
+
+  /* Make the class easily available.  */
+  elf->class = e_ident[EI_CLASS];
+
+  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);
+
+      /* 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))
+	{
+	  /* We can use the mmapped memory.  */
+	  elf->state.elf32.ehdr = ehdr;
+	}
+      else
+	{
+	  /* Copy the ELF header.  */
+	  elf->state.elf32.ehdr = memcpy (&elf->state.elf32.ehdr_mem, e_ident,
+					  sizeof (Elf32_Ehdr));
+
+	  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);
+	    }
+	}
+
+      /* Don't precache the phdr pointer here.
+	 elf32_getphdr will validate it against the size when asked.  */
+
+      Elf32_Off e_shoff = elf->state.elf32.ehdr->e_shoff;
+      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
+	  && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write.  */
+	  && (ALLOW_UNALIGNED
+	      || (((uintptr_t) ((char *) ehdr + e_shoff)
+		   & (__alignof__ (Elf32_Shdr) - 1)) == 0)))
+	{
+	  if (unlikely (scncnt > 0 && e_shoff >= maxsize)
+	      || unlikely (maxsize - e_shoff
+			   < scncnt * sizeof (Elf32_Shdr)))
+	    {
+	    free_and_out:
+	      free (elf);
+	      __libelf_seterrno (ELF_E_INVALID_ELF);
+	      return NULL;
+	    }
+	  elf->state.elf32.shdr
+	    = (Elf32_Shdr *) ((char *) ehdr + e_shoff);
+
+	  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];
+	      if (likely (elf->state.elf32.shdr[cnt].sh_offset < maxsize)
+		  && likely (elf->state.elf32.shdr[cnt].sh_size
+			     <= maxsize - elf->state.elf32.shdr[cnt].sh_offset))
+		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;
+
+	      /* If this is a section with an extended index add a
+		 reference in the section which uses the extended
+		 index.  */
+	      if (elf->state.elf32.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
+		  && elf->state.elf32.shdr[cnt].sh_link < scncnt)
+		elf->state.elf32.scns.data[elf->state.elf32.shdr[cnt].sh_link].shndx_index
+		  = cnt;
+
+	      /* Set the own shndx_index field in case it has not yet
+		 been set.  */
+	      if (elf->state.elf32.scns.data[cnt].shndx_index == 0)
+		elf->state.elf32.scns.data[cnt].shndx_index = -1;
+	    }
+	}
+      else
+	{
+	  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);
+
+      /* 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))
+	{
+	  /* We can use the mmapped memory.  */
+	  elf->state.elf64.ehdr = ehdr;
+	}
+      else
+	{
+	  /* Copy the ELF header.  */
+	  elf->state.elf64.ehdr = memcpy (&elf->state.elf64.ehdr_mem, e_ident,
+					  sizeof (Elf64_Ehdr));
+
+	  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);
+	    }
+	}
+
+      /* Don't precache the phdr pointer here.
+	 elf64_getphdr will validate it against the size when asked.  */
+
+      Elf64_Off e_shoff = elf->state.elf64.ehdr->e_shoff;
+      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
+	  && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write.  */
+	  && (ALLOW_UNALIGNED
+	      || (((uintptr_t) ((char *) ehdr + e_shoff)
+		   & (__alignof__ (Elf64_Shdr) - 1)) == 0)))
+	{
+	  if (unlikely (scncnt > 0 && e_shoff >= maxsize)
+	      || unlikely (maxsize - e_shoff
+			   < scncnt * sizeof (Elf64_Shdr)))
+	    goto free_and_out;
+	  elf->state.elf64.shdr
+	    = (Elf64_Shdr *) ((char *) ehdr + e_shoff);
+
+	  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];
+	      if (likely (elf->state.elf64.shdr[cnt].sh_offset < maxsize)
+		  && likely (elf->state.elf64.shdr[cnt].sh_size
+			     <= maxsize - elf->state.elf64.shdr[cnt].sh_offset))
+		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;
+
+	      /* If this is a section with an extended index add a
+		 reference in the section which uses the extended
+		 index.  */
+	      if (elf->state.elf64.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
+		  && elf->state.elf64.shdr[cnt].sh_link < scncnt)
+		elf->state.elf64.scns.data[elf->state.elf64.shdr[cnt].sh_link].shndx_index
+		  = cnt;
+
+	      /* Set the own shndx_index field in case it has not yet
+		 been set.  */
+	      if (elf->state.elf64.scns.data[cnt].shndx_index == 0)
+		elf->state.elf64.scns.data[cnt].shndx_index = -1;
+	    }
+	}
+      else
+	{
+	  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;
+    }
+
+  return elf;
+}
+
+
+Elf *
+internal_function
+__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.  */
+  unsigned char *e_ident = (unsigned char *) map_address + offset;
+
+  /* See what kind of object we have here.  */
+  Elf_Kind kind = determine_kind (e_ident, maxsize);
+
+  switch (kind)
+    {
+    case ELF_K_ELF:
+      return file_read_elf (fildes, map_address, e_ident, 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 identification header for an ELF file is EI_NIDENT
+     bytes in size, but we read the whole ELF header since we will
+     need it anyway later.  For archives the header in SARMAG bytes
+     long.  Read the maximum of these numbers.
+
+     XXX We have to change this for the extended `ar' format some day.
+
+     Use a union to ensure alignment.  We might later access the
+     memory as a ElfXX_Ehdr.  */
+  union
+  {
+    Elf64_Ehdr ehdr;
+    unsigned char header[MAX (sizeof (Elf64_Ehdr), SARMAG)];
+  } mem;
+
+  /* Read the head of the file.  */
+  ssize_t nread = pread_retry (fildes, mem.header,
+			       MIN (MAX (sizeof (Elf64_Ehdr), SARMAG),
+				    maxsize),
+			       offset);
+  if (unlikely (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.  */
+      __libelf_seterrno (ELF_E_INVALID_FILE);
+      return NULL;
+    }
+
+  /* See what kind of object we have here.  */
+  Elf_Kind kind = determine_kind (mem.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 ((size_t) nread >= (mem.header[EI_CLASS] == ELFCLASS32
+			     ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)))
+	return file_read_elf (fildes, NULL, mem.header, 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 (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;
+	}
+    }
+  else
+    {
+      /* The parent is already loaded.  Use it.  */
+      assert (maxsize != ~((size_t) 0));
+    }
+
+  if (use_mmap)
+    {
+      if (parent == NULL)
+	{
+	  /* 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
+			      || cmd == ELF_C_READ_MMAP
+			      ? MAP_PRIVATE : MAP_SHARED,
+			      fildes, offset);
+
+	  if (map_address == MAP_FAILED)
+	    map_address = NULL;
+	}
+      else
+	{
+	  map_address = parent->map_address;
+	}
+    }
+
+  /* If we have the file in memory optimize the access.  */
+  if (map_address != NULL)
+    {
+      assert (map_address != MAP_FAILED);
+
+      struct Elf *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 ((size_t) offset > elf->maximum_size
+	      || elf->maximum_size - offset < sizeof (struct ar_hdr))
+	    return NULL;
+
+	  /* The data is mapped.  */
+	  hdr = (struct ar_hdr *) (elf->map_address + offset);
+	}
+      else
+	{
+	  /* Read the header from the file.  */
+	  if (unlikely (pread_retry (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)
+	{
+	  if (len > elf->maximum_size - offset - sizeof (struct ar_hdr))
+	    goto too_much;
+	  /* Simply copy it over.  */
+	  elf->state.ar.long_names = (char *) memcpy (newp,
+						      elf->map_address + offset
+						      + sizeof (struct ar_hdr),
+						      len);
+	}
+      else
+	{
+	  if (unlikely ((size_t) pread_retry (elf->fildes, newp, len,
+					      elf->start_offset + offset
+					      + sizeof (struct ar_hdr))
+			!= len))
+	    {
+	    too_much:
+	      /* 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)
+        {
+	  char *startp = runp;
+	  runp = (char *) memchr (runp, '/', newp + len - runp);
+	  if (runp == NULL)
+	    {
+	      /* This was the last entry.  Clear any left overs.  */
+	      memset (startp, '\0', newp + len - startp);
+	      break;
+	    }
+
+	  /* NUL-terminate the string.  */
+	  *runp++ = '\0';
+
+	  /* A sanity check.  Somebody might have generated invalid
+	     archive.  */
+	  if (runp >= newp + len)
+	    break;
+	}
+    }
+
+  return newp;
+}
+
+
+/* Read the next archive header.  */
+int
+internal_function
+__libelf_next_arhdr_wrlock (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 (unlikely ((size_t) elf->state.ar.offset
+		    > elf->start_offset + elf->maximum_size
+		    || (elf->start_offset + elf->maximum_size
+			- elf->state.ar.offset) < sizeof (struct ar_hdr)))
+	{
+	  /* 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 (unlikely (pread_retry (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 (unlikely (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] == 'S'
+	       && memcmp (ar_hdr->ar_name, "/SYM64/         ", 16) == 0)
+	/* 64-bit index.  */
+	elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/SYM64/", 8);
+      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 (likely  (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 (unlikely (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 (unlikely (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
+	{
+	  /* In the old BSD style of archive, there is no / terminator.
+	     Instead, there is space padding at the end of the name.  */
+	  size_t i = 15;
+	  do
+	    elf->state.ar.ar_name[i] = '\0';
+	  while (i > 0 && elf->state.ar.ar_name[--i] == ' ');
+	}
+
+      elf_ar_hdr->ar_name = elf->state.ar.ar_name;
+    }
+
+  if (unlikely (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;
+    }
+
+  /* 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.  */
+
+#define INT_FIELD(FIELD)						      \
+  do									      \
+    {									      \
+      char buf[sizeof (ar_hdr->FIELD) + 1];				      \
+      const char *string = ar_hdr->FIELD;				      \
+      if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ')		      \
+	{								      \
+	  *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD)))  \
+	    = '\0';							      \
+	  string = buf;							      \
+	}								      \
+      if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int))		      \
+	elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atol (string);     \
+      else								      \
+	elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atoll (string);    \
+    }									      \
+  while (0)
+
+  INT_FIELD (ar_date);
+  INT_FIELD (ar_uid);
+  INT_FIELD (ar_gid);
+  INT_FIELD (ar_mode);
+  INT_FIELD (ar_size);
+
+  if (elf_ar_hdr->ar_size < 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
+      return -1;
+    }
+
+  /* Truncated file?  */
+  size_t maxsize;
+  maxsize = (elf->start_offset + elf->maximum_size
+	     - elf->state.ar.offset - sizeof (struct ar_hdr));
+  if ((size_t) elf_ar_hdr->ar_size > maxsize)
+    elf_ar_hdr->ar_size = maxsize;
+
+  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 (unlikely (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 (unlikely (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_wrlock (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;
+}
+
+/* Lock if necessary before dup an archive.  */
+static inline Elf *
+lock_dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
+{
+  /* We need wrlock to dup an archive.  */
+  if (ref->kind == ELF_K_AR)
+    {
+      rwlock_unlock (ref->lock);
+      rwlock_wrlock (ref->lock);
+    }
+    /* Duplicate the descriptor.  */
+  return dup_elf (fildes, cmd, ref);
+}
+
+/* Return a descriptor for the file belonging to FILDES.  */
+Elf *
+elf_begin (int fildes, Elf_Cmd cmd, Elf *ref)
+{
+  Elf *retval;
+
+  if (unlikely (! __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 (unlikely (fcntl (fildes, F_GETFD) == -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 (unlikely (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)
+	retval = lock_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 (unlikely (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
+	    retval = lock_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..e6fe472
--- /dev/null
+++ b/libelf/elf_clone.c
@@ -0,0 +1,81 @@
+/* Create clone of a given descriptor.
+   Copyright (C) 2003, 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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..fd68178
--- /dev/null
+++ b/libelf/elf_cntl.c
@@ -0,0 +1,81 @@
+/* Control an ELF file desrciptor.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <unistd.h>
+
+#include "libelfP.h"
+
+
+int
+elf_cntl (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_compress.c b/libelf/elf_compress.c
new file mode 100644
index 0000000..711be59
--- /dev/null
+++ b/libelf/elf_compress.c
@@ -0,0 +1,525 @@
+/* Compress or decompress a section.
+   Copyright (C) 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <system.h>
+#include "libelfP.h"
+#include "common.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <zlib.h>
+
+/* Cleanup and return result.  Don't leak memory.  */
+static void *
+do_deflate_cleanup (void *result, z_stream *z, void *out_buf,
+                    int ei_data, Elf_Data *cdatap)
+{
+  deflateEnd (z);
+  free (out_buf);
+  if (ei_data != MY_ELFDATA)
+    free (cdatap->d_buf);
+  return result;
+}
+
+#define deflate_cleanup(result) \
+    do_deflate_cleanup(result, &z, out_buf, ei_data, &cdata)
+
+/* Given a section, uses the (in-memory) Elf_Data to extract the
+   original data size (including the given header size) and data
+   alignment.  Returns a buffer that has at least hsize bytes (for the
+   caller to fill in with a header) plus zlib compressed date.  Also
+   returns the new buffer size in new_size (hsize + compressed data
+   size).  Returns (void *) -1 when FORCE is false and the compressed
+   data would be bigger than the original data.  */
+void *
+internal_function
+__libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data,
+		   size_t *orig_size, size_t *orig_addralign,
+		   size_t *new_size, bool force)
+{
+  /* The compressed data is the on-disk data.  We simplify the
+     implementation a bit by asking for the (converted) in-memory
+     data (which might be all there is if the user created it with
+     elf_newdata) and then convert back to raw if needed before
+     compressing.  Should be made a bit more clever to directly
+     use raw if that is directly available.  */
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (data == NULL)
+    return NULL;
+
+  /* When not forced and we immediately know we would use more data by
+     compressing, because of the header plus zlib overhead (five bytes
+     per 16 KB block, plus a one-time overhead of six bytes for the
+     entire stream), don't do anything.  */
+  Elf_Data *next_data = elf_getdata (scn, data);
+  if (next_data == NULL && !force
+      && data->d_size <= hsize + 5 + 6)
+    return (void *) -1;
+
+  *orig_addralign = data->d_align;
+  *orig_size = data->d_size;
+
+  /* Guess an output block size. 1/8th of the original Elf_Data plus
+     hsize.  Make the first chunk twice that size (25%), then increase
+     by a block (12.5%) when necessary.  */
+  size_t block = (data->d_size / 8) + hsize;
+  size_t out_size = 2 * block;
+  void *out_buf = malloc (out_size);
+  if (out_buf == NULL)
+    {
+      __libelf_seterrno (ELF_E_NOMEM);
+      return NULL;
+    }
+
+  /* Caller gets to fill in the header at the start.  Just skip it here.  */
+  size_t used = hsize;
+
+  z_stream z;
+  z.zalloc = Z_NULL;
+  z.zfree = Z_NULL;
+  z.opaque = Z_NULL;
+  int zrc = deflateInit (&z, Z_BEST_COMPRESSION);
+  if (zrc != Z_OK)
+    {
+      free (out_buf);
+      __libelf_seterrno (ELF_E_COMPRESS_ERROR);
+      return NULL;
+    }
+
+  Elf_Data cdata;
+  cdata.d_buf = NULL;
+
+  /* Loop over data buffers.  */
+  int flush = Z_NO_FLUSH;
+  do
+    {
+      /* Convert to raw if different endianess.  */
+      cdata = *data;
+      if (ei_data != MY_ELFDATA)
+	{
+	  /* Don't do this conversion in place, we might want to keep
+	     the original data around, caller decides.  */
+	  cdata.d_buf = malloc (data->d_size);
+	  if (cdata.d_buf == NULL)
+	    {
+	      __libelf_seterrno (ELF_E_NOMEM);
+	      return deflate_cleanup (NULL);
+	    }
+	  if (gelf_xlatetof (scn->elf, &cdata, data, ei_data) == NULL)
+	    return deflate_cleanup (NULL);
+	}
+
+      z.avail_in = cdata.d_size;
+      z.next_in = cdata.d_buf;
+
+      /* Get next buffer to see if this is the last one.  */
+      data = next_data;
+      if (data != NULL)
+	{
+	  *orig_addralign = MAX (*orig_addralign, data->d_align);
+	  *orig_size += data->d_size;
+	  next_data = elf_getdata (scn, data);
+	}
+      else
+	flush = Z_FINISH;
+
+      /* Flush one data buffer.  */
+      do
+	{
+	  z.avail_out = out_size - used;
+	  z.next_out = out_buf + used;
+	  zrc = deflate (&z, flush);
+	  if (zrc == Z_STREAM_ERROR)
+	    {
+	      __libelf_seterrno (ELF_E_COMPRESS_ERROR);
+	      return deflate_cleanup (NULL);
+	    }
+	  used += (out_size - used) - z.avail_out;
+
+	  /* Bail out if we are sure the user doesn't want the
+	     compression forced and we are using more compressed data
+	     than original data.  */
+	  if (!force && flush == Z_FINISH && used >= *orig_size)
+	    return deflate_cleanup ((void *) -1);
+
+	  if (z.avail_out == 0)
+	    {
+	      void *bigger = realloc (out_buf, out_size + block);
+	      if (bigger == NULL)
+		{
+		  __libelf_seterrno (ELF_E_NOMEM);
+		  return deflate_cleanup (NULL);
+		}
+	      out_buf = bigger;
+	      out_size += block;
+	    }
+	}
+      while (z.avail_out == 0); /* Need more output buffer.  */
+
+      if (ei_data != MY_ELFDATA)
+	{
+	  free (cdata.d_buf);
+	  cdata.d_buf = NULL;
+	}
+    }
+  while (flush != Z_FINISH); /* More data blocks.  */
+
+  zrc = deflateEnd (&z);
+  if (zrc != Z_OK)
+    {
+      __libelf_seterrno (ELF_E_COMPRESS_ERROR);
+      return deflate_cleanup (NULL);
+    }
+
+  *new_size = used;
+  return out_buf;
+}
+
+void *
+internal_function
+__libelf_decompress (void *buf_in, size_t size_in, size_t size_out)
+{
+  /* Catch highly unlikely compression ratios so we don't allocate
+     some giant amount of memory for nothing. The max compression
+     factor 1032:1 comes from http://www.zlib.net/zlib_tech.html  */
+  if (unlikely (size_out / 1032 > size_in))
+    {
+      __libelf_seterrno (ELF_E_INVALID_DATA);
+      return NULL;
+    }
+
+  void *buf_out = malloc (size_out);
+  if (unlikely (buf_out == NULL))
+    {
+      __libelf_seterrno (ELF_E_NOMEM);
+      return NULL;
+    }
+
+  z_stream z =
+    {
+      .next_in = buf_in,
+      .avail_in = size_in,
+      .next_out = buf_out,
+      .avail_out = size_out
+    };
+  int zrc = inflateInit (&z);
+  while (z.avail_in > 0 && likely (zrc == Z_OK))
+    {
+      z.next_out = buf_out + (size_out - z.avail_out);
+      zrc = inflate (&z, Z_FINISH);
+      if (unlikely (zrc != Z_STREAM_END))
+	{
+	  zrc = Z_DATA_ERROR;
+	  break;
+	}
+      zrc = inflateReset (&z);
+    }
+  if (likely (zrc == Z_OK))
+    zrc = inflateEnd (&z);
+
+  if (unlikely (zrc != Z_OK) || unlikely (z.avail_out != 0))
+    {
+      free (buf_out);
+      __libelf_seterrno (ELF_E_DECOMPRESS_ERROR);
+      return NULL;
+    }
+
+  return buf_out;
+}
+
+void *
+internal_function
+__libelf_decompress_elf (Elf_Scn *scn, size_t *size_out, size_t *addralign)
+{
+  GElf_Chdr chdr;
+  if (gelf_getchdr (scn, &chdr) == NULL)
+    return NULL;
+
+  if (chdr.ch_type != ELFCOMPRESS_ZLIB)
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_COMPRESSION_TYPE);
+      return NULL;
+    }
+
+  if (! powerof2 (chdr.ch_addralign))
+    {
+      __libelf_seterrno (ELF_E_INVALID_ALIGN);
+      return NULL;
+    }
+
+  /* Take the in-memory representation, so we can even handle a
+     section that has just been constructed (maybe it was copied
+     over from some other ELF file first with elf_newdata).  This
+     is slightly inefficient when the raw data needs to be
+     converted since then we'll be converting the whole buffer and
+     not just Chdr.  */
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (data == NULL)
+    return NULL;
+
+  int elfclass = scn->elf->class;
+  size_t hsize = (elfclass == ELFCLASS32
+		  ? sizeof (Elf32_Chdr) : sizeof (Elf64_Chdr));
+  size_t size_in = data->d_size - hsize;
+  void *buf_in = data->d_buf + hsize;
+  void *buf_out = __libelf_decompress (buf_in, size_in, chdr.ch_size);
+  *size_out = chdr.ch_size;
+  *addralign = chdr.ch_addralign;
+  return buf_out;
+}
+
+/* Assumes buf is a malloced buffer.  */
+void
+internal_function
+__libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size, size_t align,
+			Elf_Type type)
+{
+  /* This is the new raw data, replace and possibly free old data.  */
+  scn->rawdata.d.d_off = 0;
+  scn->rawdata.d.d_version = __libelf_version;
+  scn->rawdata.d.d_buf = buf;
+  scn->rawdata.d.d_size = size;
+  scn->rawdata.d.d_align = align;
+  scn->rawdata.d.d_type = type;
+
+  /* Existing existing data is no longer valid.  */
+  scn->data_list_rear = NULL;
+  if (scn->data_base != scn->rawdata_base)
+    free (scn->data_base);
+  scn->data_base = NULL;
+  if (scn->elf->map_address == NULL
+      || scn->rawdata_base == scn->zdata_base
+      || (scn->flags & ELF_F_MALLOCED) != 0)
+    free (scn->rawdata_base);
+
+  scn->rawdata_base = buf;
+  scn->flags |= ELF_F_MALLOCED;
+}
+
+int
+elf_compress (Elf_Scn *scn, int type, unsigned int flags)
+{
+  if (scn == NULL)
+    return -1;
+
+  if ((flags & ~ELF_CHF_FORCE) != 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_OPERAND);
+      return -1;
+    }
+
+  bool force = (flags & ELF_CHF_FORCE) != 0;
+
+  Elf *elf = scn->elf;
+  GElf_Ehdr ehdr;
+  if (gelf_getehdr (elf, &ehdr) == NULL)
+    return -1;
+
+  int elfclass = elf->class;
+  int elfdata = ehdr.e_ident[EI_DATA];
+
+  Elf64_Xword sh_flags;
+  Elf64_Word sh_type;
+  Elf64_Xword sh_addralign;
+  if (elfclass == ELFCLASS32)
+    {
+      Elf32_Shdr *shdr = elf32_getshdr (scn);
+      if (shdr == NULL)
+	return -1;
+
+      sh_flags = shdr->sh_flags;
+      sh_type = shdr->sh_type;
+      sh_addralign = shdr->sh_addralign;
+    }
+  else
+    {
+      Elf64_Shdr *shdr = elf64_getshdr (scn);
+      if (shdr == NULL)
+	return -1;
+
+      sh_flags = shdr->sh_flags;
+      sh_type = shdr->sh_type;
+      sh_addralign = shdr->sh_addralign;
+    }
+
+  if ((sh_flags & SHF_ALLOC) != 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS);
+      return -1;
+    }
+
+  if (sh_type == SHT_NULL || sh_type == SHT_NOBITS)
+    {
+      __libelf_seterrno (ELF_E_INVALID_SECTION_TYPE);
+      return -1;
+    }
+
+  int compressed = (sh_flags & SHF_COMPRESSED);
+  if (type == ELFCOMPRESS_ZLIB)
+    {
+      /* Compress/Deflate.  */
+      if (compressed == 1)
+	{
+	  __libelf_seterrno (ELF_E_ALREADY_COMPRESSED);
+	  return -1;
+	}
+
+      size_t hsize = (elfclass == ELFCLASS32
+		      ? sizeof (Elf32_Chdr) : sizeof (Elf64_Chdr));
+      size_t orig_size, orig_addralign, new_size;
+      void *out_buf = __libelf_compress (scn, hsize, elfdata,
+					 &orig_size, &orig_addralign,
+					 &new_size, force);
+
+      /* Compression would make section larger, don't change anything.  */
+      if (out_buf == (void *) -1)
+	return 0;
+
+      /* Compression failed, return error.  */
+      if (out_buf == NULL)
+	return -1;
+
+      /* Put the header in front of the data.  */
+      if (elfclass == ELFCLASS32)
+	{
+	  Elf32_Chdr chdr;
+	  chdr.ch_type = ELFCOMPRESS_ZLIB;
+	  chdr.ch_size = orig_size;
+	  chdr.ch_addralign = orig_addralign;
+	  if (elfdata != MY_ELFDATA)
+	    {
+	      CONVERT (chdr.ch_type);
+	      CONVERT (chdr.ch_size);
+	      CONVERT (chdr.ch_addralign);
+	    }
+	  memcpy (out_buf, &chdr, sizeof (Elf32_Chdr));
+	}
+      else
+	{
+	  Elf64_Chdr chdr;
+	  chdr.ch_type = ELFCOMPRESS_ZLIB;
+	  chdr.ch_reserved = 0;
+	  chdr.ch_size = orig_size;
+	  chdr.ch_addralign = sh_addralign;
+	  if (elfdata != MY_ELFDATA)
+	    {
+	      CONVERT (chdr.ch_type);
+	      CONVERT (chdr.ch_reserved);
+	      CONVERT (chdr.ch_size);
+	      CONVERT (chdr.ch_addralign);
+	    }
+	  memcpy (out_buf, &chdr, sizeof (Elf64_Chdr));
+	}
+
+      /* Note we keep the sh_entsize as is, we assume it is setup
+	 correctly and ignored when SHF_COMPRESSED is set.  */
+      if (elfclass == ELFCLASS32)
+	{
+	  Elf32_Shdr *shdr = elf32_getshdr (scn);
+	  shdr->sh_size = new_size;
+	  shdr->sh_addralign = 1;
+	  shdr->sh_flags |= SHF_COMPRESSED;
+	}
+      else
+	{
+	  Elf64_Shdr *shdr = elf64_getshdr (scn);
+	  shdr->sh_size = new_size;
+	  shdr->sh_addralign = 1;
+	  shdr->sh_flags |= SHF_COMPRESSED;
+	}
+
+      __libelf_reset_rawdata (scn, out_buf, new_size, 1, ELF_T_CHDR);
+
+      /* The section is now compressed, we could keep the uncompressed
+	 data around, but since that might have been multiple Elf_Data
+	 buffers let the user uncompress it explicitly again if they
+	 want it to simplify bookkeeping.  */
+      scn->zdata_base = NULL;
+
+      return 1;
+    }
+  else if (type == 0)
+    {
+      /* Decompress/Inflate.  */
+      if (compressed == 0)
+	{
+	  __libelf_seterrno (ELF_E_NOT_COMPRESSED);
+	  return -1;
+	}
+
+      /* If the data is already decompressed (by elf_strptr), then we
+	 only need to setup the rawdata and section header. XXX what
+	 about elf_newdata?  */
+      if (scn->zdata_base == NULL)
+	{
+	  size_t size_out, addralign;
+	  void *buf_out = __libelf_decompress_elf (scn, &size_out, &addralign);
+	  if (buf_out == NULL)
+	    return -1;
+
+	  scn->zdata_base = buf_out;
+	  scn->zdata_size = size_out;
+	  scn->zdata_align = addralign;
+	}
+
+      /* Note we keep the sh_entsize as is, we assume it is setup
+	 correctly and ignored when SHF_COMPRESSED is set.  */
+      if (elfclass == ELFCLASS32)
+	{
+	  Elf32_Shdr *shdr = elf32_getshdr (scn);
+	  shdr->sh_size = scn->zdata_size;
+	  shdr->sh_addralign = scn->zdata_align;
+	  shdr->sh_flags &= ~SHF_COMPRESSED;
+	}
+      else
+	{
+	  Elf64_Shdr *shdr = elf64_getshdr (scn);
+	  shdr->sh_size = scn->zdata_size;
+	  shdr->sh_addralign = scn->zdata_align;
+	  shdr->sh_flags &= ~SHF_COMPRESSED;
+	}
+
+      __libelf_reset_rawdata (scn, scn->zdata_base,
+			      scn->zdata_size, scn->zdata_align,
+			      __libelf_data_type (elf, sh_type));
+
+      return 1;
+    }
+  else
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_COMPRESSION_TYPE);
+      return -1;
+    }
+}
diff --git a/libelf/elf_compress_gnu.c b/libelf/elf_compress_gnu.c
new file mode 100644
index 0000000..c35dc39
--- /dev/null
+++ b/libelf/elf_compress_gnu.c
@@ -0,0 +1,208 @@
+/* Compress or decompress a section.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include "libelfP.h"
+#include "common.h"
+
+int
+elf_compress_gnu (Elf_Scn *scn, int inflate, unsigned int flags)
+{
+  if (scn == NULL)
+    return -1;
+
+  if ((flags & ~ELF_CHF_FORCE) != 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_OPERAND);
+      return -1;
+    }
+
+  bool force = (flags & ELF_CHF_FORCE) != 0;
+
+  Elf *elf = scn->elf;
+  GElf_Ehdr ehdr;
+  if (gelf_getehdr (elf, &ehdr) == NULL)
+    return -1;
+
+  int elfclass = elf->class;
+  int elfdata = ehdr.e_ident[EI_DATA];
+
+  Elf64_Xword sh_flags;
+  Elf64_Word sh_type;
+  Elf64_Xword sh_addralign;
+  if (elfclass == ELFCLASS32)
+    {
+      Elf32_Shdr *shdr = elf32_getshdr (scn);
+      if (shdr == NULL)
+	return -1;
+
+      sh_flags = shdr->sh_flags;
+      sh_type = shdr->sh_type;
+      sh_addralign = shdr->sh_addralign;
+    }
+  else
+    {
+      Elf64_Shdr *shdr = elf64_getshdr (scn);
+      if (shdr == NULL)
+	return -1;
+
+      sh_flags = shdr->sh_flags;
+      sh_type = shdr->sh_type;
+      sh_addralign = shdr->sh_addralign;
+    }
+
+  if ((sh_flags & SHF_ALLOC) != 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS);
+      return -1;
+    }
+
+  if (sh_type == SHT_NULL || sh_type == SHT_NOBITS)
+    {
+      __libelf_seterrno (ELF_E_INVALID_SECTION_TYPE);
+      return -1;
+    }
+
+  /* For GNU compression we cannot really know whether the section is
+     already compressed or not.  Just try and see what happens...  */
+  // int compressed = (sh_flags & SHF_COMPRESSED);
+  if (inflate == 1)
+    {
+      size_t hsize = 4 + 8; /* GNU "ZLIB" + 8 byte size.  */
+      size_t orig_size, new_size, orig_addralign;
+      void *out_buf = __libelf_compress (scn, hsize, elfdata,
+					 &orig_size, &orig_addralign,
+					 &new_size, force);
+
+      /* Compression would make section larger, don't change anything.  */
+      if (out_buf == (void *) -1)
+	return 0;
+
+      /* Compression failed, return error.  */
+      if (out_buf == NULL)
+	return -1;
+
+      uint64_t be64_size = htobe64 (orig_size);
+      memmove (out_buf, "ZLIB", 4);
+      memmove (out_buf + 4, &be64_size, sizeof (be64_size));
+
+      /* We don't know anything about sh_entsize, sh_addralign and
+	 sh_flags won't have a SHF_COMPRESSED hint in the GNU format.
+	 Just adjust the sh_size.  */
+      if (elfclass == ELFCLASS32)
+	{
+	  Elf32_Shdr *shdr = elf32_getshdr (scn);
+	  shdr->sh_size = new_size;
+	}
+      else
+	{
+	  Elf64_Shdr *shdr = elf64_getshdr (scn);
+	  shdr->sh_size = new_size;
+	}
+
+      __libelf_reset_rawdata (scn, out_buf, new_size, 1, ELF_T_BYTE);
+
+      /* The section is now compressed, we could keep the uncompressed
+	 data around, but since that might have been multiple Elf_Data
+	 buffers let the user uncompress it explicitly again if they
+	 want it to simplify bookkeeping.  */
+      scn->zdata_base = NULL;
+
+      return 1;
+    }
+  else if (inflate == 0)
+    {
+      /* In theory the user could have constucted a compressed section
+	 by hand.  But we always just take the rawdata directly and
+	 decompress that.  */
+      Elf_Data *data = elf_rawdata (scn, NULL);
+      if (data == NULL)
+	return -1;
+
+      size_t hsize = 4 + 8; /* GNU "ZLIB" + 8 byte size.  */
+      if (data->d_size < hsize || memcmp (data->d_buf, "ZLIB", 4) != 0)
+	{
+          __libelf_seterrno (ELF_E_NOT_COMPRESSED);
+	  return -1;
+	}
+
+      /* There is a 12-byte header of "ZLIB" followed by
+	 an 8-byte big-endian size.  There is only one type and
+	 Alignment isn't preserved separately.  */
+      uint64_t gsize;
+      memcpy (&gsize, data->d_buf + 4, sizeof gsize);
+      gsize = be64toh (gsize);
+
+      /* One more sanity check, size should be bigger than original
+	 data size plus some overhead (4 chars ZLIB + 8 bytes size + 6
+	 bytes zlib stream overhead + 5 bytes overhead max for one 16K
+	 block) and should fit into a size_t.  */
+      if (gsize + 4 + 8 + 6 + 5 < data->d_size || gsize > SIZE_MAX)
+	{
+	  __libelf_seterrno (ELF_E_NOT_COMPRESSED);
+	  return -1;
+	}
+
+      size_t size = gsize;
+      size_t size_in = data->d_size - hsize;
+      void *buf_in = data->d_buf + hsize;
+      void *buf_out = __libelf_decompress (buf_in, size_in, size);
+      if (buf_out == NULL)
+	return -1;
+
+      /* We don't know anything about sh_entsize, sh_addralign and
+	 sh_flags won't have a SHF_COMPRESSED hint in the GNU format.
+	 Just adjust the sh_size.  */
+      if (elfclass == ELFCLASS32)
+	{
+	  Elf32_Shdr *shdr = elf32_getshdr (scn);
+	  shdr->sh_size = size;
+	}
+      else
+	{
+	  Elf64_Shdr *shdr = elf64_getshdr (scn);
+	  shdr->sh_size = size;
+	}
+
+      __libelf_reset_rawdata (scn, buf_out, size, sh_addralign,
+			      __libelf_data_type (elf, sh_type));
+
+      scn->zdata_base = buf_out;
+
+      return 1;
+    }
+  else
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_COMPRESSION_TYPE);
+      return -1;
+    }
+}
diff --git a/libelf/elf_end.c b/libelf/elf_end.c
new file mode 100644
index 0000000..160f0b8
--- /dev/null
+++ b/libelf/elf_end.c
@@ -0,0 +1,239 @@
+/* Free resources associated with Elf descriptor.
+   Copyright (C) 1998,1999,2000,2001,2002,2004,2005,2007,2015,2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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 *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.  */
+      if (elf->state.ar.ar_sym != (Elf_Arsym *) -1l)
+	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_Data_Chunk *rawchunks
+	  = (elf->class == ELFCLASS32
+	     || (offsetof (struct Elf, state.elf32.rawchunks)
+		 == offsetof (struct Elf, state.elf64.rawchunks))
+	     ? elf->state.elf32.rawchunks
+	     : elf->state.elf64.rawchunks);
+	while (rawchunks != NULL)
+	  {
+	    Elf_Data_Chunk *next = rawchunks->next;
+	    if (rawchunks->dummy_scn.flags & ELF_F_MALLOCED)
+	      free (rawchunks->data.d.d_buf);
+	    free (rawchunks);
+	    rawchunks = next;
+	  }
+
+	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);
+
+		/* Free zdata if uncompressed, but not yet used as
+		   rawdata_base.  If it is already used it will be
+		   freed below.  */
+		if (scn->zdata_base != scn->rawdata_base)
+		  free (scn->zdata_base);
+
+		/* 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.  Or if we had to decompress.  */
+		if (elf->map_address == NULL
+		    || scn->rawdata_base == scn->zdata_base
+		    || (scn->flags & ELF_F_MALLOCED) != 0)
+		  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_unlock (elf->lock);
+  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..5364e68
--- /dev/null
+++ b/libelf/elf_error.c
@@ -0,0 +1,355 @@
+/* Error handling in libelf.
+   Copyright (C) 1998-2010, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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"
+
+
+/* The error number.  */
+static __thread int global_error;
+
+
+int
+elf_errno (void)
+{
+  int 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_ELF_IDX \
+  (ELF_E_INVALID_FILE_IDX + sizeof "invalid file descriptor")
+  N_("invalid ELF file data")
+  "\0"
+#define ELF_E_INVALID_OP_IDX \
+  (ELF_E_INVALID_ELF_IDX + sizeof "invalid ELF file data")
+  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 file descriptor mismatch")
+  "\0"
+#define ELF_E_OFFSET_RANGE_IDX \
+  (ELF_E_FD_MISMATCH_IDX + sizeof "archive/member file descriptor 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, shared objects, and \
+core files")
+  "\0"
+#define ELF_E_NO_PHDR_IDX \
+  (ELF_E_INVALID_PHDR_IDX \
+   + sizeof "program header only allowed in executables, shared objects, and \
+core files")
+  N_("file has no program header")
+  "\0"
+#define ELF_E_INVALID_OFFSET_IDX \
+  (ELF_E_NO_PHDR_IDX \
+   + sizeof "file has no program header")
+  N_("invalid offset")
+  "\0"
+#define ELF_E_INVALID_SECTION_TYPE_IDX \
+  (ELF_E_INVALID_OFFSET_IDX \
+   + sizeof "invalid offset")
+  N_("invalid section type")
+  "\0"
+#define ELF_E_INVALID_SECTION_FLAGS_IDX \
+  (ELF_E_INVALID_SECTION_TYPE_IDX \
+   + sizeof "invalid section type")
+  N_("invalid section flags")
+  "\0"
+#define ELF_E_NOT_COMPRESSED_IDX		\
+  (ELF_E_INVALID_SECTION_FLAGS_IDX			\
+   + sizeof "invalid section flags")
+  N_("section does not contain compressed data")
+  "\0"
+#define ELF_E_ALREADY_COMPRESSED_IDX \
+  (ELF_E_NOT_COMPRESSED_IDX \
+   + sizeof "section does not contain compressed data")
+  N_("section contains compressed data")
+  "\0"
+#define ELF_E_UNKNOWN_COMPRESSION_TYPE_IDX \
+  (ELF_E_ALREADY_COMPRESSED_IDX \
+   + sizeof "section contains compressed data")
+  N_("unknown compression type")
+  "\0"
+#define ELF_E_COMPRESS_ERROR_IDX \
+  (ELF_E_UNKNOWN_COMPRESSION_TYPE_IDX \
+   + sizeof "unknown compression type")
+  N_("cannot compress data")
+  "\0"
+#define ELF_E_DECOMPRESS_ERROR_IDX \
+  (ELF_E_COMPRESS_ERROR_IDX \
+   + sizeof "cannot compress data")
+  N_("cannot decompress data")
+};
+
+
+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_ELF] = ELF_E_INVALID_ELF_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,
+  [ELF_E_INVALID_OFFSET] = ELF_E_INVALID_OFFSET_IDX,
+  [ELF_E_INVALID_SECTION_TYPE] = ELF_E_INVALID_SECTION_TYPE_IDX,
+  [ELF_E_INVALID_SECTION_FLAGS] = ELF_E_INVALID_SECTION_FLAGS_IDX,
+  [ELF_E_NOT_COMPRESSED] = ELF_E_NOT_COMPRESSED_IDX,
+  [ELF_E_ALREADY_COMPRESSED] = ELF_E_ALREADY_COMPRESSED_IDX,
+  [ELF_E_UNKNOWN_COMPRESSION_TYPE] = ELF_E_UNKNOWN_COMPRESSION_TYPE_IDX,
+  [ELF_E_COMPRESS_ERROR] = ELF_E_COMPRESS_ERROR_IDX,
+  [ELF_E_DECOMPRESS_ERROR] = ELF_E_DECOMPRESS_ERROR_IDX
+};
+#define nmsgidx ((int) (sizeof (msgidx) / sizeof (msgidx[0])))
+
+
+void
+internal_function
+__libelf_seterrno (int value)
+{
+  global_error = value >= 0 && value < nmsgidx ? value : ELF_E_UNKNOWN_ERROR;
+}
+
+
+const char *
+elf_errmsg (int error)
+{
+  int 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]);
+}
diff --git a/libelf/elf_fill.c b/libelf/elf_fill.c
new file mode 100644
index 0000000..6ebdf63
--- /dev/null
+++ b/libelf/elf_fill.c
@@ -0,0 +1,46 @@
+/* Set fill byte used when constructing ELF objects.
+   Copyright (C) 1998, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+
+#include "libelfP.h"
+
+
+int __libelf_fill_byte;
+
+
+void
+elf_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..cd2b123
--- /dev/null
+++ b/libelf/elf_flagdata.c
@@ -0,0 +1,68 @@
+/* Manipulate ELF data flag.
+   Copyright (C) 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagdata (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..a98276d5
--- /dev/null
+++ b/libelf/elf_flagehdr.c
@@ -0,0 +1,65 @@
+/* Manipulate ELF header flags.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagehdr (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..bd90a21
--- /dev/null
+++ b/libelf/elf_flagelf.c
@@ -0,0 +1,67 @@
+/* Manipulate ELF file flags.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagelf (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..0682d1f
--- /dev/null
+++ b/libelf/elf_flagphdr.c
@@ -0,0 +1,65 @@
+/* Manipulate ELF program header flags.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagphdr (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..2164a8c
--- /dev/null
+++ b/libelf/elf_flagscn.c
@@ -0,0 +1,65 @@
+/* Manipulate ELF section flags.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagscn (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..febf4ab
--- /dev/null
+++ b/libelf/elf_flagshdr.c
@@ -0,0 +1,65 @@
+/* Manipulate ELF section header flags.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagshdr (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..509f1da
--- /dev/null
+++ b/libelf/elf_getarhdr.c
@@ -0,0 +1,73 @@
+/* Read header of next archive member.
+   Copyright (C) 1998, 1999, 2000, 2002, 2008, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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)
+{
+  if (elf == NULL)
+    return NULL;
+
+  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_wrlock (parent) != 0)
+    {
+      rwlock_wrlock (parent->lock);
+      int st = __libelf_next_arhdr_wrlock (parent);
+      rwlock_unlock (parent->lock);
+
+      if (st != 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_getaroff.c b/libelf/elf_getaroff.c
new file mode 100644
index 0000000..5b59203
--- /dev/null
+++ b/libelf/elf_getaroff.c
@@ -0,0 +1,53 @@
+/* Return offset in archive for current file ELF.
+   Copyright (C) 2005, 2008, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+off_t
+elf_getaroff (Elf *elf)
+{
+  /* 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.  */
+  Elf *parent = elf->parent;
+  assert (parent->kind == ELF_K_AR);
+
+  return elf->start_offset - sizeof (struct ar_hdr) - parent->start_offset;
+}
diff --git a/libelf/elf_getarsym.c b/libelf/elf_getarsym.c
new file mode 100644
index 0000000..1f031fc
--- /dev/null
+++ b/libelf/elf_getarsym.c
@@ -0,0 +1,331 @@
+/* Return symbol table of archive.
+   Copyright (C) 1998-2000, 2002, 2005, 2009, 2012, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <system.h>
+#include <dl-hash.h>
+#include "libelfP.h"
+
+
+static int
+read_number_entries (uint64_t *nump, Elf *elf, size_t *offp, bool index64_p)
+{
+  union u
+  {
+    uint64_t ret64;
+    uint32_t ret32;
+  } u;
+
+  size_t w = index64_p ? 8 : 4;
+  if (elf->map_address != NULL)
+    /* Use memcpy instead of pointer dereference so as not to assume the
+       field is naturally aligned within the file.  */
+    memcpy (&u, elf->map_address + *offp, sizeof u);
+  else if ((size_t) pread_retry (elf->fildes, &u, w, *offp) != w)
+    return -1;
+
+  *offp += w;
+
+  if (__BYTE_ORDER == __LITTLE_ENDIAN)
+    *nump = index64_p ? bswap_64 (u.ret64) : bswap_32 (u.ret32);
+  else
+    *nump = index64_p ? u.ret64 : u.ret32;
+
+  return 0;
+}
+
+Elf_Arsym *
+elf_getarsym (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;
+
+      /* We might have to allocate some temporary data for reading.  */
+      void *temp_data = NULL;
+
+      struct ar_hdr *index_hdr;
+      if (elf->map_address == NULL)
+	{
+	  /* We must read index from the file.  */
+	  assert (elf->fildes != -1);
+	  if (pread_retry (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;
+	}
+
+      bool index64_p;
+      /* Now test whether this is the index.  If the name is "/", this
+	 is 32-bit index, if it's "/SYM64/", it's 64-bit index.
+
+	 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)
+	index64_p = false;
+      else if (memcmp (index_hdr->ar_name, "/SYM64/         ", 16) == 0)
+	index64_p = true;
+      else
+	{
+	  /* If the index is not the first entry, there is no index.
+
+	     XXX Is this true?  */
+	  __libelf_seterrno (ELF_E_NO_INDEX);
+	  goto out;
+	}
+      int w = index64_p ? 8 : 4;
+
+      /* We have an archive.  The first word in there is the number of
+	 entries in the table.  */
+      uint64_t n = 0;
+      size_t off = elf->start_offset + SARMAG + sizeof (struct ar_hdr);
+      if (read_number_entries (&n, elf, &off, index64_p) < 0)
+	{
+	  /* Cannot read the number of entries.  */
+	  __libelf_seterrno (ELF_E_NO_INDEX);
+	  goto out;
+	}
+
+      /* 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 (index_size > elf->maximum_size
+	  || elf->maximum_size - index_size < SARMAG + sizeof (struct ar_hdr)
+#if SIZE_MAX <= 4294967295U
+	  || n >= SIZE_MAX / sizeof (Elf_Arsym)
+#endif
+	  || n > index_size / w)
+	{
+	  /* 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)
+	{
+	  void *file_data; /* unit32_t[n] or uint64_t[n] */
+	  char *str_data;
+	  size_t sz = n * w;
+
+	  if (elf->map_address == NULL)
+	    {
+	      temp_data = malloc (sz);
+	      if (unlikely (temp_data == NULL))
+		{
+		  __libelf_seterrno (ELF_E_NOMEM);
+		  goto out;
+		}
+	      file_data = temp_data;
+
+	      ar_sym_len += index_size - n * w;
+	      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_retry (elf->fildes, file_data, sz, off) != sz
+		  || ((size_t) pread_retry (elf->fildes, new_str,
+					    index_size - sz, off + sz)
+		      != index_size - sz))
+		{
+		  /* 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 = (void *) (elf->map_address + off);
+	      if (!ALLOW_UNALIGNED
+		  && ((uintptr_t) file_data & -(uintptr_t) n) != 0)
+		{
+		  temp_data = malloc (sz);
+		  if (unlikely (temp_data == NULL))
+		    {
+		      __libelf_seterrno (ELF_E_NOMEM);
+		      goto out;
+		    }
+		  file_data = memcpy (temp_data, elf->map_address + off, sz);
+		}
+	      str_data = (char *) (elf->map_address + off + sz);
+	    }
+
+	  /* Now we can build the data structure.  */
+	  Elf_Arsym *arsym = elf->state.ar.ar_sym;
+	  uint64_t (*u64)[n] = file_data;
+	  uint32_t (*u32)[n] = file_data;
+	  for (size_t cnt = 0; cnt < n; ++cnt)
+	    {
+	      arsym[cnt].as_name = str_data;
+	      if (index64_p)
+		{
+		  uint64_t tmp = (*u64)[cnt];
+		  if (__BYTE_ORDER == __LITTLE_ENDIAN)
+		    tmp = bswap_64 (tmp);
+
+		  arsym[cnt].as_off = tmp;
+
+		  /* Check whether 64-bit offset fits into 32-bit
+		     size_t.  */
+		  if (sizeof (arsym[cnt].as_off) < 8
+		      && arsym[cnt].as_off != tmp)
+		    {
+		      if (elf->map_address == NULL)
+			{
+			  free (elf->state.ar.ar_sym);
+			  elf->state.ar.ar_sym = NULL;
+			}
+
+		      __libelf_seterrno (ELF_E_RANGE);
+		      goto out;
+		    }
+		}
+	      else if (__BYTE_ORDER == __LITTLE_ENDIAN)
+		arsym[cnt].as_off = bswap_32 ((*u32)[cnt]);
+	      else
+		arsym[cnt].as_off = (*u32)[cnt];
+
+	      arsym[cnt].as_hash = _dl_elf_hash (str_data);
+#if HAVE_DECL_RAWMEMCHR
+	      str_data = rawmemchr (str_data, '\0') + 1;
+#else
+	      char c;
+	      do {
+		c = *str_data;
+		str_data++;
+	      } while (c);
+#endif
+	    }
+
+	  /* 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:
+      free (temp_data);
+      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..8ec5f87
--- /dev/null
+++ b/libelf/elf_getbase.c
@@ -0,0 +1,44 @@
+/* Return offset of first byte for the object.
+   Copyright (C) 1998, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+off_t
+elf_getbase (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..97c503b
--- /dev/null
+++ b/libelf/elf_getdata.c
@@ -0,0 +1,564 @@
+/* Return the next data element from the section after possibly converting it.
+   Copyright (C) 1998-2005, 2006, 2007, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "libelfP.h"
+#include <system.h>
+#include "common.h"
+#include "elf-knowledge.h"
+
+
+#define TYPEIDX(Sh_Type) \
+  (Sh_Type >= SHT_NULL && Sh_Type < SHT_NUM				      \
+   ? Sh_Type								      \
+   : (Sh_Type >= SHT_GNU_HASH && Sh_Type <= SHT_HISUNW			      \
+      ? SHT_NUM + Sh_Type - SHT_GNU_HASH				      \
+      : 0))
+
+/* Associate section types with libelf types.  */
+static const Elf_Type shtype_map[EV_NUM - 1][TYPEIDX (SHT_HISUNW) + 1] =
+  {
+    [EV_CURRENT - 1] =
+    {
+      [SHT_SYMTAB] = ELF_T_SYM,
+      [SHT_RELA] = ELF_T_RELA,
+      [SHT_HASH] = ELF_T_WORD,
+      [SHT_DYNAMIC] = ELF_T_DYN,
+      [SHT_REL] = ELF_T_REL,
+      [SHT_DYNSYM] = ELF_T_SYM,
+      [SHT_INIT_ARRAY] = ELF_T_ADDR,
+      [SHT_FINI_ARRAY] = ELF_T_ADDR,
+      [SHT_PREINIT_ARRAY] = ELF_T_ADDR,
+      [SHT_GROUP] = ELF_T_WORD,
+      [SHT_SYMTAB_SHNDX] = ELF_T_WORD,
+      [SHT_NOTE] = ELF_T_NHDR,
+      [TYPEIDX (SHT_GNU_verdef)] = ELF_T_VDEF,
+      [TYPEIDX (SHT_GNU_verneed)] = ELF_T_VNEED,
+      [TYPEIDX (SHT_GNU_versym)] = ELF_T_HALF,
+      [TYPEIDX (SHT_SUNW_syminfo)] = ELF_T_SYMINFO,
+      [TYPEIDX (SHT_SUNW_move)] = ELF_T_MOVE,
+      [TYPEIDX (SHT_GNU_LIBLIST)] = ELF_T_LIB,
+      [TYPEIDX (SHT_GNU_HASH)] = ELF_T_GNUHASH,
+    }
+  };
+
+#if !ALLOW_UNALIGNED
+/* Associate libelf types with their internal alignment requirements.  */
+const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
+  {
+# define TYPE_ALIGNS(Bits)						      \
+    {									      \
+      [ELF_T_ADDR] = __alignof__ (ElfW2(Bits,Addr)),			      \
+      [ELF_T_EHDR] = __alignof__ (ElfW2(Bits,Ehdr)),			      \
+      [ELF_T_HALF] = __alignof__ (ElfW2(Bits,Half)),			      \
+      [ELF_T_OFF] = __alignof__ (ElfW2(Bits,Off)),			      \
+      [ELF_T_PHDR] = __alignof__ (ElfW2(Bits,Phdr)),			      \
+      [ELF_T_SHDR] = __alignof__ (ElfW2(Bits,Shdr)),			      \
+      [ELF_T_SWORD] = __alignof__ (ElfW2(Bits,Sword)),			      \
+      [ELF_T_WORD] = __alignof__ (ElfW2(Bits,Word)),			      \
+      [ELF_T_XWORD] = __alignof__ (ElfW2(Bits,Xword)),			      \
+      [ELF_T_SXWORD] = __alignof__ (ElfW2(Bits,Sxword)),		      \
+      [ELF_T_SYM] = __alignof__ (ElfW2(Bits,Sym)),			      \
+      [ELF_T_SYMINFO] = __alignof__ (ElfW2(Bits,Syminfo)),		      \
+      [ELF_T_REL] = __alignof__ (ElfW2(Bits,Rel)),			      \
+      [ELF_T_RELA] = __alignof__ (ElfW2(Bits,Rela)),			      \
+      [ELF_T_DYN] = __alignof__ (ElfW2(Bits,Dyn)),			      \
+      [ELF_T_VDEF] = __alignof__ (ElfW2(Bits,Verdef)),			      \
+      [ELF_T_VDAUX] = __alignof__ (ElfW2(Bits,Verdaux)),		      \
+      [ELF_T_VNEED] = __alignof__ (ElfW2(Bits,Verneed)),		      \
+      [ELF_T_VNAUX] = __alignof__ (ElfW2(Bits,Vernaux)),		      \
+      [ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)),			      \
+      [ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)),			      \
+      [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)),			      \
+      [ELF_T_GNUHASH] = __alignof__ (Elf32_Word),			      \
+      [ELF_T_AUXV] = __alignof__ (ElfW2(Bits,auxv_t)),			      \
+      [ELF_T_CHDR] = __alignof__ (ElfW2(Bits,Chdr)),			      \
+    }
+    [EV_CURRENT - 1] =
+    {
+      [ELFCLASS32 - 1] = TYPE_ALIGNS (32),
+      [ELFCLASS64 - 1] = TYPE_ALIGNS (64),
+    }
+# undef TYPE_ALIGNS
+  };
+#endif
+
+
+Elf_Type
+internal_function
+__libelf_data_type (Elf *elf, int sh_type)
+{
+  /* Some broken ELF ABI for 64-bit machines use the wrong hash table
+     entry size.  See elf-knowledge.h for more information.  */
+  if (sh_type == SHT_HASH && elf->class == ELFCLASS64)
+    {
+      GElf_Ehdr ehdr_mem;
+      GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
+      return (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD);
+    }
+  else
+    return shtype_map[LIBELF_EV_IDX][TYPEIDX (sh_type)];
+}
+
+/* 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, Elf_Type type)
+{
+  const size_t align = __libelf_type_align (eclass, type);
+
+  if (data == MY_ELFDATA)
+    {
+      if (((((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;
+	}
+
+      /* Make sure the source is correctly aligned for the conversion
+	 function to directly access the data elements.  */
+      char *rawdata_source;
+      if (ALLOW_UNALIGNED ||
+	  ((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
+	rawdata_source = scn->rawdata_base;
+      else
+	{
+	  rawdata_source = (char *) malloc (size);
+	  if (rawdata_source == NULL)
+	    {
+	      __libelf_seterrno (ELF_E_NOMEM);
+	      return;
+	    }
+
+	  /* The copy will be appropriately aligned for direct access.  */
+	  memcpy (rawdata_source, scn->rawdata_base, size);
+	}
+
+      /* 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, rawdata_source, size, 0);
+
+      if (rawdata_source != scn->rawdata_base)
+	free (rawdata_source);
+    }
+
+  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
+__libelf_set_rawdata_wrlock (Elf_Scn *scn)
+{
+  Elf64_Off offset;
+  Elf64_Xword size;
+  Elf64_Xword align;
+  Elf64_Xword flags;
+  int type;
+  Elf *elf = scn->elf;
+
+  if (elf->class == ELFCLASS32)
+    {
+      Elf32_Shdr *shdr
+	= scn->shdr.e32 ?: __elf32_getshdr_wrlock (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;
+      flags = shdr->sh_flags;
+    }
+  else
+    {
+      Elf64_Shdr *shdr
+	= scn->shdr.e64 ?: __elf64_getshdr_wrlock (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;
+      flags = shdr->sh_flags;
+    }
+
+  /* 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;
+
+      /* Compressed data has a header, but then compressed data.  */
+      if ((flags & SHF_COMPRESSED) != 0)
+	entsize = 1;
+      else if (type == SHT_HASH)
+	{
+	  GElf_Ehdr ehdr_mem;
+	  GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
+	  entsize = SH_ENTSIZE_HASH (ehdr);
+	}
+      else
+	{
+	  Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
+	  if (t == ELF_T_VDEF || t == ELF_T_NHDR
+	      || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
+	    entsize = 1;
+	  else
+	    entsize = __libelf_type_sizes[LIBELF_EV_IDX][elf->class - 1][t];
+	}
+
+      /* 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 (unlikely (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.  Check for unsigned
+	     overflow.  */
+	  if (unlikely (offset > elf->maximum_size
+	      || elf->maximum_size - offset < 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 (likely (elf->fildes != -1))
+	{
+	  /* First see whether the information in the section header is
+	     valid and it does not ask for too much.  Check for unsigned
+	     overflow.  */
+	  if (unlikely (offset > elf->maximum_size
+			|| elf->maximum_size - offset < size))
+	    {
+	      /* Something is wrong.  */
+	      __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+	      return 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;
+	    }
+
+	  ssize_t n = pread_retry (elf->fildes, scn->rawdata.d.d_buf, size,
+				   elf->start_offset + offset);
+	  if (unlikely ((size_t) n != 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;
+
+  /* Compressed data always has type ELF_T_CHDR regardless of the
+     section type.  */
+  if ((flags & SHF_COMPRESSED) != 0)
+    scn->rawdata.d.d_type = ELF_T_CHDR;
+  else
+    scn->rawdata.d.d_type = __libelf_data_type (elf, type);
+  scn->rawdata.d.d_off = 0;
+
+  /* Make sure the alignment makes sense.  d_align should be aligned both
+     in the section (trivially true since d_off is zero) and in the file.
+     Unfortunately we cannot be too strict because there are ELF files
+     out there that fail this requirement.  We will try to fix those up
+     in elf_update when writing out the image.  But for very large
+     alignment values this can bloat the image considerably.  So here
+     just check and clamp the alignment value to not be bigger than the
+     actual offset of the data in the file.  Given that there is always
+     at least an ehdr this will only trigger for alignment values > 64
+     which should be uncommon.  */
+  align = align ?: 1;
+  if (type != SHT_NOBITS && align > offset)
+    align = offset;
+  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;
+}
+
+int
+internal_function
+__libelf_set_rawdata (Elf_Scn *scn)
+{
+  int result;
+
+  if (scn == NULL)
+    return 1;
+
+  rwlock_wrlock (scn->elf->lock);
+  result = __libelf_set_rawdata_wrlock (scn);
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
+
+void
+internal_function
+__libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked)
+{
+  if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
+    {
+      Elf *elf = scn->elf;
+
+      /* Upgrade the lock to a write lock if necessary and check
+	 nobody else already did the work.  */
+      if (!wrlocked)
+	{
+	  rwlock_unlock (elf->lock);
+	  rwlock_wrlock (elf->lock);
+	  if (scn->data_list_rear != NULL)
+	    return;
+	}
+
+      /* 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.data.s = scn;
+    }
+
+  scn->data_list_rear = &scn->data_list;
+}
+
+Elf_Data *
+internal_function
+__elf_getdata_rdlock (Elf_Scn *scn, Elf_Data *data)
+{
+  Elf_Data *result = NULL;
+  Elf *elf;
+  int locked = 0;
+
+  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;
+
+  /* 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);
+      locked = 1;
+
+      /* 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_wrlock (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)
+    __libelf_set_data_list_rdlock (scn, locked);
+
+  /* Return the first data element in the list.  */
+  result = &scn->data_list.data.d;
+
+ out:
+  return result;
+}
+
+Elf_Data *
+elf_getdata (Elf_Scn *scn, Elf_Data *data)
+{
+  Elf_Data *result;
+
+  if (scn == NULL)
+    return NULL;
+
+  rwlock_rdlock (scn->elf->lock);
+  result = __elf_getdata_rdlock (scn, data);
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
+INTDEF(elf_getdata)
diff --git a/libelf/elf_getdata_rawchunk.c b/libelf/elf_getdata_rawchunk.c
new file mode 100644
index 0000000..31b2fe7
--- /dev/null
+++ b/libelf/elf_getdata_rawchunk.c
@@ -0,0 +1,187 @@
+/* Return converted data from raw chunk of ELF file.
+   Copyright (C) 2007, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <system.h>
+#include "libelfP.h"
+#include "common.h"
+
+Elf_Data *
+elf_getdata_rawchunk (Elf *elf, off_t offset, size_t size, Elf_Type type)
+{
+  if (unlikely (elf == NULL))
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      /* No valid descriptor.  */
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  if (unlikely (offset < 0 || (uint64_t) offset > elf->maximum_size
+		|| elf->maximum_size - (uint64_t) offset < size))
+
+    {
+      /* Invalid request.  */
+      __libelf_seterrno (ELF_E_INVALID_OP);
+      return NULL;
+    }
+
+  if (type >= ELF_T_NUM)
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_TYPE);
+      return NULL;
+    }
+
+  /* Get the raw bytes from the file.  */
+  void *rawchunk;
+  int flags = 0;
+  Elf_Data *result = NULL;
+
+  rwlock_rdlock (elf->lock);
+
+  size_t align = __libelf_type_align (elf->class, type);
+  if (elf->map_address != NULL)
+    {
+    /* If the file is mmap'ed we can use it directly, if aligned for type.  */
+      char *rawdata = elf->map_address + elf->start_offset + offset;
+      if (ALLOW_UNALIGNED ||
+	  ((uintptr_t) rawdata & (align - 1)) == 0)
+	rawchunk = rawdata;
+      else
+	{
+	  /* We allocate the memory and memcpy it to get aligned data. */
+	  rawchunk = malloc (size);
+	  if (rawchunk == NULL)
+	    goto nomem;
+	  memcpy (rawchunk, rawdata, size);
+	  flags = ELF_F_MALLOCED;
+	}
+    }
+  else
+    {
+      /* We allocate the memory and read the data from the file.  */
+      rawchunk = malloc (size);
+      if (rawchunk == NULL)
+	{
+	nomem:
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  goto out;
+	}
+
+      /* Read the file content.  */
+      if (unlikely ((size_t) pread_retry (elf->fildes, rawchunk, size,
+					  elf->start_offset + offset)
+		    != size))
+	{
+	  /* Something went wrong.  */
+	  free (rawchunk);
+	  __libelf_seterrno (ELF_E_READ_ERROR);
+	  goto out;
+	}
+
+      flags = ELF_F_MALLOCED;
+    }
+
+  /* Copy and/or convert the data as needed for aligned native-order access.  */
+  void *buffer;
+  if (elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA)
+    {
+      if (((uintptr_t) rawchunk & (align - 1)) == 0)
+	/* No need to copy, we can use the raw data.  */
+	buffer = rawchunk;
+      else
+	{
+	  /* A malloc'd block is always sufficiently aligned.  */
+	  assert (flags == 0);
+
+	  buffer = malloc (size);
+	  if (unlikely (buffer == NULL))
+	    goto nomem;
+	  flags = ELF_F_MALLOCED;
+
+	  /* The copy will be appropriately aligned for direct access.  */
+	  memcpy (buffer, rawchunk, size);
+	}
+    }
+  else
+    {
+      if (flags)
+	buffer = rawchunk;
+      else
+	{
+	  buffer = malloc (size);
+	  if (unlikely (buffer == NULL))
+	    goto nomem;
+	  flags = ELF_F_MALLOCED;
+	}
+
+      /* Call the conversion function.  */
+      (*__elf_xfctstom[LIBELF_EV_IDX][LIBELF_EV_IDX][elf->class - 1][type])
+	(buffer, rawchunk, size, 0);
+    }
+
+  /* Allocate the dummy container to point at this buffer.  */
+  Elf_Data_Chunk *chunk = calloc (1, sizeof *chunk);
+  if (chunk == NULL)
+    {
+      if (flags)
+	free (buffer);
+      goto nomem;
+    }
+
+  chunk->dummy_scn.elf = elf;
+  chunk->dummy_scn.flags = flags;
+  chunk->data.s = &chunk->dummy_scn;
+  chunk->data.d.d_buf = buffer;
+  chunk->data.d.d_size = size;
+  chunk->data.d.d_type = type;
+  chunk->data.d.d_align = align;
+  chunk->data.d.d_version = __libelf_version;
+
+  rwlock_unlock (elf->lock);
+  rwlock_wrlock (elf->lock);
+
+  chunk->next = elf->state.elf.rawchunks;
+  elf->state.elf.rawchunks = chunk;
+  result = &chunk->data.d;
+
+ out:
+  rwlock_unlock (elf->lock);
+  return result;
+}
diff --git a/libelf/elf_getident.c b/libelf/elf_getident.c
new file mode 100644
index 0000000..5abf8c9
--- /dev/null
+++ b/libelf/elf_getident.c
@@ -0,0 +1,61 @@
+/* Retrieve file identification data.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+char *
+elf_getident (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_getphdrnum.c b/libelf/elf_getphdrnum.c
new file mode 100644
index 0000000..f91cba9
--- /dev/null
+++ b/libelf/elf_getphdrnum.c
@@ -0,0 +1,142 @@
+/* Return number of program headers in the ELF file.
+   Copyright (C) 2010, 2014, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+int
+internal_function
+__elf_getphdrnum_rdlock (Elf *elf, size_t *dst)
+{
+ if (unlikely (elf->state.elf64.ehdr == NULL))
+   {
+     /* Maybe no ELF header was created yet.  */
+     __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+     return -1;
+   }
+
+ *dst = (elf->class == ELFCLASS32
+	 ? elf->state.elf32.ehdr->e_phnum
+	 : elf->state.elf64.ehdr->e_phnum);
+
+ if (*dst == PN_XNUM)
+   {
+     const Elf_ScnList *const scns = (elf->class == ELFCLASS32
+				      ? &elf->state.elf32.scns
+				      : &elf->state.elf64.scns);
+
+     /* If there are no section headers, perhaps this is really just 65536
+	written without PN_XNUM support.  Either that or it's bad data.  */
+
+     if (elf->class == ELFCLASS32)
+       {
+	 if (likely (scns->cnt > 0
+		     && elf->state.elf32.scns.data[0].shdr.e32 != NULL))
+	   *dst = scns->data[0].shdr.e32->sh_info;
+       }
+     else
+       {
+	 if (likely (scns->cnt > 0
+		     && elf->state.elf64.scns.data[0].shdr.e64 != NULL))
+	   *dst = scns->data[0].shdr.e64->sh_info;
+       }
+   }
+
+ return 0;
+}
+
+int
+internal_function
+__elf_getphdrnum_chk_rdlock (Elf *elf, size_t *dst)
+{
+  int result = __elf_getphdrnum_rdlock (elf, dst);
+
+  /* If the phdrs haven't been created or read in yet then do some
+     sanity checking to make sure phnum and phoff are consistent.  */
+  if (elf->state.elf.phdr == NULL)
+    {
+      Elf64_Off off = (elf->class == ELFCLASS32
+		       ? elf->state.elf32.ehdr->e_phoff
+		       : elf->state.elf64.ehdr->e_phoff);
+      if (unlikely (off == 0))
+	{
+	  *dst = 0;
+	  return result;
+	}
+
+      if (unlikely (off >= elf->maximum_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  return -1;
+	}
+
+      /* Check for too many sections.  */
+      size_t phdr_size = (elf->class == ELFCLASS32
+			  ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr));
+      if (unlikely (*dst > SIZE_MAX / phdr_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  return -1;
+	}
+
+      /* Truncated file?  Don't return more than can be indexed.  */
+      if (unlikely (elf->maximum_size - off < *dst * phdr_size))
+	*dst = (elf->maximum_size - off) / phdr_size;
+    }
+
+  return result;
+}
+
+int
+elf_getphdrnum (Elf *elf, size_t *dst)
+{
+  int result;
+
+  if (elf == NULL)
+    return -1;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return -1;
+    }
+
+  rwlock_rdlock (elf->lock);
+  result = __elf_getphdrnum_chk_rdlock (elf, dst);
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/libelf/elf_getscn.c b/libelf/elf_getscn.c
new file mode 100644
index 0000000..9f7213b
--- /dev/null
+++ b/libelf/elf_getscn.c
@@ -0,0 +1,87 @@
+/* Get section at specific index.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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 *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_getshdrnum.c b/libelf/elf_getshdrnum.c
new file mode 100644
index 0000000..18e5d14
--- /dev/null
+++ b/libelf/elf_getshdrnum.c
@@ -0,0 +1,87 @@
+/* Return number of sections in the ELF file.
+   Copyright (C) 2002, 2009, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+int
+internal_function
+__elf_getshdrnum_rdlock (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;
+    }
+
+  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;
+
+  return result;
+}
+
+int
+elf_getshdrnum (Elf *elf, size_t *dst)
+{
+  int result;
+
+  if (elf == NULL)
+    return -1;
+
+  rwlock_rdlock (elf->lock);
+  result = __elf_getshdrnum_rdlock (elf, dst);
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+/* Alias for the deprecated name.  */
+strong_alias (elf_getshdrnum, elf_getshnum)
diff --git a/libelf/elf_getshdrstrndx.c b/libelf/elf_getshdrstrndx.c
new file mode 100644
index 0000000..ad884fd
--- /dev/null
+++ b/libelf/elf_getshdrstrndx.c
@@ -0,0 +1,235 @@
+/* Return section index of section header string table.
+   Copyright (C) 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <gelf.h>
+#include <stddef.h>
+#include <unistd.h>
+
+#include <system.h>
+#include "libelfP.h"
+#include "common.h"
+
+
+int
+elf_getshdrstrndx (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 (unlikely (elf->state.elf32.scns.cnt == 0))
+		{
+		  /* Cannot use SHN_XINDEX without section headers.  */
+		  __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+		  result = -1;
+		  goto out;
+		}
+
+	      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
+			   + elf->start_offset + offset))
+			  & (__alignof__ (Elf32_Shdr) - 1)) == 0))
+		{
+		  /* First see whether the information in the ELF header is
+		     valid and it does not ask for too much.  */
+		  if (unlikely (elf->maximum_size - offset
+				< sizeof (Elf32_Shdr)))
+		    {
+		      /* Something is wrong.  */
+		      __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+		      result = -1;
+		      goto out;
+		    }
+
+		  /* We can directly access the memory.  */
+		  num = ((Elf32_Shdr *) (elf->map_address + elf->start_offset
+					 + offset))->sh_link;
+		}
+	      else
+		{
+		  /* We avoid reading in all the section headers.  Just read
+		     the first one.  */
+		  Elf32_Shdr shdr_mem;
+		  ssize_t r;
+
+		  if (unlikely ((r = pread_retry (elf->fildes, &shdr_mem,
+						  sizeof (Elf32_Shdr), offset))
+				!= sizeof (Elf32_Shdr)))
+		    {
+		      /* We must be able to read this ELF section header.  */
+		      if (r < 0)
+			__libelf_seterrno (ELF_E_INVALID_FILE);
+		      else
+			__libelf_seterrno (ELF_E_INVALID_ELF);
+		      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
+	    {
+	      if (unlikely (elf->state.elf64.scns.cnt == 0))
+		{
+		  /* Cannot use SHN_XINDEX without section headers.  */
+		  __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+		  result = -1;
+		  goto out;
+		}
+
+	      if (elf->state.elf64.scns.data[0].shdr.e64 != NULL)
+		{
+		  num = elf->state.elf64.scns.data[0].shdr.e64->sh_link;
+		  goto success;
+		}
+
+	      size_t 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
+			   + elf->start_offset + offset))
+			  & (__alignof__ (Elf64_Shdr) - 1)) == 0))
+		{
+		  /* First see whether the information in the ELF header is
+		     valid and it does not ask for too much.  */
+		  if (unlikely (elf->maximum_size - offset
+				< sizeof (Elf64_Shdr)))
+		    {
+		      /* Something is wrong.  */
+		      __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+		      result = -1;
+		      goto out;
+		    }
+
+		  /* We can directly access the memory.  */
+		  num = ((Elf64_Shdr *) (elf->map_address + elf->start_offset
+					 + offset))->sh_link;
+		}
+	      else
+		{
+		  /* We avoid reading in all the section headers.  Just read
+		     the first one.  */
+		  Elf64_Shdr shdr_mem;
+		  ssize_t r;
+
+		  if (unlikely ((r = pread_retry (elf->fildes, &shdr_mem,
+						  sizeof (Elf64_Shdr), offset))
+				!= sizeof (Elf64_Shdr)))
+		    {
+		      /* We must be able to read this ELF section header.  */
+		      if (r < 0)
+			__libelf_seterrno (ELF_E_INVALID_FILE);
+		      else
+			__libelf_seterrno (ELF_E_INVALID_ELF);
+		      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_getshdrstrndx)
+/* Alias for the deprecated name.  */
+strong_alias (elf_getshdrstrndx, elf_getshstrndx)
diff --git a/libelf/elf_gnu_hash.c b/libelf/elf_gnu_hash.c
new file mode 100644
index 0000000..5a1b852
--- /dev/null
+++ b/libelf/elf_gnu_hash.c
@@ -0,0 +1,46 @@
+/* GNU-style Hash function used in ELF implementations.
+   Copyright (C) 2006, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelfP.h>
+
+/* Get the implementation.  */
+#include <dl-hash.h>
+
+unsigned long int
+elf_gnu_hash (const char *string)
+{
+  uint_fast32_t h = 5381;
+  for (unsigned char c = *string; c != '\0'; c = *++string)
+    h = h * 33 + c;
+  return h & 0xffffffff;
+}
diff --git a/libelf/elf_hash.c b/libelf/elf_hash.c
new file mode 100644
index 0000000..345697e
--- /dev/null
+++ b/libelf/elf_hash.c
@@ -0,0 +1,44 @@
+/* Hash function used in ELF implementations.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelfP.h>
+
+/* Get the implementation.  */
+#include <dl-hash.h>
+
+unsigned long int
+elf_hash (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..0fb3f0c
--- /dev/null
+++ b/libelf/elf_kind.c
@@ -0,0 +1,44 @@
+/* Return the kind of file associated with the descriptor.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Kind
+elf_kind (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..a47f1d2
--- /dev/null
+++ b/libelf/elf_memory.c
@@ -0,0 +1,50 @@
+/* Create descriptor for memory region.
+   Copyright (C) 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf *
+elf_memory (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..488c4e5
--- /dev/null
+++ b/libelf/elf_ndxscn.c
@@ -0,0 +1,47 @@
+/* Get index of section.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+size_t
+elf_ndxscn (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..f6609a8
--- /dev/null
+++ b/libelf/elf_newdata.c
@@ -0,0 +1,136 @@
+/* Create new, empty section data.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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);
+
+  /* data_read is set when data has been read from the ELF image or
+     when a new section has been created by elf_newscn.  If data has
+     been read from the ELF image, then rawdata_base will point to raw
+     data.  If data_read has been set by elf_newscn, then rawdata_base
+     will be NULL.  data_list_rear will be set by elf_getdata if the
+     data has been converted, or by this function, elf_newdata, when
+     new data has been added.
+
+     Currently elf_getdata and elf_update rely on the fact that when
+     data_list_read is not NULL all they have to do is walk the data
+     list. They will ignore any (unread) raw data in that case.
+
+     So we need to make sure the data list is setup if there is
+     already data available.  */
+  if (scn->data_read
+      && scn->rawdata_base != NULL
+      && scn->data_list_rear == NULL)
+    __libelf_set_data_list_rdlock (scn, 1);
+
+  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
+    {
+      /* It would be more efficient to create new data without
+	 reading/converting the data from the file.  But then we
+	 have to remember this.  Currently elf_getdata and
+	 elf_update rely on the fact that they don't have to
+	 load/convert any data if data_list_rear is set.  */
+      if (scn->data_read == 0)
+	{
+	  if (__libelf_set_rawdata_wrlock (scn) != 0)
+	    /* Something went wrong.  The error value is already set.  */
+	    goto out;
+	  __libelf_set_data_list_rdlock (scn, 1);
+	}
+
+      /* 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;
+    }
+
+  /* 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..d15a642
--- /dev/null
+++ b/libelf/elf_newscn.c
@@ -0,0 +1,162 @@
+/* Append new section.
+   Copyright (C) 1998,1999,2000,2001,2002,2005,2009,2014,2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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_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 = NULL;
+
+      assert (elf->state.elf.scnincr > 0);
+
+      if (
+#if SIZE_MAX <= 4294967295U
+	  likely (elf->state.elf.scnincr
+		  < SIZE_MAX / 2 / sizeof (Elf_Scn) - sizeof (Elf_ScnList))
+#else
+	  1
+#endif
+	  )
+      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..6edafd2
--- /dev/null
+++ b/libelf/elf_next.c
@@ -0,0 +1,72 @@
+/* Advance in archive to next element.
+   Copyright (C) 1998-2009, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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 *parent;
+  Elf_Cmd ret;
+
+  /* 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);
+
+  rwlock_wrlock (parent->lock);
+
+  /* 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.  */
+  ret = __libelf_next_arhdr_wrlock (parent) != 0 ? ELF_C_NULL : elf->cmd;
+
+  /* If necessary, mark the archive header as unusable.  */
+  if (ret == ELF_C_NULL)
+    parent->state.ar.elf_ar_hdr.ar_name = NULL;
+
+  rwlock_unlock (parent->lock);
+
+  return ret;
+}
diff --git a/libelf/elf_nextscn.c b/libelf/elf_nextscn.c
new file mode 100644
index 0000000..d2f3e7c
--- /dev/null
+++ b/libelf/elf_nextscn.c
@@ -0,0 +1,83 @@
+/* Get next section.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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 *elf, Elf_Scn *scn)
+{
+  Elf_ScnList *list;
+  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.
+	 Set scn to the 0th section and perform nextscn.  */
+      if (elf->class == ELFCLASS32
+	   || (offsetof (Elf, state.elf32.scns)
+	       == offsetof (Elf, state.elf64.scns)))
+	list = &elf->state.elf32.scns;
+      else
+	list = &elf->state.elf64.scns;
+
+      scn = &list->data[0];
+    }
+  else
+    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..f1850e7
--- /dev/null
+++ b/libelf/elf_rand.c
@@ -0,0 +1,63 @@
+/* Select specific element in archive.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+size_t
+elf_rand (Elf *elf, size_t offset)
+{
+  /* Be gratious, the specs demand it.  */
+  if (elf == NULL || elf->kind != ELF_K_AR)
+    return 0;
+
+  rwlock_wrlock (elf->lock);
+
+  /* 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_wrlock (elf) != 0)
+    {
+      /* Mark the archive header as unusable.  */
+      elf->state.ar.elf_ar_hdr.ar_name = NULL;
+      return 0;
+    }
+
+  rwlock_unlock (elf->lock);
+
+  return offset;
+}
diff --git a/libelf/elf_rawdata.c b/libelf/elf_rawdata.c
new file mode 100644
index 0000000..db28f5d
--- /dev/null
+++ b/libelf/elf_rawdata.c
@@ -0,0 +1,76 @@
+/* Return raw section content.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+Elf_Data *
+elf_rawdata (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..b3837f4
--- /dev/null
+++ b/libelf/elf_rawfile.c
@@ -0,0 +1,67 @@
+/* Retrieve uninterpreted file contents.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+char *
+elf_rawfile (Elf *elf, size_t *ptr)
+{
+  char *result;
+
+  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;
+
+  rwlock_rdlock (elf->lock);
+  if (ptr != NULL)
+    *ptr = elf->maximum_size;
+
+  result = (char *) elf->map_address + elf->start_offset;
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/libelf/elf_readall.c b/libelf/elf_readall.c
new file mode 100644
index 0000000..384d251
--- /dev/null
+++ b/libelf/elf_readall.c
@@ -0,0 +1,152 @@
+/* Read all of the file associated with the descriptor.
+   Copyright (C) 1998-2009, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <system.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 *
+internal_function
+__libelf_readall (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 = NULL;
+
+      /* If this is an archive and we have derived descriptors get the
+	 locks for all of them.  */
+      libelf_acquire_all (elf);
+
+      if (elf->maximum_size == ~((size_t) 0))
+	{
+	  /* We don't yet know how large the file is.   Determine that now.  */
+	  struct stat st;
+
+	  if (fstat (elf->fildes, &st) < 0)
+	    goto read_error;
+
+	  if (sizeof (size_t) >= sizeof (st.st_size)
+	      || st.st_size <= ~((size_t) 0))
+	    elf->maximum_size = (size_t) st.st_size;
+	  else
+	    {
+	      errno = EOVERFLOW;
+	      goto read_error;
+	    }
+	}
+
+      /* Allocate all the memory we need.  */
+      mem = (char *) malloc (elf->maximum_size);
+      if (mem != NULL)
+	{
+	  /* Read the file content.  */
+	  if (unlikely ((size_t) pread_retry (elf->fildes, mem,
+					      elf->maximum_size,
+					      elf->start_offset)
+			!= elf->maximum_size))
+	    {
+	      /* Something went wrong.  */
+	    read_error:
+	      __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_scnshndx.c b/libelf/elf_scnshndx.c
new file mode 100644
index 0000000..5b783fa
--- /dev/null
+++ b/libelf/elf_scnshndx.c
@@ -0,0 +1,50 @@
+/* Get the section index of the extended section index table.
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2007.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libelfP.h"
+
+
+int
+elf_scnshndx (Elf_Scn *scn)
+{
+  if (unlikely (scn->shndx_index == 0))
+    {
+      /* We do not have the value yet.  We get it as a side effect of
+	 getting a section header.  */
+      GElf_Shdr shdr_mem;
+      (void) INTUSE(gelf_getshdr) (scn, &shdr_mem);
+    }
+
+  return scn->shndx_index;
+}
+INTDEF(elf_scnshndx)
diff --git a/libelf/elf_strptr.c b/libelf/elf_strptr.c
new file mode 100644
index 0000000..e72a3a3
--- /dev/null
+++ b/libelf/elf_strptr.c
@@ -0,0 +1,240 @@
+/* Return string pointer from string section.
+   Copyright (C) 1998-2002, 2004, 2008, 2009, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+static void *
+get_zdata (Elf_Scn *strscn)
+{
+  size_t zsize, zalign;
+  void *zdata = __libelf_decompress_elf (strscn, &zsize, &zalign);
+  if (zdata == NULL)
+    return NULL;
+
+  strscn->zdata_base = zdata;
+  strscn->zdata_size = zsize;
+  strscn->zdata_align = zalign;
+
+  return zdata;
+}
+
+static bool validate_str (const char *str, size_t from, size_t to)
+{
+#if HAVE_DECL_MEMRCHR
+  return memrchr (&str[from], '\0', to - from) != NULL;
+#else
+  do {
+    if (to <= from)
+      return false;
+
+    to--;
+  } while (str[to]);
+
+  return true;
+#endif
+}
+
+char *
+elf_strptr (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;
+	}
+    }
+
+  size_t sh_size = 0;
+  if (elf->class == ELFCLASS32)
+    {
+      Elf32_Shdr *shdr = strscn->shdr.e32 ?: __elf32_getshdr_rdlock (strscn);
+      if (unlikely (shdr->sh_type != SHT_STRTAB))
+	{
+	  /* This is no string section.  */
+	  __libelf_seterrno (ELF_E_INVALID_SECTION);
+	  goto out;
+	}
+
+      if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
+	sh_size = shdr->sh_size;
+      else
+	{
+	  if (strscn->zdata_base == NULL && get_zdata (strscn) == NULL)
+	    goto out;
+	  sh_size = strscn->zdata_size;
+	}
+
+      if (unlikely (offset >= sh_size))
+	{
+	  /* The given offset is too big, it is beyond this section.  */
+	  __libelf_seterrno (ELF_E_OFFSET_RANGE);
+	  goto out;
+	}
+    }
+  else
+    {
+      Elf64_Shdr *shdr = strscn->shdr.e64 ?: __elf64_getshdr_rdlock (strscn);
+      if (unlikely (shdr->sh_type != SHT_STRTAB))
+	{
+	  /* This is no string section.  */
+	  __libelf_seterrno (ELF_E_INVALID_SECTION);
+	  goto out;
+	}
+
+      if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
+	sh_size = shdr->sh_size;
+      else
+	{
+	  if (strscn->zdata_base == NULL && get_zdata (strscn) == NULL)
+	    goto out;
+	  sh_size = strscn->zdata_size;
+	}
+
+      if (unlikely (offset >= 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 && ! strscn->data_read)
+    {
+      rwlock_unlock (elf->lock);
+      rwlock_wrlock (elf->lock);
+      if (strscn->rawdata_base == NULL && ! strscn->data_read
+	/* Read the section data.  */
+	  && __libelf_set_rawdata_wrlock (strscn) != 0)
+	goto out;
+    }
+
+  if (unlikely (strscn->zdata_base != NULL))
+    {
+      /* Make sure the string is NUL terminated.  Start from the end,
+         which very likely is a NUL char.  */
+      if (likely (validate_str (strscn->zdata_base, offset, sh_size)))
+        result = &strscn->zdata_base[offset];
+      else
+        __libelf_seterrno (ELF_E_INVALID_INDEX);
+    }
+  else if (likely (strscn->data_list_rear == NULL))
+    {
+      // XXX The above is currently correct since elf_newdata will
+      // make sure to convert the rawdata into the datalist if
+      // necessary. But it would be more efficient to keep the rawdata
+      // unconverted and only then iterate over the rest of the (newly
+      // added data) list.  Note that when the ELF file is mmapped
+      // rawdata_base can be set while rawdata.d hasn't been
+      // initialized yet (when data_read is zero). So we cannot just
+      // look at the rawdata.d.d_size.
+
+      /* Make sure the string is NUL terminated.  Start from the end,
+	 which very likely is a NUL char.  */
+      if (likely (validate_str (strscn->rawdata_base, offset, sh_size)))
+	result = &strscn->rawdata_base[offset];
+      else
+	__libelf_seterrno (ELF_E_INVALID_INDEX);
+    }
+  else
+    {
+      /* This is a file which is currently created.  Use the list of
+	 data blocks.  */
+      struct Elf_Data_List *dl = &strscn->data_list;
+      while (dl != NULL)
+	{
+	  if (offset >= (size_t) dl->data.d.d_off
+	      && offset < dl->data.d.d_off + dl->data.d.d_size)
+	    {
+	      /* Make sure the string is NUL terminated.  Start from
+		 the end, which very likely is a NUL char.  */
+	      if (likely (validate_str ((char *) dl->data.d.d_buf,
+					offset - dl->data.d.d_off,
+					dl->data.d.d_size)))
+		result = ((char *) dl->data.d.d_buf
+			  + (offset - dl->data.d.d_off));
+	      else
+		__libelf_seterrno (ELF_E_INVALID_INDEX);
+	      break;
+	    }
+
+	  dl = dl->next;
+	}
+    }
+
+ 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..8ce0782
--- /dev/null
+++ b/libelf/elf_update.c
@@ -0,0 +1,222 @@
+/* Update data structures for changes and write them out.
+   Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include "libelfP.h"
+
+
+static off_t
+write_file (Elf *elf, off_t size, int change_bo, size_t shnum)
+{
+  int class = elf->class;
+
+  /* Check the mode bits now, before modification might change them.  */
+  struct stat st;
+  if (unlikely (fstat (elf->fildes, &st) != 0))
+    {
+      __libelf_seterrno (ELF_E_WRITE_ERROR);
+      return -1;
+    }
+
+  /* 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)
+    {
+      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;
+      else
+	elf->flags |= ELF_F_MMAPPED;
+    }
+
+  if (elf->map_address != NULL)
+    {
+      /* When using mmap we want to make sure the file content is
+	 really there. Only using ftruncate might mean the file is
+	 extended, but space isn't allocated yet.  This might cause a
+	 SIGBUS once we write into the mmapped space and the disk is
+	 full.  In glibc posix_fallocate is required to extend the
+	 file and allocate enough space even if the underlying
+	 filesystem would normally return EOPNOTSUPP.  But other
+	 implementations might not work as expected.  And the glibc
+	 fallback case might fail (with unexpected errnos) in some cases.
+	 So we only report an error when the call fails and errno is
+	 ENOSPC. Otherwise we ignore the error and treat it as just hint.  */
+      if (elf->parent == NULL
+	  && (elf->maximum_size == ~((size_t) 0)
+	      || (size_t) size > elf->maximum_size)
+	  && unlikely (posix_fallocate (elf->fildes, 0, size) != 0))
+	if (errno == ENOSPC)
+	  {
+	    __libelf_seterrno (ELF_E_WRITE_ERROR);
+	    return -1;
+	  }
+
+      /* 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;
+    }
+
+  /* Reduce the file size if necessary.  */
+  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;
+    }
+
+  /* POSIX says that ftruncate and write may clear the S_ISUID and S_ISGID
+     mode bits.  So make sure we restore them afterwards if they were set.
+     This is not atomic if someone else chmod's the file while we operate.  */
+  if (size != -1
+      && unlikely (st.st_mode & (S_ISUID | S_ISGID))
+      /* fchmod ignores the bits we cannot change.  */
+      && unlikely (fchmod (elf->fildes, st.st_mode) != 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 *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_wrlock (elf, &change_bo, shnum)
+	  : __elf64_updatenull_wrlock (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
+	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..7c336ff
--- /dev/null
+++ b/libelf/elf_version.c
@@ -0,0 +1,69 @@
+/* Coordinate ELF library and application versions.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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 (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..7bacd65
--- /dev/null
+++ b/libelf/exttypes.h
@@ -0,0 +1,104 @@
+/* External ELF types.
+   Copyright (C) 1998-2010, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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_);
+Lib32 (Ext_);
+auxv_t32 (Ext_);
+Chdr32 (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_);
+Lib64 (Ext_);
+auxv_t64 (Ext_);
+Chdr64 (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..0619880
--- /dev/null
+++ b/libelf/gelf.h
@@ -0,0 +1,342 @@
+/* This file defines generic ELF types, structures, and macros.
+   Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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;
+
+/* Header of a compressed section.  */
+typedef Elf64_Chdr GElf_Chdr;
+
+/* 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 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 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.  Creates an Elf32_Ehdr if CLASS
+   is ELFCLASS32 or an Elf64_Ehdr if CLASS is ELFCLASS64.  Returns NULL
+   on error.  */
+extern void *gelf_newehdr (Elf *__elf, int __class);
+
+/* Get section at OFFSET.  */
+extern Elf_Scn *gelf_offscn (Elf *__elf, GElf_Off __offset);
+
+/* 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.  Creates either an
+   Elf32_Phdr or an Elf64_Phdr depending on whether the given ELF is
+   ELFCLASS32 or ELFCLASS64.  Returns NULL on error.  */
+extern void *gelf_newphdr (Elf *__elf, size_t __phnum);
+
+/* Get compression header of section if any.  Returns NULL and sets
+   elf_errno if the section isn't compressed or an error occurred.  */
+extern GElf_Chdr *gelf_getchdr (Elf_Scn *__scn, GElf_Chdr *__dst);
+
+/* 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);
+
+
+/* Get auxv entry at the given index.  */
+extern GElf_auxv_t *gelf_getauxv (Elf_Data *__data, int __ndx,
+				  GElf_auxv_t *__dst);
+
+/* Update auxv entry at the given index.  */
+extern int gelf_update_auxv (Elf_Data *__data, int __ndx, GElf_auxv_t *__src);
+
+
+/* Get note header at the given offset into the data, and the offsets of
+   the note's name and descriptor data.  Returns the offset of the next
+   note header, or 0 for an invalid offset or corrupt note header.  */
+extern size_t gelf_getnote (Elf_Data *__data, size_t __offset,
+			    GElf_Nhdr *__result,
+			    size_t *__name_offset, size_t *__desc_offset);
+
+
+/* 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..831c54c
--- /dev/null
+++ b/libelf/gelf_checksum.c
@@ -0,0 +1,48 @@
+/* Convert from file to memory representation.  Generic ELF version.
+   Copyright (C) 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+long int
+gelf_checksum (Elf *elf)
+{
+  if (elf == NULL)
+    return -1l;
+
+  return (elf->class == ELFCLASS32
+	  ? INTUSE(elf32_checksum) (elf) : INTUSE(elf64_checksum) (elf));
+}
diff --git a/libelf/gelf_fsize.c b/libelf/gelf_fsize.c
new file mode 100644
index 0000000..0c50926
--- /dev/null
+++ b/libelf/gelf_fsize.c
@@ -0,0 +1,108 @@
+/* Return the size of an object file type.
+   Copyright (C) 1998-2010, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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 since 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)),		      \
+      [ELF_T_LIB]	= sizeof (ElfW2(LIBELFBITS, Ext_Lib)),		      \
+      [ELF_T_AUXV]	= sizeof (ElfW2(LIBELFBITS, Ext_auxv_t)),	      \
+      [ELF_T_CHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Chdr)),		      \
+      [ELF_T_GNUHASH]	= ELFW2(LIBELFBITS, FSZ_WORD)
+      TYPE_SIZES (32)
+    },
+    [ELFCLASS64 - 1] = {
+      TYPE_SIZES (64)
+    }
+  }
+};
+
+
+size_t
+gelf_fsize (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_getauxv.c b/libelf/gelf_getauxv.c
new file mode 100644
index 0000000..1591be2
--- /dev/null
+++ b/libelf/gelf_getauxv.c
@@ -0,0 +1,107 @@
+/* Get information from auxiliary vector at the given index.
+   Copyright (C) 2007, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_auxv_t *
+gelf_getauxv (Elf_Data *data, int ndx, GElf_auxv_t *dst)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  GElf_auxv_t *result = NULL;
+  Elf *elf;
+
+  if (data_scn == NULL)
+    return NULL;
+
+  if (unlikely (data_scn->d.d_type != ELF_T_AUXV))
+    {
+      __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_auxv_t *src;
+
+      /* Here it gets a bit more complicated.  The format of the vector
+	 entries has to be converted.  The user better have provided a
+	 buffer where we can store the information.  While copying the data
+	 we convert the format.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf32_auxv_t) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      src = &((Elf32_auxv_t *) 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->a_type = src->a_type;
+      dst->a_un.a_val = src->a_un.a_val;
+    }
+  else
+    {
+      /* If this is a 64 bit object it's easy.  */
+      assert (sizeof (GElf_auxv_t) == sizeof (Elf64_auxv_t));
+
+      /* The data is already in the correct form.  Just make sure the
+	 index is OK.  */
+      if (unlikely ((ndx + 1) * sizeof (GElf_auxv_t) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      memcpy (dst, data_scn->d.d_buf + ndx * sizeof (GElf_auxv_t),
+	      sizeof (GElf_auxv_t));
+    }
+
+  result = dst;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_getchdr.c b/libelf/gelf_getchdr.c
new file mode 100644
index 0000000..394bf4b
--- /dev/null
+++ b/libelf/gelf_getchdr.c
@@ -0,0 +1,69 @@
+/* Return section compression header.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libelfP.h"
+#include <gelf.h>
+#include <stddef.h>
+
+
+GElf_Chdr *
+gelf_getchdr (Elf_Scn *scn, GElf_Chdr *dest)
+{
+  if (scn == NULL)
+    return NULL;
+
+  if (dest == NULL)
+    {
+      __libelf_seterrno (ELF_E_INVALID_OPERAND);
+      return NULL;
+    }
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      Elf32_Chdr *chdr = elf32_getchdr (scn);
+      if (chdr == NULL)
+	return NULL;
+      dest->ch_type = chdr->ch_type;
+      dest->ch_size = chdr->ch_size;
+      dest->ch_addralign = chdr->ch_addralign;
+    }
+  else
+    {
+      Elf64_Chdr *chdr = elf64_getchdr (scn);
+      if (chdr == NULL)
+	return NULL;
+      *dest = *chdr;
+    }
+
+  return dest;
+}
+INTDEF(gelf_getchdr)
diff --git a/libelf/gelf_getclass.c b/libelf/gelf_getclass.c
new file mode 100644
index 0000000..7d0924b
--- /dev/null
+++ b/libelf/gelf_getclass.c
@@ -0,0 +1,44 @@
+/* Return the class of file associated with the descriptor.
+   Copyright (C) 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_getclass (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..a0090e1
--- /dev/null
+++ b/libelf/gelf_getdyn.c
@@ -0,0 +1,108 @@
+/* Get information from dynamic table at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Dyn *
+gelf_getdyn (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 (INVALID_NDX (ndx, Elf32_Dyn, &data_scn->d))
+	{
+	  __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 (INVALID_NDX (ndx, GElf_Dyn, &data_scn->d))
+	{
+	  __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..abeb70c
--- /dev/null
+++ b/libelf/gelf_getehdr.c
@@ -0,0 +1,108 @@
+/* Get ELF header.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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 *
+internal_function
+__gelf_getehdr_rdlock (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;
+    }
+
+  /* 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));
+
+  return result;
+}
+
+GElf_Ehdr *
+gelf_getehdr (Elf *elf, GElf_Ehdr *dest)
+{
+  GElf_Ehdr *result;
+  if (elf == NULL)
+    return NULL;
+
+  rwlock_rdlock (elf->lock);
+  result = __gelf_getehdr_rdlock (elf, dest);
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_getlib.c b/libelf/gelf_getlib.c
new file mode 100644
index 0000000..a8ac478
--- /dev/null
+++ b/libelf/gelf_getlib.c
@@ -0,0 +1,77 @@
+/* Get library from table at the given index.
+   Copyright (C) 2004, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Lib *
+gelf_getlib (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 (INVALID_NDX (ndx, GElf_Lib, data))
+    __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..18efedc
--- /dev/null
+++ b/libelf/gelf_getmove.c
@@ -0,0 +1,79 @@
+/* Get move structure at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+GElf_Move *
+gelf_getmove (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 (INVALID_NDX (ndx, GElf_Move, data))
+    {
+      __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_getnote.c b/libelf/gelf_getnote.c
new file mode 100644
index 0000000..c75edda
--- /dev/null
+++ b/libelf/gelf_getnote.c
@@ -0,0 +1,100 @@
+/* Get note information at the supplied offset.
+   Copyright (C) 2007, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+size_t
+gelf_getnote (Elf_Data *data, size_t offset, GElf_Nhdr *result,
+	      size_t *name_offset, size_t *desc_offset)
+{
+  if (data == NULL)
+    return 0;
+
+  if (unlikely (data->d_type != ELF_T_NHDR))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  /* It's easy to handle this type.  It has the same size for 32 and
+     64 bit objects.  */
+  assert (sizeof (GElf_Nhdr) == sizeof (Elf32_Nhdr));
+  assert (sizeof (GElf_Nhdr) == sizeof (Elf64_Nhdr));
+
+  rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  /* The data is already in the correct form.  Just make sure the
+     offset is OK.  */
+  if (unlikely (offset > data->d_size
+		|| data->d_size - offset < sizeof (GElf_Nhdr)))
+    {
+      __libelf_seterrno (ELF_E_OFFSET_RANGE);
+      offset = 0;
+    }
+  else
+    {
+      const GElf_Nhdr *n = data->d_buf + offset;
+      offset += sizeof *n;
+
+      /* Include padding.  Check below for overflow.  */
+      GElf_Word namesz = NOTE_ALIGN (n->n_namesz);
+      GElf_Word descsz = NOTE_ALIGN (n->n_descsz);
+
+      if (unlikely (offset > data->d_size
+		    || data->d_size - offset < namesz
+		    || (namesz == 0 && n->n_namesz != 0)))
+	offset = 0;
+      else
+	{
+	  *name_offset = offset;
+	  offset += namesz;
+	  if (unlikely (offset > data->d_size
+			|| data->d_size - offset < descsz
+			|| (descsz == 0 && n->n_descsz != 0)))
+	    offset = 0;
+	  else
+	    {
+	      *desc_offset = offset;
+	      offset += descsz;
+	      *result = *n;
+	    }
+	}
+    }
+
+  rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  return offset;
+}
diff --git a/libelf/gelf_getphdr.c b/libelf/gelf_getphdr.c
new file mode 100644
index 0000000..c719e4b
--- /dev/null
+++ b/libelf/gelf_getphdr.c
@@ -0,0 +1,135 @@
+/* Return program header table entry.
+   Copyright (C) 1998-2010, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "libelfP.h"
+
+
+GElf_Phdr *
+gelf_getphdr (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)
+	{
+	  rwlock_unlock (elf->lock);
+	  phdr = INTUSE(elf32_getphdr) (elf);
+	  if (phdr == NULL)
+	    /* The error number is already set.  */
+	    return NULL;
+	  rwlock_rdlock (elf->lock);
+	}
+
+      /* Test whether the index is ok.  */
+      size_t phnum;
+      if (__elf_getphdrnum_chk_rdlock (elf, &phnum) != 0
+	  || (size_t) ndx >= 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)
+	{
+	  rwlock_unlock (elf->lock);
+	  phdr = INTUSE(elf64_getphdr) (elf);
+	  if (phdr == NULL)
+	    /* The error number is already set.  */
+	    return NULL;
+	  rwlock_rdlock (elf->lock);
+	}
+
+      /* Test whether the index is ok.  */
+      size_t phnum;
+      if (__elf_getphdrnum_chk_rdlock (elf, &phnum) != 0
+	  || (size_t) ndx >= 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..309e3d3
--- /dev/null
+++ b/libelf/gelf_getrel.c
@@ -0,0 +1,99 @@
+/* Get REL relocation information at given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Rel *
+gelf_getrel (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 (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 (INVALID_NDX (ndx, Elf32_Rel, &data_scn->d))
+	{
+	  __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 (INVALID_NDX (ndx, Elf64_Rel, &data_scn->d))
+	{
+	  __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..d695f65
--- /dev/null
+++ b/libelf/gelf_getrela.c
@@ -0,0 +1,100 @@
+/* Get RELA relocation information at given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Rela *
+gelf_getrela (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 (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 (INVALID_NDX (ndx, Elf32_Rela, &data_scn->d))
+	{
+	  __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 (INVALID_NDX (ndx, Elf64_Rela, &data_scn->d))
+	{
+	  __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..3858c8e
--- /dev/null
+++ b/libelf/gelf_getshdr.c
@@ -0,0 +1,103 @@
+/* Return section header.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Shdr *
+gelf_getshdr (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 ?: __elf32_getshdr_rdlock (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 ?: __elf64_getshdr_rdlock (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..01534d2
--- /dev/null
+++ b/libelf/gelf_getsym.c
@@ -0,0 +1,114 @@
+/* Get symbol information from symbol table at the given index.
+   Copyright (C) 1999, 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Sym *
+gelf_getsym (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 (INVALID_NDX (ndx, Elf32_Sym, data))
+	{
+	  __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 (INVALID_NDX (ndx, GElf_Sym, data))
+	{
+	  __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..8360ed3
--- /dev/null
+++ b/libelf/gelf_getsyminfo.c
@@ -0,0 +1,77 @@
+/* Get additional symbol information from symbol table at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Syminfo *
+gelf_getsyminfo (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 (INVALID_NDX (ndx, GElf_Syminfo, data))
+    {
+      __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..17c90fc
--- /dev/null
+++ b/libelf/gelf_getsymshndx.c
@@ -0,0 +1,136 @@
+/* Get symbol information and separate section index from symbol table
+   at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Sym *
+gelf_getsymshndx (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 (INVALID_NDX (ndx, Elf32_Word, &shndxdata_scn->d))
+	{
+	  __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 (INVALID_NDX (ndx, Elf32_Sym, symdata))
+	{
+	  __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 (INVALID_NDX (ndx, GElf_Sym, symdata))
+	{
+	  __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..739a765
--- /dev/null
+++ b/libelf/gelf_getverdaux.c
@@ -0,0 +1,79 @@
+/* Get additional symbol version definition information at the given offset.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Verdaux *
+gelf_getverdaux (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..651f4fa
--- /dev/null
+++ b/libelf/gelf_getverdef.c
@@ -0,0 +1,78 @@
+/* Get symbol version definition information at the given offset.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Verdef *
+gelf_getverdef (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..e47fb0a
--- /dev/null
+++ b/libelf/gelf_getvernaux.c
@@ -0,0 +1,81 @@
+/* Get additional required symbol version information at the given offset.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Vernaux *
+gelf_getvernaux (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..c1f5d34
--- /dev/null
+++ b/libelf/gelf_getverneed.c
@@ -0,0 +1,81 @@
+/* Get required symbol version information at the given offset.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Verneed *
+gelf_getverneed (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..68d23c7
--- /dev/null
+++ b/libelf/gelf_getversym.c
@@ -0,0 +1,86 @@
+/* Get symbol version information at the given index.
+   Copyright (C) 1999, 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Versym *
+gelf_getversym (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 (INVALID_NDX (ndx, GElf_Versym, data))
+    {
+      __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..2788906
--- /dev/null
+++ b/libelf/gelf_newehdr.c
@@ -0,0 +1,46 @@
+/* Create new ELF header.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+void *
+gelf_newehdr (Elf *elf, int class)
+{
+  return (class == ELFCLASS32
+	  ? (void *) INTUSE(elf32_newehdr) (elf)
+	  : (void *) INTUSE(elf64_newehdr) (elf));
+}
diff --git a/libelf/gelf_newphdr.c b/libelf/gelf_newphdr.c
new file mode 100644
index 0000000..84aad78
--- /dev/null
+++ b/libelf/gelf_newphdr.c
@@ -0,0 +1,46 @@
+/* Create new ELF program header.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+void *
+gelf_newphdr ( Elf *elf, size_t phnum)
+{
+  return (elf->class == ELFCLASS32
+	  ? (void *) INTUSE(elf32_newphdr) (elf, phnum)
+	  : (void *) INTUSE(elf64_newphdr) (elf, phnum));
+}
diff --git a/libelf/gelf_offscn.c b/libelf/gelf_offscn.c
new file mode 100644
index 0000000..cf206f5
--- /dev/null
+++ b/libelf/gelf_offscn.c
@@ -0,0 +1,55 @@
+/* Create new ELF header.
+   Copyright (C) 2005, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+Elf_Scn *
+gelf_offscn (Elf *elf, GElf_Off offset)
+{
+  if (elf->class == ELFCLASS32)
+    {
+      if ((Elf32_Off) offset != offset)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_OFFSET);
+	  return NULL;
+	}
+
+      return INTUSE(elf32_offscn) (elf, (Elf32_Off) offset);
+    }
+
+  return INTUSE(elf64_offscn) (elf, offset);
+}
diff --git a/libelf/gelf_update_auxv.c b/libelf/gelf_update_auxv.c
new file mode 100644
index 0000000..e4e5229
--- /dev/null
+++ b/libelf/gelf_update_auxv.c
@@ -0,0 +1,111 @@
+/* Update information in dynamic table at the given index.
+   Copyright (C) 2007, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_auxv (Elf_Data *data, int ndx, GElf_auxv_t *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_AUXV))
+    {
+      /* 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_auxv_t *auxv;
+
+      /* There is the possibility that the values in the input are
+	 too large.  */
+      if (unlikely (src->a_type > 0xffffffffll)
+	  || unlikely (src->a_un.a_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_auxv_t) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      auxv = &((Elf32_auxv_t *) data_scn->d.d_buf)[ndx];
+
+      auxv->a_type = src->a_type;
+      auxv->a_un.a_val = src->a_un.a_val;
+    }
+  else
+    {
+      /* Check whether we have to resize the data buffer.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf64_auxv_t) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      ((Elf64_auxv_t *) 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_dyn.c b/libelf/gelf_update_dyn.c
new file mode 100644
index 0000000..5c515d2
--- /dev/null
+++ b/libelf/gelf_update_dyn.c
@@ -0,0 +1,107 @@
+/* Update information in dynamic table at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_dyn (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 (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 (INVALID_NDX (ndx, Elf32_Dyn, &data_scn->d))
+	{
+	  __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 (INVALID_NDX (ndx, Elf64_Dyn, &data_scn->d))
+	{
+	  __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..73d5af7
--- /dev/null
+++ b/libelf/gelf_update_ehdr.c
@@ -0,0 +1,118 @@
+/* Update ELF header.
+   Copyright (C) 2000, 2001, 2002, 2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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));
+    }
+
+  /* Mark the ELF header as modified.  */
+  elf->state.elf.ehdr_flags |= ELF_F_DIRTY;
+
+  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..d0f235e
--- /dev/null
+++ b/libelf/gelf_update_lib.c
@@ -0,0 +1,75 @@
+/* Update library in table at the given index.
+   Copyright (C) 2004, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_lib (Elf_Data *data, int ndx, GElf_Lib *src)
+{
+  if (data == NULL)
+    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 (INVALID_NDX (ndx, Elf64_Lib, &data_scn->d))
+    __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..4190ee3
--- /dev/null
+++ b/libelf/gelf_update_move.c
@@ -0,0 +1,77 @@
+/* Update move structure at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_move (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 (INVALID_NDX (ndx, GElf_Move, &data_scn->d))
+    {
+      __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..a848677
--- /dev/null
+++ b/libelf/gelf_update_phdr.c
@@ -0,0 +1,143 @@
+/* Update program header program header table entry.
+   Copyright (C) 2000-2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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 = __elf32_getphdr_wrlock (elf);
+	  if (phdr == NULL)
+	    /* The error number is already set.  */
+	    goto out;
+	}
+
+      /* Test whether the index is ok.  */
+      size_t phnum;
+      if (ndx >= elf->state.elf32.ehdr->e_phnum
+	  && (elf->state.elf32.ehdr->e_phnum != PN_XNUM
+	      || __elf_getphdrnum_rdlock (elf, &phnum) != 0
+	      || (size_t) ndx >= 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 = __elf64_getphdr_wrlock (elf);
+	  if (phdr == NULL)
+	    /* The error number is already set.  */
+	    goto out;
+	}
+
+      /* Test whether the index is ok.  */
+      size_t phnum;
+      if (ndx >= elf->state.elf64.ehdr->e_phnum
+	  && (elf->state.elf64.ehdr->e_phnum != PN_XNUM
+	      || __elf_getphdrnum_rdlock (elf, &phnum) != 0
+	      || (size_t) ndx >= phnum))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      /* Just copy the data.  */
+      memcpy (phdr + ndx, src, sizeof (Elf64_Phdr));
+    }
+
+  /* Mark the program header as modified.  */
+  elf->state.elf.phdr_flags |= ELF_F_DIRTY;
+
+  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..14f62e9
--- /dev/null
+++ b/libelf/gelf_update_rel.c
@@ -0,0 +1,108 @@
+/* Update REL relocation information at given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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 (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 (INVALID_NDX (ndx, Elf32_Rel, &data_scn->d))
+	{
+	  __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 (INVALID_NDX (ndx, Elf64_Rel, &data_scn->d))
+	{
+	  __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..8825270
--- /dev/null
+++ b/libelf/gelf_update_rela.c
@@ -0,0 +1,111 @@
+/* Update RELA relocation information at given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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 (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 (INVALID_NDX (ndx, Elf32_Rela, &data_scn->d))
+	{
+	  __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 (INVALID_NDX (ndx, Elf64_Rela, &data_scn->d))
+	{
+	  __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..c93c6ec
--- /dev/null
+++ b/libelf/gelf_update_shdr.c
@@ -0,0 +1,111 @@
+/* Update section header.
+   Copyright (C) 2000, 2001, 2002, 2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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 ?: __elf32_getshdr_wrlock (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 ?: __elf64_getshdr_wrlock (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));
+    }
+
+  /* Mark the section header as modified.  */
+  scn->shdr_flags |= ELF_F_DIRTY;
+
+  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..0f47885
--- /dev/null
+++ b/libelf/gelf_update_sym.c
@@ -0,0 +1,116 @@
+/* Update symbol information in symbol table at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_sym (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 (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 (INVALID_NDX (ndx, Elf32_Sym, &data_scn->d))
+	{
+	  __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 (INVALID_NDX (ndx, Elf64_Sym, &data_scn->d))
+	{
+	  __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..6f7f302
--- /dev/null
+++ b/libelf/gelf_update_syminfo.c
@@ -0,0 +1,83 @@
+/* Update additional symbol information in symbol table at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_syminfo (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 (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 (INVALID_NDX (ndx, GElf_Syminfo, &data_scn->d))
+    {
+      __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..eb80afa
--- /dev/null
+++ b/libelf/gelf_update_symshndx.c
@@ -0,0 +1,145 @@
+/* Update symbol information and section index in symbol table at the
+   given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_symshndx (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 (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 (INVALID_NDX (ndx, Elf32_Sym, &symdata_scn->d))
+	{
+	  __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 (INVALID_NDX (ndx, Elf64_Sym, &symdata_scn->d))
+	{
+	  __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..f3554fd
--- /dev/null
+++ b/libelf/gelf_update_verdaux.c
@@ -0,0 +1,78 @@
+/* Update additional symbol version definition information.
+   Copyright (C) 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_verdaux (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..adb5db1
--- /dev/null
+++ b/libelf/gelf_update_verdef.c
@@ -0,0 +1,78 @@
+/* Update symbol version definition information.
+   Copyright (C) 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_verdef (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..854afab
--- /dev/null
+++ b/libelf/gelf_update_vernaux.c
@@ -0,0 +1,78 @@
+/* Update additional required symbol version information.
+   Copyright (C) 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_vernaux (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..bf5af5a
--- /dev/null
+++ b/libelf/gelf_update_verneed.c
@@ -0,0 +1,78 @@
+/* Update required symbol version information.
+   Copyright (C) 2001, 2002, 201r Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_verneed (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..9949dff
--- /dev/null
+++ b/libelf/gelf_update_versym.c
@@ -0,0 +1,77 @@
+/* Update symbol version information.
+   Copyright (C) 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_versym (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 (INVALID_NDX (ndx, GElf_Versym, &data_scn->d))
+    {
+      __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..479f143
--- /dev/null
+++ b/libelf/gelf_xlate.c
@@ -0,0 +1,217 @@
+/* Transformation functions for ELF data types.
+   Copyright (C) 1998,1999,2000,2002,2004,2005,2006,2007,2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <byteswap.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.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)))
+{
+  if (n != 0)
+    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.  */
+
+#if ALLOW_UNALIGNED
+
+#define FETCH(Bits, ptr)	(*(const uint##Bits##_t *) ptr)
+#define STORE(Bits, ptr, val)	(*(uint##Bits##_t *) ptr = val)
+
+#else
+
+union unaligned
+  {
+    uint16_t u16;
+    uint32_t u32;
+    uint64_t u64;
+  } attribute_packed;
+
+#define FETCH(Bits, ptr)	(((const union unaligned *) ptr)->u##Bits)
+#define STORE(Bits, ptr, val)	(((union unaligned *) ptr)->u##Bits = val)
+
+#endif
+
+/* 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 inline void FName##1 (void *dest, const void *ptr)		      \
+  {									      \
+    switch (Bytes)							      \
+      {									      \
+      case 2: STORE (16, dest, bswap_16 (FETCH (16, ptr))); break;	      \
+      case 4: STORE (32, dest, bswap_32 (FETCH (32, ptr))); break;	      \
+      case 8: STORE (64, dest, bswap_64 (FETCH (64, ptr))); break;	      \
+      default:								      \
+	abort ();							      \
+      }									      \
+  }									      \
+									      \
+  static void FName (void *dest, const void *ptr, size_t len,		      \
+		     int encode __attribute__ ((unused)))		      \
+  {									      \
+    size_t n = len / sizeof (TName);					      \
+    if (dest < ptr)							      \
+      while (n-- > 0)							      \
+	{								      \
+	  FName##1 (dest, ptr);						      \
+	  dest += Bytes;						      \
+	  ptr += Bytes;							      \
+	}								      \
+    else								      \
+      {									      \
+	dest += len;							      \
+	ptr += len;							      \
+	while (n-- > 0)							      \
+	  {								      \
+	    ptr -= Bytes;						      \
+	    dest -= Bytes;						      \
+	    FName##1 (dest, 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"
+#include "gnuhash_xlate.h"
+#include "note_xlate.h"
+#include "chdr_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]	= elf_cvt_note,					      \
+	[ELF_T_SYMINFO] = ElfW2(Bits, cvt_Syminfo),			      \
+	[ELF_T_MOVE]	= ElfW2(Bits, cvt_Move),			      \
+	[ELF_T_LIB]	= ElfW2(Bits, cvt_Lib),				      \
+	[ELF_T_AUXV]	= ElfW2(Bits, cvt_auxv_t),			      \
+	[ELF_T_CHDR]	= ElfW2(Bits, cvt_chdr)
+        define_xfcts (32),
+	[ELF_T_GNUHASH] = Elf32_cvt_Word
+      },
+      [ELFCLASS64 - 1] = {
+	define_xfcts (64),
+	[ELF_T_GNUHASH] = elf_cvt_gnuhash
+      }
+    }
+  }
+};
+/* 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..3c0e4bf
--- /dev/null
+++ b/libelf/gelf_xlate.h
@@ -0,0 +1,57 @@
+/* Helper file for type conversion function generation.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2007 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+
+/* 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)
+TYPE (auxv_t, LIBELFBITS)
+TYPE (Chdr, 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..e266180
--- /dev/null
+++ b/libelf/gelf_xlatetof.c
@@ -0,0 +1,50 @@
+/* Convert from memory to file representation.  Generic ELF version.
+   Copyright (C) 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Data *
+gelf_xlatetof (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..8499c71
--- /dev/null
+++ b/libelf/gelf_xlatetom.c
@@ -0,0 +1,50 @@
+/* Convert from file to memory representation.  Generic ELF version.
+   Copyright (C) 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Data *
+gelf_xlatetom (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/gnuhash_xlate.h b/libelf/gnuhash_xlate.h
new file mode 100644
index 0000000..6faf113
--- /dev/null
+++ b/libelf/gnuhash_xlate.h
@@ -0,0 +1,74 @@
+/* Conversion functions for versioning information.
+   Copyright (C) 2006, 2007 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2006.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <gelf.h>
+
+#include "libelfP.h"
+
+
+static void
+elf_cvt_gnuhash (void *dest, const void *src, size_t len, int encode)
+{
+  /* The GNU hash table format on 64 bit machines mixes 32 bit and 64 bit
+     words.  We must detangle them here.   */
+  Elf32_Word *dest32 = dest;
+  const Elf32_Word *src32 = src;
+
+  /* First four control words, 32 bits.  */
+  for (unsigned int cnt = 0; cnt < 4; ++cnt)
+    {
+      if (len < 4)
+	return;
+      dest32[cnt] = bswap_32 (src32[cnt]);
+      len -= 4;
+    }
+
+  Elf32_Word bitmask_words = encode ? src32[2] : dest32[2];
+
+  /* Now the 64 bit words.  */
+  Elf64_Xword *dest64 = (Elf64_Xword *) &dest32[4];
+  const Elf64_Xword *src64 = (const Elf64_Xword *) &src32[4];
+  for (unsigned int cnt = 0; cnt < bitmask_words; ++cnt)
+    {
+      if (len < 8)
+	return;
+      dest64[cnt] = bswap_64 (src64[cnt]);
+      len -= 8;
+    }
+
+  /* The rest are 32 bit words again.  */
+  src32 = (const Elf32_Word *) &src64[bitmask_words];
+  dest32 = (Elf32_Word *) &dest64[bitmask_words];
+  while (len >= 4)
+    {
+      *dest32++ = bswap_32 (*src32++);
+      len -= 4;
+    }
+}
diff --git a/libelf/libelf.h b/libelf/libelf.h
new file mode 100644
index 0000000..547c0f5
--- /dev/null
+++ b/libelf/libelf.h
@@ -0,0 +1,515 @@
+/* Interface for libelf.
+   Copyright (C) 1998-2010, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBELF_H
+#define _LIBELF_H 1
+
+#include <stdint.h>
+#include <sys/types.h>
+
+/* Get the ELF types.  */
+#include <elf.h>
+
+#ifndef SHF_COMPRESSED
+ /* Older glibc elf.h might not yet define the ELF compression types.  */
+ #define SHF_COMPRESSED      (1 << 11)  /* Section with compressed data. */
+
+ /* Section compression header.  Used when SHF_COMPRESSED is set.  */
+
+ typedef struct
+ {
+   Elf32_Word   ch_type;        /* Compression format.  */
+   Elf32_Word   ch_size;        /* Uncompressed data size.  */
+   Elf32_Word   ch_addralign;   /* Uncompressed data alignment.  */
+ } Elf32_Chdr;
+
+ typedef struct
+ {
+   Elf64_Word   ch_type;        /* Compression format.  */
+   Elf64_Word   ch_reserved;
+   Elf64_Xword  ch_size;        /* Uncompressed data size.  */
+   Elf64_Xword  ch_addralign;   /* Uncompressed data alignment.  */
+ } Elf64_Chdr;
+
+ /* Legal values for ch_type (compression algorithm).  */
+ #define ELFCOMPRESS_ZLIB       1          /* ZLIB/DEFLATE algorithm.  */
+ #define ELFCOMPRESS_LOOS       0x60000000 /* Start of OS-specific.  */
+ #define ELFCOMPRESS_HIOS       0x6fffffff /* End of OS-specific.  */
+ #define ELFCOMPRESS_LOPROC     0x70000000 /* Start of processor-specific.  */
+ #define ELFCOMPRESS_HIPROC     0x7fffffff /* End of processor-specific.  */
+#endif
+
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
+# define __nonnull_attribute__(...) __attribute__ ((__nonnull__ (__VA_ARGS__)))
+# define __deprecated_attribute__ __attribute__ ((__deprecated__))
+# define __pure_attribute__ __attribute__ ((__pure__))
+# define __const_attribute__ __attribute__ ((__const__))
+#else
+# define __nonnull_attribute__(...)
+# define __deprecated_attribute__
+# define __pure_attribute__
+# define __const_attribute__
+#endif
+
+#if __GNUC__ < 4
+#define __noreturn_attribute__
+#else
+#define __noreturn_attribute__ __attribute__ ((noreturn))
+#endif
+
+#ifdef __GNUC_STDC_INLINE__
+# define __libdw_extern_inline extern __inline __attribute__ ((__gnu_inline__))
+#else
+# define __libdw_extern_inline extern __inline
+#endif
+
+/* 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, ... */
+  ELF_T_GNUHASH,		/* GNU-style hash section.  */
+  ELF_T_AUXV,			/* Elf32_auxv_t, Elf64_auxv_t, ... */
+  ELF_T_CHDR,			/* Compressed, Elf32_Chdr, Elf64_Chdr, ... */
+  /* 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.  */
+  int64_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
+};
+
+/* Flags for elf_compress[_gnu].  */
+enum
+{
+  ELF_CHF_FORCE = 0x1
+#define ELF_CHF_FORCE ELF_CHF_FORCE
+};
+
+/* 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.  */
+  int64_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 int64_t elf_update (Elf *__elf, Elf_Cmd __cmd);
+
+/* Determine what kind of file is associated with ELF.  */
+extern Elf_Kind elf_kind (Elf *__elf) __pure_attribute__;
+
+/* Get the base offset for an object file.  */
+extern int64_t elf_getbase (Elf *__elf);
+
+
+/* Retrieve file identification data.  */
+extern char *elf_getident (Elf *__elf, size_t *__nbytes);
+
+/* 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);
+
+/* Get the number of program headers in the ELF file.  If the file uses
+   more headers than can be represented in the e_phnum field of the ELF
+   header the information from the sh_info field in the zeroth section
+   header is used.  */
+extern int elf_getphdrnum (Elf *__elf, size_t *__dst);
+
+/* 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 section at OFFSET.  */
+extern Elf_Scn *elf32_offscn (Elf *__elf, Elf32_Off __offset);
+/* Similar bug this time the binary calls is ELFCLASS64.  */
+extern Elf_Scn *elf64_offscn (Elf *__elf, Elf64_Off __offset);
+
+/* 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 section index of the extended section index table for the
+   given symbol table.  */
+extern int elf_scnshndx (Elf_Scn *__scn);
+
+/* 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_getshdrnum (Elf *__elf, size_t *__dst);
+/* Sun messed up the implementation of 'elf_getshnum' in their implementation.
+   It was agreed to make the same functionality available under a different
+   name and obsolete the old name.  */
+extern int elf_getshnum (Elf *__elf, size_t *__dst)
+     __deprecated_attribute__;
+
+
+/* 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_getshdrstrndx (Elf *__elf, size_t *__dst);
+/* Sun messed up the implementation of 'elf_getshnum' in their implementation.
+   It was agreed to make the same functionality available under a different
+   name and obsolete the old name.  */
+extern int elf_getshstrndx (Elf *__elf, size_t *__dst)
+     __deprecated_attribute__;
+
+
+/* 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);
+
+/* Returns compression header for a section if section data is
+   compressed.  Returns NULL and sets elf_errno if the section isn't
+   compressed or an error occurred.  */
+extern Elf32_Chdr *elf32_getchdr (Elf_Scn *__scn);
+extern Elf64_Chdr *elf64_getchdr (Elf_Scn *__scn);
+
+/* Compress or decompress the data of a section and adjust the section
+   header.
+
+   elf_compress works by setting or clearing the SHF_COMPRESS flag
+   from the section Shdr and will encode or decode a Elf32_Chdr or
+   Elf64_Chdr at the start of the section data.  elf_compress_gnu will
+   encode or decode any section, but is traditionally only used for
+   sections that have a name starting with ".debug" when
+   uncompressed or ".zdebug" when compressed and stores just the
+   uncompressed size.  The GNU compression method is deprecated and
+   should only be used for legacy support.
+
+   elf_compress takes a compression type that should be either zero to
+   decompress or an ELFCOMPRESS algorithm to use for compression.
+   Currently only ELFCOMPRESS_ZLIB is supported.  elf_compress_gnu
+   will compress in the traditional GNU compression format when
+   compress is one and decompress the section data when compress is
+   zero.
+
+   The FLAGS argument can be zero or ELF_CHF_FORCE.  If FLAGS contains
+   ELF_CHF_FORCE then it will always compress the section, even if
+   that would not reduce the size of the data section (including the
+   header).  Otherwise elf_compress and elf_compress_gnu will compress
+   the section only if the total data size is reduced.
+
+   On successful compression or decompression the function returns
+   one.  If (not forced) compression is requested and the data section
+   would not actually reduce in size, the section is not actually
+   compressed and zero is returned.  Otherwise -1 is returned and
+   elf_errno is set.
+
+   It is an error to request compression for a section that already
+   has SHF_COMPRESSED set, or (for elf_compress) to request
+   decompression for an section that doesn't have SHF_COMPRESSED set.
+   It is always an error to call these functions on SHT_NOBITS
+   sections or if the section has the SHF_ALLOC flag set.
+   elf_compress_gnu will not check whether the section name starts
+   with ".debug" or .zdebug".  It is the responsibilty of the caller
+   to make sure the deprecated GNU compression method is only called
+   on correctly named sections (and to change the name of the section
+   when using elf_compress_gnu).
+
+   All previous returned Shdrs and Elf_Data buffers are invalidated by
+   this call and should no longer be accessed.
+
+   Note that although this changes the header and data returned it
+   doesn't mark the section as dirty.  To keep the changes when
+   calling elf_update the section has to be flagged ELF_F_DIRTY.  */
+extern int elf_compress (Elf_Scn *scn, int type, unsigned int flags);
+extern int elf_compress_gnu (Elf_Scn *scn, int compress, unsigned int flags);
+
+/* 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.  The Elf_Data d_type is set based on the
+   section type if known.  Otherwise d_type is set to ELF_T_BYTE.  If
+   the section contains compressed data then d_type is always set to
+   ELF_T_CHDR.  */
+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);
+
+/* Get data translated from a chunk of the file contents as section data
+   would be for TYPE.  The resulting Elf_Data pointer is valid until
+   elf_end (ELF) is called.  */
+extern Elf_Data *elf_getdata_rawchunk (Elf *__elf,
+				       int64_t __offset, size_t __size,
+				       Elf_Type __type);
+
+
+/* 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);
+
+/* Return offset in archive for current file ELF.  */
+extern int64_t elf_getaroff (Elf *__elf);
+
+/* Select archive element at OFFSET.  */
+extern size_t elf_rand (Elf *__elf, size_t __offset);
+
+/* Get symbol table of archive.  */
+extern Elf_Arsym *elf_getarsym (Elf *__elf, size_t *__narsyms);
+
+
+/* Control ELF descriptor.  */
+extern int elf_cntl (Elf *__elf, Elf_Cmd __cmd);
+
+/* Retrieve uninterpreted file contents.  */
+extern char *elf_rawfile (Elf *__elf, size_t *__nbytes);
+
+
+/* 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)
+       __const_attribute__;
+/* Similar but this time the binary calls is ELFCLASS64.  */
+extern size_t elf64_fsize (Elf_Type __type, size_t __count,
+			   unsigned int __version)
+       __const_attribute__;
+
+
+/* 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)
+       __pure_attribute__;
+
+/* Compute hash value using the GNU-specific hash function.  */
+extern unsigned long int elf_gnu_hash (const char *__string)
+       __pure_attribute__;
+
+
+/* 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..10dc505
--- /dev/null
+++ b/libelf/libelf.map
@@ -0,0 +1,150 @@
+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_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_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;
+
+ELFUTILS_1.1.1 {
+  global:
+    elf32_offscn;
+    elf64_offscn;
+    gelf_offscn;
+    elf_getaroff;
+} ELFUTILS_1.1;
+
+ELFUTILS_1.2 {
+  global:
+    elf_gnu_hash;
+} ELFUTILS_1.1.1;
+
+ELFUTILS_1.3 {
+  global:
+    elf_getdata_rawchunk;
+    gelf_getauxv;
+    gelf_update_auxv;
+    gelf_getnote;
+} ELFUTILS_1.2;
+
+ELFUTILS_1.4 {
+  global:
+    elf_scnshndx;
+} ELFUTILS_1.3;
+
+ELFUTILS_1.5 {
+  global:
+    elf_getshdrnum; elf_getshdrstrndx;
+} ELFUTILS_1.4;
+
+ELFUTILS_1.6 {
+  global:
+    elf_getphdrnum;
+} ELFUTILS_1.5;
+
+ELFUTILS_1.7 {
+  global:
+    elf32_getchdr;
+    elf64_getchdr;
+    gelf_getchdr;
+
+    elf_compress;
+    elf_compress_gnu;
+} ELFUTILS_1.6;
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
new file mode 100644
index 0000000..ca805ac
--- /dev/null
+++ b/libelf/libelfP.h
@@ -0,0 +1,638 @@
+/* Internal interfaces for libelf.
+   Copyright (C) 1998-2010, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBELFP_H
+#define _LIBELFP_H 1
+
+#include <ar.h>
+#include <gelf.h>
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+/* gettext helper macros.  */
+#define _(Str) dgettext ("elfutils", 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_ELF,
+  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,
+  ELF_E_INVALID_OFFSET,
+  ELF_E_INVALID_SECTION_TYPE,
+  ELF_E_INVALID_SECTION_FLAGS,
+  ELF_E_NOT_COMPRESSED,
+  ELF_E_ALREADY_COMPRESSED,
+  ELF_E_UNKNOWN_COMPRESSION_TYPE,
+  ELF_E_COMPRESS_ERROR,
+  ELF_E_DECOMPRESS_ERROR,
+  /* 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.  */
+  int shndx_index;		/* Index of the extended section index
+				   table for this symbol table (if this
+				   section is a symbol table).  */
+
+  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?
+				   ELF_F_MALLOCED for a Elf_Data_Chunk
+				   dummy_scn means the rawchunks
+				   data.d.d_buf was malloced. For normal
+				   sections it means rawdata_base was
+				   malloced (by elf_compress) even if
+				   the Elf was mmapped.  */
+
+  char *rawdata_base;		/* The unmodified data of the section.  */
+  char *data_base;		/* The converted data of the section.  */
+
+  char *zdata_base;		/* The uncompressed data of the section.  */
+  size_t zdata_size;		/* If zdata_base != NULL, the size of data.  */
+  size_t zdata_align;		/* If zdata_base != NULL, the addralign.  */
+
+  struct Elf_ScnList *list;	/* Pointer to 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;
+
+
+/* elf_getdata_rawchunk result.  */
+typedef struct Elf_Data_Chunk
+{
+  Elf_Data_Scn data;
+  union
+  {
+    Elf_Scn dummy_scn;
+    struct Elf_Data_Chunk *next;
+  };
+} Elf_Data_Chunk;
+
+
+/* The ELF descriptor.  */
+struct Elf
+{
+  /* Address to which the file was mapped.  NULL if not mapped.  */
+  void *map_address;
+
+  /* When created for an archive member this points to the descriptor
+     for the archive. */
+  Elf *parent;
+  Elf *next;             /* Used in list of archive descriptors.  */
+
+  /* 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;
+
+  /* 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;
+
+  /* Reference counting for the descriptor.  */
+  int ref_count;
+
+  /* Lock to handle multithreaded programs.  */
+  rwlock_define (,lock);
+
+  union
+  {
+    struct
+    {
+      /* 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.  */
+      Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results.  */
+      unsigned int scnincr;	/* Number of sections allocate the last
+				   time.  */
+      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.  */
+      off_t sizestr_offset;	/* Offset of the size string in the parent
+				   if this is an archive member.  */
+    } elf;
+
+    struct
+    {
+      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.  */
+      Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results.  */
+      unsigned int scnincr;	/* Number of sections allocate the last
+				   time.  */
+      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.  */
+      off_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
+    {
+      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.  */
+      Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results.  */
+      unsigned int scnincr;	/* Number of sections allocate the last
+				   time.  */
+      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.  */
+      off_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
+    {
+      Elf *children;		/* List of all descriptors for this archive. */
+      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.  */
+    } 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;
+
+/* Index for __libelf_type_sizes et al.  */
+#if EV_NUM == 2
+# define LIBELF_EV_IDX	0
+#else
+# define LIBELF_EV_IDX	(__libelf_version - 1)
+#endif
+
+#if !ALLOW_UNALIGNED
+/* Array with alignment requirements of the internal types indexed by ELF
+   version, binary class, and type. */
+extern const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
+# define __libelf_type_align(class, type)	\
+    (__libelf_type_aligns[LIBELF_EV_IDX][class - 1][type] ?: 1)
+#else
+# define __libelf_type_align(class, type)	1
+#endif
+
+/* Given an Elf handle and a section type returns the Elf_Data d_type.
+   Should not be called when SHF_COMPRESSED is set, the d_type should
+   be ELF_T_BYTE.  */
+extern Elf_Type __libelf_data_type (Elf *elf, int sh_type) internal_function;
+
+/* 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_wrlock (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;
+extern int __libelf_set_rawdata_wrlock (Elf_Scn *scn) internal_function;
+
+
+/* Helper functions for elf_update.  */
+extern off_t __elf32_updatenull_wrlock (Elf *elf, int *change_bop,
+					size_t shnum) internal_function;
+extern off_t __elf64_updatenull_wrlock (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, and
+   rdlock/wrlock variants of these functions.  */
+extern int __elf_end_internal (Elf *__elf) attribute_hidden;
+extern Elf *__elf_begin_internal (int __fildes, Elf_Cmd __cmd, Elf *__ref)
+     attribute_hidden;
+extern Elf32_Ehdr *__elf32_getehdr_wrlock (Elf *__elf) internal_function;
+extern Elf64_Ehdr *__elf64_getehdr_wrlock (Elf *__elf) internal_function;
+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_getphdr_wrlock (Elf *__elf) attribute_hidden;
+extern Elf64_Phdr *__elf64_getphdr_wrlock (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 Elf_Scn *__elf32_offscn_internal (Elf *__elf, Elf32_Off __offset)
+     attribute_hidden;
+extern Elf_Scn *__elf64_offscn_internal (Elf *__elf, Elf64_Off __offset)
+     attribute_hidden;
+extern int __elf_getphdrnum_rdlock (Elf *__elf, size_t *__dst)
+     internal_function;
+extern int __elf_getphdrnum_chk_rdlock (Elf *__elf, size_t *__dst)
+     internal_function;
+extern int __elf_getshdrnum_rdlock (Elf *__elf, size_t *__dst)
+     internal_function;
+extern int __elf_getshdrstrndx_internal (Elf *__elf, size_t *__dst)
+     attribute_hidden;
+extern Elf32_Shdr *__elf32_getshdr_rdlock (Elf_Scn *__scn) internal_function;
+extern Elf64_Shdr *__elf64_getshdr_rdlock (Elf_Scn *__scn) internal_function;
+extern Elf32_Shdr *__elf32_getshdr_wrlock (Elf_Scn *__scn) internal_function;
+extern Elf64_Shdr *__elf64_getshdr_wrlock (Elf_Scn *__scn) internal_function;
+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 int __elf_scnshndx_internal (Elf_Scn *__scn) attribute_hidden;
+extern Elf_Data *__elf_getdata_internal (Elf_Scn *__scn, Elf_Data *__data)
+     attribute_hidden;
+extern Elf_Data *__elf_getdata_rdlock (Elf_Scn *__scn, Elf_Data *__data)
+     internal_function;
+extern Elf_Data *__elf_rawdata_internal (Elf_Scn *__scn, Elf_Data *__data)
+     attribute_hidden;
+/* Should be called to setup first section data element if
+   data_list_rear is NULL and we know data_read is set and there is
+   raw data available.  Might upgrade the ELF lock from a read to a
+   write lock.  If the lock is already a write lock set wrlocked.  */
+extern void __libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked)
+     internal_function;
+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__)) attribute_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_rdlock (Elf *__elf, GElf_Ehdr *__dest)
+     internal_function;
+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;
+
+extern void * __libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data,
+				 size_t *orig_size, size_t *orig_addralign,
+				 size_t *size, bool force)
+     internal_function;
+
+extern void * __libelf_decompress (void *buf_in, size_t size_in,
+				   size_t size_out) internal_function;
+extern void * __libelf_decompress_elf (Elf_Scn *scn,
+				       size_t *size_out, size_t *addralign)
+     internal_function;
+
+
+extern void __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size,
+				    size_t align, Elf_Type type)
+     internal_function;
+
+
+/* We often have to update a flag iff a value changed.  Make this
+   convenient.  */
+#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)
+
+/* Align offset to 4 bytes as needed for note name and descriptor data.  */
+#define NOTE_ALIGN(n)	(((n) + 3) & -4U)
+
+/* Convenience macro.  */
+#define INVALID_NDX(ndx, type, data) \
+  unlikely ((data)->d_size / sizeof (type) <= (unsigned int) (ndx))
+
+#endif  /* libelfP.h */
diff --git a/libelf/libelf_crc32.c b/libelf/libelf_crc32.c
new file mode 100644
index 0000000..1426faf
--- /dev/null
+++ b/libelf/libelf_crc32.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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..05229c3
--- /dev/null
+++ b/libelf/libelf_next_prime.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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..c7b32fd
--- /dev/null
+++ b/libelf/nlist.c
@@ -0,0 +1,247 @@
+/* Extract symbol list from binary.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2007, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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_fd;
+
+  /* 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);
+      if (unlikely (shdr == NULL))
+	goto fail_close;
+    }
+  /* 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, EV_CURRENT));
+
+  /* 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);
+
+  /* Neither the file descriptor.  */
+  (void) close (fd);
+
+  return 0;
+
+ fail_dealloc:
+  nlist_fshash_fini (table);
+
+ fail_close:
+  /* We do not need the ELF descriptor anymore.  */
+  (void) INTUSE(elf_end) (elf);
+
+ fail_fd:
+  /* Neither the file descriptor.  */
+  (void) close (fd);
+
+ 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..5990918
--- /dev/null
+++ b/libelf/nlist.h
@@ -0,0 +1,56 @@
+/* Interface for nlist.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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/note_xlate.h b/libelf/note_xlate.h
new file mode 100644
index 0000000..62c6f63
--- /dev/null
+++ b/libelf/note_xlate.h
@@ -0,0 +1,64 @@
+/* Conversion functions for notes.
+   Copyright (C) 2007, 2009, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+static void
+elf_cvt_note (void *dest, const void *src, size_t len, int encode)
+{
+  assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
+
+  while (len >= sizeof (Elf32_Nhdr))
+    {
+      (1 ? Elf32_cvt_Nhdr : Elf64_cvt_Nhdr) (dest, src, sizeof (Elf32_Nhdr),
+					     encode);
+      const Elf32_Nhdr *n = encode ? src : dest;
+      Elf32_Word namesz = NOTE_ALIGN (n->n_namesz);
+      Elf32_Word descsz = NOTE_ALIGN (n->n_descsz);
+
+      len -= sizeof *n;
+      src += sizeof *n;
+      dest += sizeof *n;
+
+      if (namesz > len)
+	break;
+      len -= namesz;
+      if (descsz > len)
+	break;
+      len -= descsz;
+
+      if (src != dest)
+	memcpy (dest, src, namesz + descsz);
+
+      src += namesz + descsz;
+      dest += namesz + descsz;
+    }
+
+    /* Copy opver any leftover data unconcerted.  Probably part of
+       truncated name/desc data.  */
+    if (unlikely (len > 0) && src != dest)
+      memcpy (dest, src, len);
+}
diff --git a/libelf/version_xlate.h b/libelf/version_xlate.h
new file mode 100644
index 0000000..9fe01c6
--- /dev/null
+++ b/libelf/version_xlate.h
@@ -0,0 +1,230 @@
+/* Conversion functions for versioning information.
+   Copyright (C) 1998, 1999, 2000, 2002, 2003, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#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;
+
+  /* Below we rely on the next field offsets to be correct, start by
+     copying over all data as is in case some data isn't translated.
+     We don't want to leave (undefined) garbage in the dest buffer.  */
+  memmove (dest, src, len);
+
+  do
+    {
+      size_t aux_offset;
+      GElf_Verdaux *asrc;
+
+      /* Test for correct offset.  */
+      if (def_offset > len || len - def_offset < sizeof (GElf_Verdef))
+	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 > len || len - aux_offset < sizeof (GElf_Verdaux))
+	    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;
+
+  /* Below we rely on the next field offsets to be correct, start by
+     copying over all data as is in case some data isn't translated.
+     We don't want to leave (undefined) garbage in the dest buffer.  */
+  memmove (dest, src, len);
+
+  do
+    {
+      size_t aux_offset;
+      GElf_Vernaux *asrc;
+
+      /* Test for correct offset.  */
+      if (need_offset > len || len - need_offset < sizeof (GElf_Verneed))
+	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 > len || len - aux_offset < sizeof (GElf_Vernaux))
+	    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);
+}