summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/32.fsize.c155
-rw-r--r--lib/32.getehdr.c56
-rw-r--r--lib/32.getphdr.c56
-rw-r--r--lib/32.getshdr.c58
-rw-r--r--lib/32.newehdr.c80
-rw-r--r--lib/32.newphdr.c118
-rw-r--r--lib/32.xlatetof.c438
-rw-r--r--lib/64.xlatetof.c512
-rw-r--r--lib/Makefile.in278
-rw-r--r--lib/Makefile.w32166
-rw-r--r--lib/assert.c33
-rw-r--r--lib/begin.c429
-rw-r--r--lib/build.bat36
-rw-r--r--lib/byteswap.h95
-rw-r--r--lib/checksum.c178
-rw-r--r--lib/cntl.c71
-rw-r--r--lib/config.h.w32161
-rw-r--r--lib/cook.c501
-rw-r--r--lib/data.c36
-rw-r--r--lib/elf_repl.h996
-rw-r--r--lib/end.c118
-rw-r--r--lib/errmsg.c77
-rw-r--r--lib/errno.c32
-rw-r--r--lib/errors.h100
-rw-r--r--lib/ext_types.h334
-rw-r--r--lib/fill.c29
-rw-r--r--lib/flag.c92
-rw-r--r--lib/gelf.h155
-rw-r--r--lib/gelfehdr.c140
-rw-r--r--lib/gelfphdr.c148
-rw-r--r--lib/gelfshdr.c125
-rw-r--r--lib/gelftrans.c407
-rw-r--r--lib/getarhdr.c37
-rw-r--r--lib/getaroff.c40
-rw-r--r--lib/getarsym.c87
-rw-r--r--lib/getbase.c33
-rw-r--r--lib/getdata.c157
-rw-r--r--lib/getident.c48
-rw-r--r--lib/getscn.c48
-rw-r--r--lib/hash.c38
-rw-r--r--lib/input.c106
-rw-r--r--lib/kind.c33
-rw-r--r--lib/libelf.def82
-rw-r--r--lib/libelf.h305
-rw-r--r--lib/memset.c53
-rw-r--r--lib/ndxscn.c33
-rw-r--r--lib/newdata.c56
-rw-r--r--lib/newscn.c145
-rw-r--r--lib/next.c42
-rw-r--r--lib/nextscn.c54
-rw-r--r--lib/nlist.c253
-rw-r--r--lib/nlist.h48
-rw-r--r--lib/opt.delscn.c205
-rw-r--r--lib/private.h446
-rw-r--r--lib/rand.c43
-rw-r--r--lib/rawdata.c89
-rw-r--r--lib/rawfile.c54
-rw-r--r--lib/strptr.c150
-rw-r--r--lib/swap64.c81
-rw-r--r--lib/sys_elf.h.in130
-rw-r--r--lib/sys_elf.h.w32130
-rw-r--r--lib/update.c1021
-rw-r--r--lib/verdef.h241
-rw-r--r--lib/verdef_32_tof.c53
-rw-r--r--lib/verdef_32_tom.c53
-rw-r--r--lib/verdef_64_tof.c53
-rw-r--r--lib/verdef_64_tom.c53
-rw-r--r--lib/verneed.h245
-rw-r--r--lib/version.c44
-rw-r--r--lib/x.elfext.c190
-rw-r--r--lib/x.movscn.c112
-rw-r--r--lib/x.remscn.c119
72 files changed, 11420 insertions, 0 deletions
diff --git a/lib/32.fsize.c b/lib/32.fsize.c
new file mode 100644
index 0000000..1815fa1
--- /dev/null
+++ b/lib/32.fsize.c
@@ -0,0 +1,155 @@
+/*
+32.fsize.c - implementation of the elf{32,64}_fsize(3) functions.
+Copyright (C) 1995 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+#include <ext_types.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 32.fsize.c,v 1.13 2008/05/23 08:15:33 michael Exp $";
+#endif /* lint */
+
+const size_t
+_elf_fmsize[2][EV_CURRENT - EV_NONE][ELF_T_NUM][2] = {
+ /* ELFCLASS32 */
+ {
+ /* version 1 */
+ {
+ { sizeof(unsigned char), sizeof(unsigned char) },
+ { sizeof(Elf32_Addr), sizeof(__ext_Elf32_Addr) },
+ { sizeof(Elf32_Dyn), sizeof(__ext_Elf32_Dyn) },
+ { sizeof(Elf32_Ehdr), sizeof(__ext_Elf32_Ehdr) },
+ { sizeof(Elf32_Half), sizeof(__ext_Elf32_Half) },
+ { sizeof(Elf32_Off), sizeof(__ext_Elf32_Off) },
+ { sizeof(Elf32_Phdr), sizeof(__ext_Elf32_Phdr) },
+ { sizeof(Elf32_Rela), sizeof(__ext_Elf32_Rela) },
+ { sizeof(Elf32_Rel), sizeof(__ext_Elf32_Rel) },
+ { sizeof(Elf32_Shdr), sizeof(__ext_Elf32_Shdr) },
+ { sizeof(Elf32_Sword), sizeof(__ext_Elf32_Sword) },
+ { sizeof(Elf32_Sym), sizeof(__ext_Elf32_Sym) },
+ { sizeof(Elf32_Word), sizeof(__ext_Elf32_Word) },
+ { 0, 0 }, /* there is no Elf32_Sxword */
+ { 0, 0 }, /* there is no Elf32_Xword */
+ /* XXX: check Solaris values */
+ { 0, 0 }, /* Elf32_Verdef/Verdaux size varies */
+ { 0, 0 }, /* Elf32_Verneed/Vernaux size varies */
+ },
+ },
+#if __LIBELF64
+ /* ELFCLASS64 */
+ {
+ /* version 1 */
+ {
+ { sizeof(unsigned char), sizeof(unsigned char) },
+ { sizeof(Elf64_Addr), sizeof(__ext_Elf64_Addr) },
+ { sizeof(Elf64_Dyn), sizeof(__ext_Elf64_Dyn) },
+ { sizeof(Elf64_Ehdr), sizeof(__ext_Elf64_Ehdr) },
+ { sizeof(Elf64_Half), sizeof(__ext_Elf64_Half) },
+ { sizeof(Elf64_Off), sizeof(__ext_Elf64_Off) },
+ { sizeof(Elf64_Phdr), sizeof(__ext_Elf64_Phdr) },
+ { sizeof(Elf64_Rela), sizeof(__ext_Elf64_Rela) },
+ { sizeof(Elf64_Rel), sizeof(__ext_Elf64_Rel) },
+ { sizeof(Elf64_Shdr), sizeof(__ext_Elf64_Shdr) },
+ { sizeof(Elf64_Sword), sizeof(__ext_Elf64_Sword) },
+ { sizeof(Elf64_Sym), sizeof(__ext_Elf64_Sym) },
+ { sizeof(Elf64_Word), sizeof(__ext_Elf64_Word) },
+ { sizeof(Elf64_Sxword), sizeof(__ext_Elf64_Sxword) },
+ { sizeof(Elf64_Xword), sizeof(__ext_Elf64_Xword) },
+ /* XXX: check Solaris values */
+ { 0, 0 }, /* Elf64_Verdef/Verdaux size varies */
+ { 0, 0 }, /* Elf64_Verneed/Vernaux size varies */
+ },
+ },
+#endif /* __LIBELF64 */
+};
+
+static size_t
+_elf_fsize(unsigned cls, Elf_Type type, unsigned ver) {
+ size_t n = 0;
+
+ if (!valid_version(ver)) {
+ seterr(ERROR_UNKNOWN_VERSION);
+ }
+ else if (!valid_type(type)) {
+ seterr(ERROR_UNKNOWN_TYPE);
+ }
+ else if (!(n = _fsize(cls, ver, type))) {
+ seterr(ERROR_UNKNOWN_TYPE);
+ }
+ return n;
+}
+
+size_t
+elf32_fsize(Elf_Type type, size_t count, unsigned ver) {
+ return count * _elf_fsize(ELFCLASS32, type, ver);
+}
+
+#if __LIBELF64
+
+size_t
+elf64_fsize(Elf_Type type, size_t count, unsigned ver) {
+ return count * _elf_fsize(ELFCLASS64, type, ver);
+}
+
+size_t
+gelf_fsize(Elf *elf, Elf_Type type, size_t count, unsigned ver) {
+ if (elf) {
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ }
+ else if (valid_class(elf->e_class)) {
+ return count * _elf_fsize(elf->e_class, type, ver);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ }
+ return 0;
+}
+
+/*
+ * Extension: report memory size
+ */
+size_t
+gelf_msize(Elf *elf, Elf_Type type, size_t count, unsigned ver) {
+ size_t n;
+
+ if (elf) {
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ }
+ else if (!valid_class(elf->e_class)) {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ else if (!valid_version(ver)) {
+ seterr(ERROR_UNKNOWN_VERSION);
+ }
+ else if (!valid_type(type)) {
+ seterr(ERROR_UNKNOWN_TYPE);
+ }
+ else if (!(n = _msize(elf->e_class, ver, type))) {
+ seterr(ERROR_UNKNOWN_TYPE);
+ }
+ else {
+ return count * n;
+ }
+ }
+ return 0;
+}
+
+#endif /* __LIBELF64 */
diff --git a/lib/32.getehdr.c b/lib/32.getehdr.c
new file mode 100644
index 0000000..5690dd0
--- /dev/null
+++ b/lib/32.getehdr.c
@@ -0,0 +1,56 @@
+/*
+32.getehdr.c - implementation of the elf{32,64}_getehdr(3) functions.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 32.getehdr.c,v 1.9 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+char*
+_elf_getehdr(Elf *elf, unsigned cls) {
+ if (!elf) {
+ return NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ }
+ else if (elf->e_class != cls) {
+ seterr(ERROR_CLASSMISMATCH);
+ }
+ else if (elf->e_ehdr || _elf_cook(elf)) {
+ return elf->e_ehdr;
+ }
+ return NULL;
+}
+
+Elf32_Ehdr*
+elf32_getehdr(Elf *elf) {
+ return (Elf32_Ehdr*)_elf_getehdr(elf, ELFCLASS32);
+}
+
+#if __LIBELF64
+
+Elf64_Ehdr*
+elf64_getehdr(Elf *elf) {
+ return (Elf64_Ehdr*)_elf_getehdr(elf, ELFCLASS64);
+}
+
+#endif /* __LIBELF64 */
diff --git a/lib/32.getphdr.c b/lib/32.getphdr.c
new file mode 100644
index 0000000..c34b8c7
--- /dev/null
+++ b/lib/32.getphdr.c
@@ -0,0 +1,56 @@
+/*
+32.getphdr.c - implementation of the elf{32,64}_getphdr(3) functions.
+Copyright (C) 1995 - 2000 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 32.getphdr.c,v 1.11 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+char*
+_elf_getphdr(Elf *elf, unsigned cls) {
+ if (!elf) {
+ return NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ }
+ else if (elf->e_class != cls) {
+ seterr(ERROR_CLASSMISMATCH);
+ }
+ else if (elf->e_ehdr || _elf_cook(elf)) {
+ return elf->e_phdr;
+ }
+ return NULL;
+}
+
+Elf32_Phdr*
+elf32_getphdr(Elf *elf) {
+ return (Elf32_Phdr*)_elf_getphdr(elf, ELFCLASS32);
+}
+
+#if __LIBELF64
+
+Elf64_Phdr*
+elf64_getphdr(Elf *elf) {
+ return (Elf64_Phdr*)_elf_getphdr(elf, ELFCLASS64);
+}
+
+#endif /* __LIBELF64 */
diff --git a/lib/32.getshdr.c b/lib/32.getshdr.c
new file mode 100644
index 0000000..498cc5a
--- /dev/null
+++ b/lib/32.getshdr.c
@@ -0,0 +1,58 @@
+/*
+32.getshdr.c - implementation of the elf{32,64}_getshdr(3) functions.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 32.getshdr.c,v 1.10 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+Elf32_Shdr*
+elf32_getshdr(Elf_Scn *scn) {
+ if (!scn) {
+ return NULL;
+ }
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ elf_assert(scn->s_elf);
+ elf_assert(scn->s_elf->e_magic == ELF_MAGIC);
+ if (scn->s_elf->e_class == ELFCLASS32) {
+ return &scn->s_shdr32;
+ }
+ seterr(ERROR_CLASSMISMATCH);
+ return NULL;
+}
+
+#if __LIBELF64
+
+Elf64_Shdr*
+elf64_getshdr(Elf_Scn *scn) {
+ if (!scn) {
+ return NULL;
+ }
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ elf_assert(scn->s_elf);
+ elf_assert(scn->s_elf->e_magic == ELF_MAGIC);
+ if (scn->s_elf->e_class == ELFCLASS64) {
+ return &scn->s_shdr64;
+ }
+ seterr(ERROR_CLASSMISMATCH);
+ return NULL;
+}
+
+#endif /* __LIBELF64 */
diff --git a/lib/32.newehdr.c b/lib/32.newehdr.c
new file mode 100644
index 0000000..fd59fb7
--- /dev/null
+++ b/lib/32.newehdr.c
@@ -0,0 +1,80 @@
+/*
+ * 32.newehdr.c - implementation of the elf{32,64}_newehdr(3) functions.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 32.newehdr.c,v 1.16 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+static char*
+_elf_newehdr(Elf *elf, unsigned cls) {
+ size_t size;
+
+ if (!elf) {
+ return NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (elf->e_readable) {
+ return _elf_getehdr(elf, cls);
+ }
+ else if (!elf->e_ehdr) {
+ size = _msize(cls, _elf_version, ELF_T_EHDR);
+ elf_assert(size);
+ if ((elf->e_ehdr = (char*)malloc(size))) {
+ memset(elf->e_ehdr, 0, size);
+ elf->e_ehdr_flags |= ELF_F_DIRTY;
+ elf->e_kind = ELF_K_ELF;
+ elf->e_class = cls;
+ return elf->e_ehdr;
+ }
+ seterr(ERROR_MEM_EHDR);
+ }
+ else if (elf->e_class != cls) {
+ seterr(ERROR_CLASSMISMATCH);
+ }
+ else {
+ elf_assert(elf->e_kind == ELF_K_ELF);
+ return elf->e_ehdr;
+ }
+ return NULL;
+}
+
+Elf32_Ehdr*
+elf32_newehdr(Elf *elf) {
+ return (Elf32_Ehdr*)_elf_newehdr(elf, ELFCLASS32);
+}
+
+#if __LIBELF64
+
+Elf64_Ehdr*
+elf64_newehdr(Elf *elf) {
+ return (Elf64_Ehdr*)_elf_newehdr(elf, ELFCLASS64);
+}
+
+unsigned long
+gelf_newehdr(Elf *elf, int cls) {
+ if (!valid_class(cls) || !_msize(cls, _elf_version, ELF_T_EHDR)) {
+ seterr(ERROR_UNKNOWN_CLASS);
+ return 0;
+ }
+ return (unsigned long)_elf_newehdr(elf, cls);
+}
+
+#endif /* __LIBELF64 */
diff --git a/lib/32.newphdr.c b/lib/32.newphdr.c
new file mode 100644
index 0000000..91c63df
--- /dev/null
+++ b/lib/32.newphdr.c
@@ -0,0 +1,118 @@
+/*
+ * 32.newphdr.c - implementation of the elf{32,64}_newphdr(3) functions.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 32.newphdr.c,v 1.16 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+static char*
+_elf_newphdr(Elf *elf, size_t count, unsigned cls) {
+ size_t extcount = 0;
+ Elf_Scn *scn = NULL;
+ char *phdr = NULL;
+ size_t size;
+
+ if (!elf) {
+ return NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (!elf->e_ehdr && !elf->e_readable) {
+ seterr(ERROR_NOEHDR);
+ }
+ else if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ }
+ else if (elf->e_class != cls) {
+ seterr(ERROR_CLASSMISMATCH);
+ }
+ else if (elf->e_ehdr || _elf_cook(elf)) {
+ size = _msize(cls, _elf_version, ELF_T_PHDR);
+ elf_assert(size);
+ if (!(scn = _elf_first_scn(elf))) {
+ return NULL;
+ }
+ if (count) {
+ if (!(phdr = (char*)malloc(count * size))) {
+ seterr(ERROR_MEM_PHDR);
+ return NULL;
+ }
+ memset(phdr, 0, count * size);
+ }
+ elf_assert(elf->e_ehdr);
+ elf->e_phnum = count;
+ if (count >= PN_XNUM) {
+ /*
+ * get NULL section (create it if necessary)
+ */
+ extcount = count;
+ count = PN_XNUM;
+ }
+ if (cls == ELFCLASS32) {
+ ((Elf32_Ehdr*)elf->e_ehdr)->e_phnum = count;
+ scn->s_shdr32.sh_info = extcount;
+ }
+#if __LIBELF64
+ else if (cls == ELFCLASS64) {
+ ((Elf64_Ehdr*)elf->e_ehdr)->e_phnum = count;
+ scn->s_shdr64.sh_info = extcount;
+ }
+#endif /* __LIBELF64 */
+ else {
+ seterr(ERROR_UNIMPLEMENTED);
+ if (phdr) {
+ free(phdr);
+ }
+ return NULL;
+ }
+ if (elf->e_phdr) {
+ free(elf->e_phdr);
+ }
+ elf->e_phdr = phdr;
+ elf->e_phdr_flags |= ELF_F_DIRTY;
+ elf->e_ehdr_flags |= ELF_F_DIRTY;
+ scn->s_scn_flags |= ELF_F_DIRTY;
+ return phdr;
+ }
+ return NULL;
+}
+
+Elf32_Phdr*
+elf32_newphdr(Elf *elf, size_t count) {
+ return (Elf32_Phdr*)_elf_newphdr(elf, count, ELFCLASS32);
+}
+
+#if __LIBELF64
+
+Elf64_Phdr*
+elf64_newphdr(Elf *elf, size_t count) {
+ return (Elf64_Phdr*)_elf_newphdr(elf, count, ELFCLASS64);
+}
+
+unsigned long
+gelf_newphdr(Elf *elf, size_t phnum) {
+ if (!valid_class(elf->e_class)) {
+ seterr(ERROR_UNKNOWN_CLASS);
+ return 0;
+ }
+ return (unsigned long)_elf_newphdr(elf, phnum, elf->e_class);
+}
+
+#endif /* __LIBELF64 */
diff --git a/lib/32.xlatetof.c b/lib/32.xlatetof.c
new file mode 100644
index 0000000..068bac5
--- /dev/null
+++ b/lib/32.xlatetof.c
@@ -0,0 +1,438 @@
+/*
+ * 32.xlatetof.c - implementation of the elf32_xlateto[fm](3) functions.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+#include <ext_types.h>
+#include <byteswap.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 32.xlatetof.c,v 1.27 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+/*
+ * Ugly, ugly
+ */
+#ifdef _WIN32
+# define Cat2(a,b)a##b
+# define Cat3(a,b,c)a##b##c
+# define Ex1(m1,m2,a,b)m1##m2(a##b)
+# define Ex2(m1,m2,a,b,c)m1##m2(a,b##c)
+#else /* _WIN32 */
+# define x
+# if defined/**/x
+# define Cat2(a,b)a##b
+# define Cat3(a,b,c)a##b##c
+# define Ex1(m1,m2,a,b)m1##m2(a##b)
+# define Ex2(m1,m2,a,b,c)m1##m2(a,b##c)
+# else
+# define Cat2(a,b)a/**/b
+# define Cat3(a,b,c)a/**/b/**/c
+# define Ex1(m1,m2,a,b)m1/**/m2(a/**/b)
+# define Ex2(m1,m2,a,b,c)m1/**/m2(a,b/**/c)
+# endif
+# undef x
+#endif /* _WIN32 */
+
+/*
+ * auxiliary macros for execution order reversal
+ */
+#define seq_forw(a,b) a b
+#define seq_back(a,b) b a
+
+/*
+ * function instantiator
+ */
+#define copy_type_e_io(name,e,io,tfrom,tto,copy) \
+ static size_t \
+ Cat3(name,_,io)(unsigned char *dst, const unsigned char *src, size_t n) { \
+ n /= sizeof(tfrom); \
+ if (n && dst) { \
+ const tfrom *from = (const tfrom*)src; \
+ tto *to = (tto*)dst; \
+ size_t i; \
+ \
+ if (sizeof(tfrom) < sizeof(tto)) { \
+ from += n; \
+ to += n; \
+ for (i = 0; i < n; i++) { \
+ --from; \
+ --to; \
+ copy(e,io,seq_back) \
+ } \
+ } \
+ else { \
+ for (i = 0; i < n; i++) { \
+ copy(e,io,seq_forw) \
+ from++; \
+ to++; \
+ } \
+ } \
+ } \
+ return n * sizeof(tto); \
+ }
+
+#define copy_type_e(name,e,type,copy) \
+ copy_type_e_io(name,e,tom,Cat2(__ext_,type),type,copy) \
+ copy_type_e_io(name,e,tof,type,Cat2(__ext_,type),copy)
+
+/*
+ * master function instantiator
+ */
+#define copy_type(name,version,type,copy) \
+ copy_type_e(Cat3(name,L,version),L,type,copy) \
+ copy_type_e(Cat3(name,M,version),M,type,copy)
+
+/*
+ * scalar copying
+ */
+#define copy_scalar_tom(type) *to = Cat2(__load_,type)(*from);
+#define copy_scalar_tof(type) Cat2(__store_,type)(*to, *from);
+
+/*
+ * structure member copying
+ */
+#define copy_tom(mb,type) to->mb = Cat2(__load_,type)(from->mb);
+#define copy_tof(mb,type) Cat2(__store_,type)(to->mb, from->mb);
+
+/*
+ * structure member copying (direction independent)
+ */
+#define copy_byte(e,io,mb) to->mb = from->mb;
+#define copy_addr(e,io,mb) Ex2(copy_,io,mb,u32,e)
+#define copy_half(e,io,mb) Ex2(copy_,io,mb,u16,e)
+#define copy_off(e,io,mb) Ex2(copy_,io,mb,u32,e)
+#define copy_sword(e,io,mb) Ex2(copy_,io,mb,i32,e)
+#define copy_word(e,io,mb) Ex2(copy_,io,mb,u32,e)
+#define copy_arr(e,io,mb) \
+ array_copy(to->mb, sizeof(to->mb), from->mb, sizeof(from->mb));
+
+/*
+ * scalar copying (direction independent)
+ * these macros are used as `copy' arguments to copy_type()
+ */
+#define copy_addr_11(e,io,seq) Ex1(copy_scalar_,io,u32,e)
+#define copy_half_11(e,io,seq) Ex1(copy_scalar_,io,u16,e)
+#define copy_off_11(e,io,seq) Ex1(copy_scalar_,io,u32,e)
+#define copy_sword_11(e,io,seq) Ex1(copy_scalar_,io,i32,e)
+#define copy_word_11(e,io,seq) Ex1(copy_scalar_,io,u32,e)
+
+/*
+ * structure copying (direction independent)
+ * these macros are used as `copy' arguments to copy_type()
+ */
+#define copy_dyn_11(e,io,seq) \
+ seq(copy_sword(e,io,d_tag), \
+ seq(copy_addr(e,io,d_un.d_ptr), \
+ nullcopy))
+#define copy_ehdr_11(e,io,seq) \
+ seq(copy_arr(e,io,e_ident), \
+ seq(copy_half(e,io,e_type), \
+ seq(copy_half(e,io,e_machine), \
+ seq(copy_word(e,io,e_version), \
+ seq(copy_addr(e,io,e_entry), \
+ seq(copy_off(e,io,e_phoff), \
+ seq(copy_off(e,io,e_shoff), \
+ seq(copy_word(e,io,e_flags), \
+ seq(copy_half(e,io,e_ehsize), \
+ seq(copy_half(e,io,e_phentsize), \
+ seq(copy_half(e,io,e_phnum), \
+ seq(copy_half(e,io,e_shentsize), \
+ seq(copy_half(e,io,e_shnum), \
+ seq(copy_half(e,io,e_shstrndx), \
+ nullcopy))))))))))))))
+#define copy_phdr_11(e,io,seq) \
+ seq(copy_word(e,io,p_type), \
+ seq(copy_off(e,io,p_offset), \
+ seq(copy_addr(e,io,p_vaddr), \
+ seq(copy_addr(e,io,p_paddr), \
+ seq(copy_word(e,io,p_filesz), \
+ seq(copy_word(e,io,p_memsz), \
+ seq(copy_word(e,io,p_flags), \
+ seq(copy_word(e,io,p_align), \
+ nullcopy))))))))
+#define copy_rela_11(e,io,seq) \
+ seq(copy_addr(e,io,r_offset), \
+ seq(copy_word(e,io,r_info), \
+ seq(copy_sword(e,io,r_addend), \
+ nullcopy)))
+#define copy_rel_11(e,io,seq) \
+ seq(copy_addr(e,io,r_offset), \
+ seq(copy_word(e,io,r_info), \
+ nullcopy))
+#define copy_shdr_11(e,io,seq) \
+ seq(copy_word(e,io,sh_name), \
+ seq(copy_word(e,io,sh_type), \
+ seq(copy_word(e,io,sh_flags), \
+ seq(copy_addr(e,io,sh_addr), \
+ seq(copy_off(e,io,sh_offset), \
+ seq(copy_word(e,io,sh_size), \
+ seq(copy_word(e,io,sh_link), \
+ seq(copy_word(e,io,sh_info), \
+ seq(copy_word(e,io,sh_addralign), \
+ seq(copy_word(e,io,sh_entsize), \
+ nullcopy))))))))))
+#define copy_sym_11(e,io,seq) \
+ seq(copy_word(e,io,st_name), \
+ seq(copy_addr(e,io,st_value), \
+ seq(copy_word(e,io,st_size), \
+ seq(copy_byte(e,io,st_info), \
+ seq(copy_byte(e,io,st_other), \
+ seq(copy_half(e,io,st_shndx), \
+ nullcopy))))))
+
+#define nullcopy /**/
+
+static size_t
+byte_copy(unsigned char *dst, const unsigned char *src, size_t n) {
+ if (n && dst && dst != src) {
+#if HAVE_BROKEN_MEMMOVE
+ size_t i;
+
+ if (dst >= src + n || dst + n <= src) {
+ memcpy(dst, src, n);
+ }
+ else if (dst < src) {
+ for (i = 0; i < n; i++) {
+ dst[i] = src[i];
+ }
+ }
+ else {
+ for (i = n; --i; ) {
+ dst[i] = src[i];
+ }
+ }
+#else /* HAVE_BROKEN_MEMMOVE */
+ memmove(dst, src, n);
+#endif /* HAVE_BROKEN_MEMMOVE */
+ }
+ return n;
+}
+
+static void
+array_copy(unsigned char *dst, size_t dlen, const unsigned char *src, size_t slen) {
+ byte_copy(dst, src, dlen < slen ? dlen : slen);
+ if (dlen > slen) {
+ memset(dst + slen, 0, dlen - slen);
+ }
+}
+
+/*
+ * instantiate copy functions
+ */
+copy_type(addr_32,_,Elf32_Addr,copy_addr_11)
+copy_type(half_32,_,Elf32_Half,copy_half_11)
+copy_type(off_32,_,Elf32_Off,copy_off_11)
+copy_type(sword_32,_,Elf32_Sword,copy_sword_11)
+copy_type(word_32,_,Elf32_Word,copy_word_11)
+copy_type(dyn_32,11,Elf32_Dyn,copy_dyn_11)
+copy_type(ehdr_32,11,Elf32_Ehdr,copy_ehdr_11)
+copy_type(phdr_32,11,Elf32_Phdr,copy_phdr_11)
+copy_type(rela_32,11,Elf32_Rela,copy_rela_11)
+copy_type(rel_32,11,Elf32_Rel,copy_rel_11)
+copy_type(shdr_32,11,Elf32_Shdr,copy_shdr_11)
+copy_type(sym_32,11,Elf32_Sym,copy_sym_11)
+
+typedef size_t (*xlator)(unsigned char*, const unsigned char*, size_t);
+typedef xlator xltab[ELF_T_NUM][2];
+
+/*
+ * translation table (32-bit, version 1 -> version 1)
+ */
+#if PIC
+static xltab
+#else /* PIC */
+static const xltab
+#endif /* PIC */
+xlate32_11[/*encoding*/] = {
+ {
+ { byte_copy, byte_copy },
+ { addr_32L__tom, addr_32L__tof },
+ { dyn_32L11_tom, dyn_32L11_tof },
+ { ehdr_32L11_tom, ehdr_32L11_tof },
+ { half_32L__tom, half_32L__tof },
+ { off_32L__tom, off_32L__tof },
+ { phdr_32L11_tom, phdr_32L11_tof },
+ { rela_32L11_tom, rela_32L11_tof },
+ { rel_32L11_tom, rel_32L11_tof },
+ { shdr_32L11_tom, shdr_32L11_tof },
+ { sword_32L__tom, sword_32L__tof },
+ { sym_32L11_tom, sym_32L11_tof },
+ { word_32L__tom, word_32L__tof },
+ { 0, 0 }, /* there is no Sxword */
+ { 0, 0 }, /* there is no Xword */
+#if __LIBELF_SYMBOL_VERSIONS
+ { _elf_verdef_32L11_tom, _elf_verdef_32L11_tof },
+ { _elf_verneed_32L11_tom, _elf_verneed_32L11_tof },
+#else /* __LIBELF_SYMBOL_VERSIONS */
+ { 0, 0 },
+ { 0, 0 },
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+ },
+ {
+ { byte_copy, byte_copy },
+ { addr_32M__tom, addr_32M__tof },
+ { dyn_32M11_tom, dyn_32M11_tof },
+ { ehdr_32M11_tom, ehdr_32M11_tof },
+ { half_32M__tom, half_32M__tof },
+ { off_32M__tom, off_32M__tof },
+ { phdr_32M11_tom, phdr_32M11_tof },
+ { rela_32M11_tom, rela_32M11_tof },
+ { rel_32M11_tom, rel_32M11_tof },
+ { shdr_32M11_tom, shdr_32M11_tof },
+ { sword_32M__tom, sword_32M__tof },
+ { sym_32M11_tom, sym_32M11_tof },
+ { word_32M__tom, word_32M__tof },
+ { 0, 0 }, /* there is no Sxword */
+ { 0, 0 }, /* there is no Xword */
+#if __LIBELF_SYMBOL_VERSIONS
+ { _elf_verdef_32M11_tom, _elf_verdef_32M11_tof },
+ { _elf_verneed_32M11_tom, _elf_verneed_32M11_tof },
+#else /* __LIBELF_SYMBOL_VERSIONS */
+ { 0, 0 },
+ { 0, 0 },
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+ },
+};
+
+/*
+ * main translation table (32-bit)
+ */
+#if PIC
+static xltab*
+#else /* PIC */
+static const xltab *const
+#endif /* PIC */
+xlate32[EV_CURRENT - EV_NONE][EV_CURRENT - EV_NONE] = {
+ { xlate32_11, },
+};
+
+#define translator(sv,dv,enc,type,d) \
+ (xlate32[(sv) - EV_NONE - 1] \
+ [(dv) - EV_NONE - 1] \
+ [(enc) - ELFDATA2LSB] \
+ [(type) - ELF_T_BYTE] \
+ [d])
+
+/*
+ * destination buffer size
+ */
+size_t
+_elf32_xltsize(const Elf_Data *src, unsigned dv, unsigned encode, int tof) {
+ Elf_Type type = src->d_type;
+ unsigned sv = src->d_version;
+ xlator op;
+
+ if (!valid_version(sv) || !valid_version(dv)) {
+ seterr(ERROR_UNKNOWN_VERSION);
+ return (size_t)-1;
+ }
+ if (tof) {
+ /*
+ * Encoding doesn't really matter (the translator only looks at
+ * the source, which resides in memory), but we need a proper
+ * encoding to select a translator...
+ */
+ encode = ELFDATA2LSB;
+ }
+ else if (!valid_encoding(encode)) {
+ seterr(ERROR_UNKNOWN_ENCODING);
+ return (size_t)-1;
+ }
+ if (!valid_type(type)) {
+ seterr(ERROR_UNKNOWN_TYPE);
+ return (size_t)-1;
+ }
+ if (!(op = translator(sv, dv, encode, type, tof))) {
+ seterr(ERROR_UNKNOWN_TYPE);
+ return (size_t)-1;
+ }
+ return (*op)(NULL, src->d_buf, src->d_size);
+}
+
+/*
+ * direction-independent translation
+ */
+static Elf_Data*
+elf32_xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof) {
+ Elf_Type type;
+ int dv;
+ int sv;
+ size_t dsize;
+ size_t tmp;
+ xlator op;
+
+ if (!src || !dst) {
+ return NULL;
+ }
+ if (!src->d_buf || !dst->d_buf) {
+ seterr(ERROR_NULLBUF);
+ return NULL;
+ }
+ if (!valid_encoding(encode)) {
+ seterr(ERROR_UNKNOWN_ENCODING);
+ return NULL;
+ }
+ sv = src->d_version;
+ dv = dst->d_version;
+ if (!valid_version(sv) || !valid_version(dv)) {
+ seterr(ERROR_UNKNOWN_VERSION);
+ return NULL;
+ }
+ type = src->d_type;
+ if (!valid_type(type)) {
+ seterr(ERROR_UNKNOWN_TYPE);
+ return NULL;
+ }
+ op = translator(sv, dv, encode, type, tof);
+ if (!op) {
+ seterr(ERROR_UNKNOWN_TYPE);
+ return NULL;
+ }
+ dsize = (*op)(NULL, src->d_buf, src->d_size);
+ if (dsize == (size_t)-1) {
+ return NULL;
+ }
+ if (dst->d_size < dsize) {
+ seterr(ERROR_DST2SMALL);
+ return NULL;
+ }
+ if (dsize) {
+ tmp = (*op)(dst->d_buf, src->d_buf, src->d_size);
+ if (tmp == (size_t)-1) {
+ return NULL;
+ }
+ elf_assert(tmp == dsize);
+ }
+ dst->d_size = dsize;
+ dst->d_type = type;
+ return dst;
+}
+
+/*
+ * finally, the "official" translation functions
+ */
+Elf_Data*
+elf32_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned encode) {
+ return elf32_xlate(dst, src, encode, 0);
+}
+
+Elf_Data*
+elf32_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned encode) {
+ return elf32_xlate(dst, src, encode, 1);
+}
diff --git a/lib/64.xlatetof.c b/lib/64.xlatetof.c
new file mode 100644
index 0000000..c66f000
--- /dev/null
+++ b/lib/64.xlatetof.c
@@ -0,0 +1,512 @@
+/*
+ * 64.xlatetof.c - implementation of the elf64_xlateto[fm](3) functions.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+#include <ext_types.h>
+#include <byteswap.h>
+
+#if __LIBELF64
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 64.xlatetof.c,v 1.27 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+/*
+ * Ugly, ugly
+ */
+#ifdef _WIN32
+# define Cat2(a,b)a##b
+# define Cat3(a,b,c)a##b##c
+# define Ex1(m1,m2,a,b)m1##m2(a##b)
+# define Ex2(m1,m2,a,b,c)m1##m2(a,b##c)
+#else /* _WIN32 */
+# define x
+# if defined/**/x
+# define Cat2(a,b)a##b
+# define Cat3(a,b,c)a##b##c
+# define Ex1(m1,m2,a,b)m1##m2(a##b)
+# define Ex2(m1,m2,a,b,c)m1##m2(a,b##c)
+# else
+# define Cat2(a,b)a/**/b
+# define Cat3(a,b,c)a/**/b/**/c
+# define Ex1(m1,m2,a,b)m1/**/m2(a/**/b)
+# define Ex2(m1,m2,a,b,c)m1/**/m2(a,b/**/c)
+# endif
+# undef x
+#endif /* _WIN32 */
+
+/*
+ * auxiliary macros for execution order reversal
+ */
+#define seq_forw(a,b) a b
+#define seq_back(a,b) b a
+
+/*
+ * function instantiator
+ */
+#define copy_type_e_io(name,e,io,tfrom,tto,copy) \
+ static size_t \
+ Cat3(name,_,io)(unsigned char *dst, const unsigned char *src, size_t n) { \
+ n /= sizeof(tfrom); \
+ if (n && dst) { \
+ const tfrom *from = (const tfrom*)src; \
+ tto *to = (tto*)dst; \
+ size_t i; \
+ \
+ if (sizeof(tfrom) < sizeof(tto)) { \
+ from += n; \
+ to += n; \
+ for (i = 0; i < n; i++) { \
+ --from; \
+ --to; \
+ copy(e,io,seq_back) \
+ } \
+ } \
+ else { \
+ for (i = 0; i < n; i++) { \
+ copy(e,io,seq_forw) \
+ from++; \
+ to++; \
+ } \
+ } \
+ } \
+ return n * sizeof(tto); \
+ }
+
+#define copy_type_e(name,e,type,copy) \
+ copy_type_e_io(name,e,tom,Cat2(__ext_,type),type,copy) \
+ copy_type_e_io(name,e,tof,type,Cat2(__ext_,type),copy)
+
+/*
+ * master function instantiator
+ */
+#define copy_type(name,version,type,copy) \
+ copy_type_e(Cat3(name,L,version),L,type,copy) \
+ copy_type_e(Cat3(name,M,version),M,type,copy)
+
+/*
+ * scalar copying
+ */
+#define copy_scalar_tom(type) *to = Cat2(__load_,type)(*from);
+#define copy_scalar_tof(type) Cat2(__store_,type)(*to, *from);
+
+/*
+ * structure member copying
+ */
+#define copy_tom(mb,type) to->mb = Cat2(__load_,type)(from->mb);
+#define copy_tof(mb,type) Cat2(__store_,type)(to->mb, from->mb);
+
+/*
+ * structure member copying (direction independent)
+ */
+#define copy_byte(e,io,mb) to->mb = from->mb;
+#define copy_addr(e,io,mb) Ex2(copy_,io,mb,u64,e)
+#define copy_half(e,io,mb) Ex2(copy_,io,mb,u16,e)
+#define copy_off(e,io,mb) Ex2(copy_,io,mb,u64,e)
+#define copy_sword(e,io,mb) Ex2(copy_,io,mb,i32,e)
+#define copy_word(e,io,mb) Ex2(copy_,io,mb,u32,e)
+#define copy_sxword(e,io,mb) Ex2(copy_,io,mb,i64,e)
+#define copy_xword(e,io,mb) Ex2(copy_,io,mb,u64,e)
+#define copy_arr(e,io,mb) \
+ array_copy(to->mb, sizeof(to->mb), from->mb, sizeof(from->mb));
+
+/*
+ * scalar copying (direction independent)
+ * these macros are used as `copy' arguments to copy_type()
+ */
+#define copy_addr_11(e,io,seq) Ex1(copy_scalar_,io,u64,e)
+#define copy_half_11(e,io,seq) Ex1(copy_scalar_,io,u16,e)
+#define copy_off_11(e,io,seq) Ex1(copy_scalar_,io,u64,e)
+#define copy_sword_11(e,io,seq) Ex1(copy_scalar_,io,i32,e)
+#define copy_word_11(e,io,seq) Ex1(copy_scalar_,io,u32,e)
+#define copy_sxword_11(e,io,seq)Ex1(copy_scalar_,io,i64,e)
+#define copy_xword_11(e,io,seq) Ex1(copy_scalar_,io,u64,e)
+
+/*
+ * structure copying (direction independent)
+ * these macros are used as `copy' arguments to copy_type()
+ */
+#define copy_dyn_11(e,io,seq) \
+ seq(copy_xword(e,io,d_tag), \
+ seq(copy_addr(e,io,d_un.d_ptr), \
+ nullcopy))
+#define copy_ehdr_11(e,io,seq) \
+ seq(copy_arr(e,io,e_ident), \
+ seq(copy_half(e,io,e_type), \
+ seq(copy_half(e,io,e_machine), \
+ seq(copy_word(e,io,e_version), \
+ seq(copy_addr(e,io,e_entry), \
+ seq(copy_off(e,io,e_phoff), \
+ seq(copy_off(e,io,e_shoff), \
+ seq(copy_word(e,io,e_flags), \
+ seq(copy_half(e,io,e_ehsize), \
+ seq(copy_half(e,io,e_phentsize), \
+ seq(copy_half(e,io,e_phnum), \
+ seq(copy_half(e,io,e_shentsize), \
+ seq(copy_half(e,io,e_shnum), \
+ seq(copy_half(e,io,e_shstrndx), \
+ nullcopy))))))))))))))
+#define copy_phdr_11(e,io,seq) \
+ seq(copy_word(e,io,p_type), \
+ seq(copy_word(e,io,p_flags), \
+ seq(copy_off(e,io,p_offset), \
+ seq(copy_addr(e,io,p_vaddr), \
+ seq(copy_addr(e,io,p_paddr), \
+ seq(copy_xword(e,io,p_filesz), \
+ seq(copy_xword(e,io,p_memsz), \
+ seq(copy_xword(e,io,p_align), \
+ nullcopy))))))))
+#if __LIBELF64_IRIX
+#define copy_rela_11(e,io,seq) \
+ seq(copy_addr(e,io,r_offset), \
+ seq(copy_word(e,io,r_sym), \
+ seq(copy_byte(e,io,r_ssym), \
+ seq(copy_byte(e,io,r_type3), \
+ seq(copy_byte(e,io,r_type2), \
+ seq(copy_byte(e,io,r_type), \
+ seq(copy_sxword(e,io,r_addend), \
+ nullcopy)))))))
+#define copy_rel_11(e,io,seq) \
+ seq(copy_addr(e,io,r_offset), \
+ seq(copy_word(e,io,r_sym), \
+ seq(copy_byte(e,io,r_ssym), \
+ seq(copy_byte(e,io,r_type3), \
+ seq(copy_byte(e,io,r_type2), \
+ seq(copy_byte(e,io,r_type), \
+ nullcopy))))))
+#else /* __LIBELF64_IRIX */
+#define copy_rela_11(e,io,seq) \
+ seq(copy_addr(e,io,r_offset), \
+ seq(copy_xword(e,io,r_info), \
+ seq(copy_sxword(e,io,r_addend), \
+ nullcopy)))
+#define copy_rel_11(e,io,seq) \
+ seq(copy_addr(e,io,r_offset), \
+ seq(copy_xword(e,io,r_info), \
+ nullcopy))
+#endif /* __LIBELF64_IRIX */
+#define copy_shdr_11(e,io,seq) \
+ seq(copy_word(e,io,sh_name), \
+ seq(copy_word(e,io,sh_type), \
+ seq(copy_xword(e,io,sh_flags), \
+ seq(copy_addr(e,io,sh_addr), \
+ seq(copy_off(e,io,sh_offset), \
+ seq(copy_xword(e,io,sh_size), \
+ seq(copy_word(e,io,sh_link), \
+ seq(copy_word(e,io,sh_info), \
+ seq(copy_xword(e,io,sh_addralign), \
+ seq(copy_xword(e,io,sh_entsize), \
+ nullcopy))))))))))
+#define copy_sym_11(e,io,seq) \
+ seq(copy_word(e,io,st_name), \
+ seq(copy_byte(e,io,st_info), \
+ seq(copy_byte(e,io,st_other), \
+ seq(copy_half(e,io,st_shndx), \
+ seq(copy_addr(e,io,st_value), \
+ seq(copy_xword(e,io,st_size), \
+ nullcopy))))))
+
+#define nullcopy /**/
+
+static size_t
+byte_copy(unsigned char *dst, const unsigned char *src, size_t n) {
+ if (n && dst && dst != src) {
+#if HAVE_BROKEN_MEMMOVE
+ size_t i;
+
+ if (dst >= src + n || dst + n <= src) {
+ memcpy(dst, src, n);
+ }
+ else if (dst < src) {
+ for (i = 0; i < n; i++) {
+ dst[i] = src[i];
+ }
+ }
+ else {
+ for (i = n; --i; ) {
+ dst[i] = src[i];
+ }
+ }
+#else /* HAVE_BROKEN_MEMMOVE */
+ memmove(dst, src, n);
+#endif /* HAVE_BROKEN_MEMMOVE */
+ }
+ return n;
+}
+
+static void
+array_copy(unsigned char *dst, size_t dlen, const unsigned char *src, size_t slen) {
+ byte_copy(dst, src, dlen < slen ? dlen : slen);
+ if (dlen > slen) {
+ memset(dst + slen, 0, dlen - slen);
+ }
+}
+
+/*
+ * instantiate copy functions
+ */
+copy_type(addr_64,_,Elf64_Addr,copy_addr_11)
+copy_type(half_64,_,Elf64_Half,copy_half_11)
+copy_type(off_64,_,Elf64_Off,copy_off_11)
+copy_type(sword_64,_,Elf64_Sword,copy_sword_11)
+copy_type(word_64,_,Elf64_Word,copy_word_11)
+copy_type(sxword_64,_,Elf64_Sxword,copy_sxword_11)
+copy_type(xword_64,_,Elf64_Xword,copy_xword_11)
+copy_type(dyn_64,11,Elf64_Dyn,copy_dyn_11)
+copy_type(ehdr_64,11,Elf64_Ehdr,copy_ehdr_11)
+copy_type(phdr_64,11,Elf64_Phdr,copy_phdr_11)
+copy_type(rela_64,11,Elf64_Rela,copy_rela_11)
+copy_type(rel_64,11,Elf64_Rel,copy_rel_11)
+copy_type(shdr_64,11,Elf64_Shdr,copy_shdr_11)
+copy_type(sym_64,11,Elf64_Sym,copy_sym_11)
+
+typedef size_t (*xlator)(unsigned char*, const unsigned char*, size_t);
+typedef xlator xltab[ELF_T_NUM][2];
+
+/*
+ * translation table (64-bit, version 1 -> version 1)
+ */
+#if PIC
+static xltab
+#else /* PIC */
+static const xltab
+#endif /* PIC */
+xlate64_11[/*encoding*/] = {
+ {
+ { byte_copy, byte_copy },
+ { addr_64L__tom, addr_64L__tof },
+ { dyn_64L11_tom, dyn_64L11_tof },
+ { ehdr_64L11_tom, ehdr_64L11_tof },
+ { half_64L__tom, half_64L__tof },
+ { off_64L__tom, off_64L__tof },
+ { phdr_64L11_tom, phdr_64L11_tof },
+ { rela_64L11_tom, rela_64L11_tof },
+ { rel_64L11_tom, rel_64L11_tof },
+ { shdr_64L11_tom, shdr_64L11_tof },
+ { sword_64L__tom, sword_64L__tof },
+ { sym_64L11_tom, sym_64L11_tof },
+ { word_64L__tom, word_64L__tof },
+ { sxword_64L__tom, sxword_64L__tof },
+ { xword_64L__tom, xword_64L__tof },
+#if __LIBELF_SYMBOL_VERSIONS
+ { _elf_verdef_64L11_tom, _elf_verdef_64L11_tof },
+ { _elf_verneed_64L11_tom, _elf_verneed_64L11_tof },
+#else /* __LIBELF_SYMBOL_VERSIONS */
+ { 0, 0 },
+ { 0, 0 },
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+ },
+ {
+ { byte_copy, byte_copy },
+ { addr_64M__tom, addr_64M__tof },
+ { dyn_64M11_tom, dyn_64M11_tof },
+ { ehdr_64M11_tom, ehdr_64M11_tof },
+ { half_64M__tom, half_64M__tof },
+ { off_64M__tom, off_64M__tof },
+ { phdr_64M11_tom, phdr_64M11_tof },
+ { rela_64M11_tom, rela_64M11_tof },
+ { rel_64M11_tom, rel_64M11_tof },
+ { shdr_64M11_tom, shdr_64M11_tof },
+ { sword_64M__tom, sword_64M__tof },
+ { sym_64M11_tom, sym_64M11_tof },
+ { word_64M__tom, word_64M__tof },
+ { sxword_64M__tom, sxword_64M__tof },
+ { xword_64M__tom, xword_64M__tof },
+#if __LIBELF_SYMBOL_VERSIONS
+ { _elf_verdef_64M11_tom, _elf_verdef_64M11_tof },
+ { _elf_verneed_64M11_tom, _elf_verneed_64M11_tof },
+#else /* __LIBELF_SYMBOL_VERSIONS */
+ { 0, 0 },
+ { 0, 0 },
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+ },
+};
+
+/*
+ * main translation table (64-bit)
+ */
+#if PIC
+static xltab*
+#else /* PIC */
+static const xltab *const
+#endif /* PIC */
+xlate64[EV_CURRENT - EV_NONE][EV_CURRENT - EV_NONE] = {
+ { xlate64_11, },
+};
+
+#define translator(sv,dv,enc,type,d) \
+ (xlate64[(sv) - EV_NONE - 1] \
+ [(dv) - EV_NONE - 1] \
+ [(enc) - ELFDATA2LSB] \
+ [(type) - ELF_T_BYTE] \
+ [d])
+
+/*
+ * destination buffer size
+ */
+size_t
+_elf64_xltsize(const Elf_Data *src, unsigned dv, unsigned encode, int tof) {
+ Elf_Type type = src->d_type;
+ unsigned sv = src->d_version;
+ xlator op;
+
+ if (!valid_version(sv) || !valid_version(dv)) {
+ seterr(ERROR_UNKNOWN_VERSION);
+ return (size_t)-1;
+ }
+ if (tof) {
+ /*
+ * Encoding doesn't really matter (the translator only looks at
+ * the source, which resides in memory), but we need a proper
+ * encoding to select a translator...
+ */
+ encode = ELFDATA2LSB;
+ }
+ else if (!valid_encoding(encode)) {
+ seterr(ERROR_UNKNOWN_ENCODING);
+ return (size_t)-1;
+ }
+ if (!valid_type(type)) {
+ seterr(ERROR_UNKNOWN_TYPE);
+ return (size_t)-1;
+ }
+ if (!(op = translator(sv, dv, encode, type, tof))) {
+ seterr(ERROR_UNKNOWN_TYPE);
+ return (size_t)-1;
+ }
+ return (*op)(NULL, src->d_buf, src->d_size);
+}
+
+/*
+ * direction-independent translation
+ */
+static Elf_Data*
+elf64_xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof) {
+ Elf_Type type;
+ int dv;
+ int sv;
+ size_t dsize;
+ size_t tmp;
+ xlator op;
+
+ if (!src || !dst) {
+ return NULL;
+ }
+ if (!src->d_buf || !dst->d_buf) {
+ seterr(ERROR_NULLBUF);
+ return NULL;
+ }
+ if (!valid_encoding(encode)) {
+ seterr(ERROR_UNKNOWN_ENCODING);
+ return NULL;
+ }
+ sv = src->d_version;
+ dv = dst->d_version;
+ if (!valid_version(sv) || !valid_version(dv)) {
+ seterr(ERROR_UNKNOWN_VERSION);
+ return NULL;
+ }
+ type = src->d_type;
+ if (!valid_type(type)) {
+ seterr(ERROR_UNKNOWN_TYPE);
+ return NULL;
+ }
+ op = translator(sv, dv, encode, type, tof);
+ if (!op) {
+ seterr(ERROR_UNKNOWN_TYPE);
+ return NULL;
+ }
+ dsize = (*op)(NULL, src->d_buf, src->d_size);
+ if (dsize == (size_t)-1) {
+ return NULL;
+ }
+ if (dst->d_size < dsize) {
+ seterr(ERROR_DST2SMALL);
+ return NULL;
+ }
+ if (dsize) {
+ tmp = (*op)(dst->d_buf, src->d_buf, src->d_size);
+ if (tmp == (size_t)-1) {
+ return NULL;
+ }
+ elf_assert(tmp == dsize);
+ }
+ dst->d_size = dsize;
+ dst->d_type = type;
+ return dst;
+}
+
+/*
+ * finally, the "official" translation functions
+ */
+Elf_Data*
+elf64_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned encode) {
+ return elf64_xlate(dst, src, encode, 0);
+}
+
+Elf_Data*
+elf64_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned encode) {
+ return elf64_xlate(dst, src, encode, 1);
+}
+
+Elf_Data*
+gelf_xlatetom(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) {
+ if (elf) {
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ }
+ else if (elf->e_class == ELFCLASS32) {
+ return elf32_xlatetom(dst, src, encode);
+ }
+ else if (elf->e_class == ELFCLASS64) {
+ return elf64_xlatetom(dst, src, encode);
+ }
+ else if (valid_class(elf->e_class)) {
+ seterr(ERROR_UNIMPLEMENTED);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ }
+ return NULL;
+}
+
+Elf_Data*
+gelf_xlatetof(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) {
+ if (elf) {
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ }
+ else if (elf->e_class == ELFCLASS32) {
+ return elf32_xlatetof(dst, src, encode);
+ }
+ else if (elf->e_class == ELFCLASS64) {
+ return elf64_xlatetof(dst, src, encode);
+ }
+ else if (valid_class(elf->e_class)) {
+ seterr(ERROR_UNIMPLEMENTED);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ }
+ return NULL;
+}
+
+#endif /* __LIBELF64__ */
diff --git a/lib/Makefile.in b/lib/Makefile.in
new file mode 100644
index 0000000..92a129f
--- /dev/null
+++ b/lib/Makefile.in
@@ -0,0 +1,278 @@
+# lib/Makefile for libelf.
+# Copyright (C) 1995 - 2009 Michael Riepe
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+# @(#) $Id: Makefile.in,v 1.40 2009/11/01 13:04:19 michael Exp $
+
+instroot =
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+installdirs = $(libdir) $(includedir) $(includedir)/libelf
+
+CC = @CC@
+LD = @LD@
+AR = ar
+MV = mv -f
+RM = rm -f
+LN_S = @LN_S@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+DEFS = -DHAVE_CONFIG_H
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+DEPSHLIBS = @DEPSHLIBS@
+
+DO_SHLIB = @DO_SHLIB@
+PICFLAGS = @PICFLAGS@
+SHLIB_SFX = @SHLIB_SFX@
+SHLINK_SFX = @SHLINK_SFX@
+SONAME_SFX = @SONAME_SFX@
+LINK_SHLIB = @LINK_SHLIB@
+INSTALL_SHLIB = @INSTALL_SHLIB@
+
+SHLIB = libelf$(SHLIB_SFX)
+SHLINK = libelf$(SHLINK_SFX)
+SONAME = libelf$(SONAME_SFX)
+
+# install includes in includedir?
+DO_COMPAT = @DO_COMPAT@
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+# no user serviceable parts below
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+MAJOR = @MAJOR@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+topdir = ..
+subdir = lib
+
+.SUFFIXES:
+.SUFFIXES: .c .o
+.c.o:
+ @$(RM) $@ $(@:.o=.os)
+ if test -n "$(PICFLAGS)"; then \
+ $(COMPILE) $(PICFLAGS) $< && $(MV) $@ $(@:.o=.os); \
+ else true; fi
+ $(COMPILE) $<
+
+INCLUDES = -I$(topdir) -I. -I$(srcdir)
+
+# generic sources
+SRCS1 = begin.c cntl.c end.c errmsg.c errno.c fill.c flag.c getarhdr.c \
+ getarsym.c getbase.c getdata.c getident.c getscn.c hash.c kind.c \
+ ndxscn.c newdata.c newscn.c next.c nextscn.c rand.c rawdata.c \
+ rawfile.c strptr.c update.c version.c checksum.c getaroff.c
+OBJS1 = begin.o cntl.o end.o errmsg.o errno.o fill.o flag.o getarhdr.o \
+ getarsym.o getbase.o getdata.o getident.o getscn.o hash.o kind.o \
+ ndxscn.o newdata.o newscn.o next.o nextscn.o rand.o rawdata.o \
+ rawfile.o strptr.o update.o version.o checksum.o getaroff.o
+
+# 32-bit sources
+SRCS2 = 32.fsize.c 32.getehdr.c 32.getphdr.c 32.getshdr.c 32.newehdr.c \
+ 32.newphdr.c 32.xlatetof.c
+OBJS2 = 32.fsize.o 32.getehdr.o 32.getphdr.o 32.getshdr.o 32.newehdr.o \
+ 32.newphdr.o 32.xlatetof.o
+
+# support
+SRCS3 = cook.c data.c input.c assert.c
+OBJS3 = cook.o data.o input.o assert.o
+
+# nlist
+SRCS4 = nlist.c
+OBJS4 = nlist.o
+
+# opt
+SRCS5 = opt.delscn.c x.remscn.c x.movscn.c x.elfext.c
+OBJS5 = opt.delscn.o x.remscn.o x.movscn.o x.elfext.o
+
+# 64-bit sources
+SRCS64 = 64.xlatetof.c gelfehdr.c gelfphdr.c gelfshdr.c gelftrans.c swap64.c
+OBJS64 = 64.xlatetof.o gelfehdr.o gelfphdr.o gelfshdr.o gelftrans.o swap64.o
+
+# Versioning sources
+SRCS_V = verdef_32_tof.c verdef_32_tom.c verdef_64_tof.c verdef_64_tom.c
+OBJS_V = verdef_32_tof.o verdef_32_tom.o verdef_64_tof.o verdef_64_tom.o
+HDRS_V = verdef.h verneed.h
+
+SRCS = $(SRCS1) $(SRCS2) $(SRCS3) $(SRCS4) $(SRCS5) $(SRCS64) $(SRCS_V)
+OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS64) $(OBJS_V)
+
+# missing functions
+LIBSRCS = memset.c
+LIBOBJS = @LIBOBJS@
+
+# public header files
+HDRS = libelf.h nlist.h gelf.h
+
+# public header files (created by configure)
+AUXHDRS = sys_elf.h
+
+# private header files
+PRIVHDRS = byteswap.h errors.h ext_types.h private.h elf_repl.h \
+ $(HDRS_V)
+
+DISTFILES = $(SRCS) $(LIBSRCS) $(HDRS) $(PRIVHDRS) Makefile.in sys_elf.h.in \
+ Makefile.w32 build.bat config.h.w32 libelf.def sys_elf.h.w32
+
+all: libelf.a shared-$(DO_SHLIB)
+
+check:
+
+shared-yes: $(SHLIB)
+shared-no:
+
+libelf.a: $(OBJS) $(LIBOBJS)
+ @$(RM) $@
+ $(AR) rcv $@ $(OBJS) $(LIBOBJS)
+ $(RANLIB) $@
+
+$(SHLIB): libelf.a
+ @$(RM) $(SHLIB)
+ $(LINK_SHLIB) -o $(SHLIB) $(OBJS:.o=.os) $(LIBOBJS:.o=.os) $(DEPSHLIBS)
+ if test "$(SONAME)" = "$(SHLIB)"; then true; else \
+ $(RM) $(SONAME) && $(LN_S) $(SHLIB) $(SONAME); \
+ fi
+ if test "$(SHLINK)" = "$(SHLIB)"; then true; else \
+ $(RM) $(SHLINK) && $(LN_S) $(SHLIB) $(SHLINK); \
+ fi
+
+install: install-data \
+ install-shared-$(DO_SHLIB) install-compat-$(DO_COMPAT)
+
+installdirs: $(top_srcdir)/mkinstalldirs
+ dirs="$(installdirs)"; for dir in $$dirs; do \
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(instroot)$$dir; \
+ done
+
+install-data: all installdirs
+ $(INSTALL_DATA) libelf.a $(instroot)$(libdir)
+ -cd $(instroot)$(libdir) && $(RANLIB) libelf.a
+ files="$(HDRS) $(AUXHDRS) elf_repl.h"; for file in $$files; do \
+ if test -r $$file; then \
+ $(INSTALL_DATA) $$file $(instroot)$(includedir)/libelf; \
+ else \
+ $(INSTALL_DATA) $(srcdir)/$$file $(instroot)$(includedir)/libelf; \
+ fi; \
+ done
+
+uninstall: uninstall-data \
+ uninstall-shared-$(DO_SHLIB) uninstall-compat-$(DO_COMPAT)
+
+uninstall-data:
+ $(RM) $(instroot)$(libdir)/libelf.a
+ $(RM) -r $(instroot)$(includedir)/libelf
+
+install-shared-yes: install-shared
+install-shared-no:
+install-shared: installdirs $(SHLIB)
+ $(INSTALL_SHLIB) $(SHLIB) $(instroot)$(libdir)
+ if test "$(SONAME)" = "$(SHLIB)"; then true; else \
+ cd $(instroot)$(libdir) && $(RM) $(SONAME) && $(LN_S) $(SHLIB) $(SONAME); \
+ fi
+ if test "$(SHLINK)" = "$(SHLIB)"; then true; else \
+ cd $(instroot)$(libdir) && $(RM) $(SHLINK) && $(LN_S) $(SHLIB) $(SHLINK); \
+ fi
+
+uninstall-shared-yes: uninstall-shared
+uninstall-shared-no:
+uninstall-shared:
+ cd $(instroot)$(libdir) && $(RM) $(SHLIB) $(SONAME) $(SHLINK)
+
+install-compat-yes: install-compat
+install-compat-no:
+install-compat: installdirs
+ files="$(HDRS)"; for file in $$files; do \
+ if test -f $(instroot)$(includedir)/$$file; then true; else \
+ echo "#include <libelf/$$file>" > $(instroot)$(includedir)/$$file; \
+ fi; \
+ done
+
+uninstall-compat-yes: uninstall-compat
+uninstall-compat-no:
+uninstall-compat:
+ files="$(HDRS)"; for file in $$files; do \
+ if grep "^#include <libelf/$$file>\$$" $(instroot)$(includedir)/$$file >/dev/null 2>&1; then \
+ $(RM) $(instroot)$(includedir)/$$file; \
+ else true; fi; \
+ done
+
+mostlyclean:
+ $(RM) *.o *.a *.os $(SHLIB) $(SONAME) $(SHLINK)
+ $(RM) *~ core a.out errlist
+
+clean: mostlyclean
+
+distclean: clean
+ $(RM) stamp-h $(AUXHDRS)
+ $(RM) Makefile
+
+maintainer-clean: distclean
+
+# maintainer only
+
+MAINT = @MAINT@
+
+distdir = $(PACKAGE)-$(VERSION)
+distsubdir = $(topdir)/$(distdir)/$(subdir)
+$(MAINT)dist: $(DISTFILES)
+ if test -d $(distsubdir); then true; else mkdir $(distsubdir); fi
+ files="$(DISTFILES)"; for file in $$files; do \
+ ln $(srcdir)/$$file $(distsubdir) || \
+ cp -p $(srcdir)/$$file $(distsubdir) || exit 1; \
+ done
+
+# For the justification of the following Makefile rules, see node
+# `Automatic Remaking' in GNU Autoconf documentation.
+
+$(MAINT)Makefile: Makefile.in $(topdir)/config.status
+ cd $(topdir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
+
+$(MAINT)sys_elf.h: stamp-h
+$(MAINT)stamp-h: sys_elf.h.in $(topdir)/config.status
+ cd $(topdir) && CONFIG_FILES= CONFIG_HEADERS=$(subdir)/sys_elf.h ./config.status
+ $(RM) stamp-h && echo timestamp > stamp-h
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+# dependencies
+$(OBJS): private.h $(topdir)/config.h libelf.h gelf.h errors.h $(AUXHDRS)
+32.fsize.o: ext_types.h
+32.xlatetof.o: byteswap.h ext_types.h
+64.xlatetof.o: byteswap.h ext_types.h
+getarsym.o: byteswap.h
+memset.o: $(topdir)/config.h
+nlist.o: nlist.h
+swap64.o: byteswap.h
+$(OBJS_V): byteswap.h ext_types.h $(HDRS_V)
diff --git a/lib/Makefile.w32 b/lib/Makefile.w32
new file mode 100644
index 0000000..7ee810c
--- /dev/null
+++ b/lib/Makefile.w32
@@ -0,0 +1,166 @@
+# lib/Makefile.w32 - Makefile for W32 port.
+# Copyright (C) 1995 - 2009 Michael Riepe
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# @(#) $Id: Makefile.w32,v 1.3 2009/11/01 13:04:19 michael Exp $
+
+instroot =
+
+prefix =
+exec_prefix =
+libdir =
+includedir =
+installdirs = $(libdir) $(includedir) $(includedir)/libelf
+
+CC = cl /nologo
+LD = link /nologo
+AR =
+MV =
+RM = del
+LN_S =
+RANLIB =
+INSTALL =
+INSTALL_DATA =
+INSTALL_PROGRAM =
+
+CFLAGS = /O2 /W2 /TC /MD
+CPPFLAGS =
+DEFS = /DHAVE_CONFIG_H
+LDFLAGS =
+LIBS =
+DEPSHLIBS =
+
+DO_SHLIB =
+PICFLAGS =
+SHLIB_SFX = .dll
+SHLINK_SFX =
+SONAME_SFX =
+LINK_SHLIB = $(LD) /DLL $(LDFLAGS)
+
+SHLIB = libelf$(SHLIB_SFX)
+SHLINK = libelf$(SHLINK_SFX)
+SONAME = libelf$(SONAME_SFX)
+
+# install includes in includedir?
+DO_COMPAT =
+
+INCLUDES = /I.
+
+COMPILE = $(CC) /c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+# no user serviceable parts below
+
+PACKAGE = libelf
+VERSION = 0.8.9
+MAJOR = 0
+
+SHELL = /bin/sh
+
+srcdir = .
+top_srcdir = ..
+
+topdir = ..
+subdir = lib
+
+.SUFFIXES:
+.SUFFIXES: .obj .c
+.c.obj:
+ $(COMPILE) $<
+
+# generic sources
+SRCS1 = begin.c cntl.c end.c errmsg.c errno.c fill.c flag.c getarhdr.c \
+ getarsym.c getbase.c getdata.c getident.c getscn.c hash.c kind.c \
+ ndxscn.c newdata.c newscn.c next.c nextscn.c rand.c rawdata.c \
+ rawfile.c strptr.c update.c version.c checksum.c getaroff.c
+OBJS1 = $(SRCS1:.c=.obj)
+
+# 32-bit sources
+SRCS2 = 32.fsize.c 32.getehdr.c 32.getphdr.c 32.getshdr.c 32.newehdr.c \
+ 32.newphdr.c 32.xlatetof.c
+OBJS2 = $(SRCS2:.c=.obj)
+
+# support
+SRCS3 = cook.c data.c input.c assert.c
+OBJS3 = $(SRCS3:.c=.obj)
+
+# nlist
+SRCS4 = nlist.c
+OBJS4 = $(SRCS4:.c=.obj)
+
+# opt
+SRCS5 = opt.delscn.c x.remscn.c x.movscn.c x.elfext.c
+OBJS5 = $(SRCS5:.c=.obj)
+
+# 64-bit sources
+SRCS64 = 64.xlatetof.c gelfehdr.c gelfphdr.c gelfshdr.c gelftrans.c swap64.c
+OBJS64 = $(SRCS64:.c=.obj)
+
+# Versioning sources
+SRCS_V = verdef_32_tof.c verdef_32_tom.c verdef_64_tof.c verdef_64_tom.c
+OBJS_V = $(SRCS_V:.c=.obj)
+HDRS_V = verdef.h verneed.h
+
+SRCS = $(SRCS1) $(SRCS2) $(SRCS3) $(SRCS4) $(SRCS5) $(SRCS64) $(SRCS_V)
+OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS64) $(OBJS_V)
+
+# missing functions
+LIBSRCS = memset.c
+LIBOBJS =
+
+# public header files
+HDRS = libelf.h nlist.h gelf.h
+
+# public header files (created by configure)
+AUXHDRS = sys_elf.h
+
+# private header files
+PRIVHDRS = byteswap.h errors.h ext_types.h private.h elf_repl.h $(HDRS_V)
+
+DISTFILES = $(SRCS) $(LIBSRCS) $(HDRS) $(PRIVHDRS) Makefile.in sys_elf.h.in
+
+all: $(OBJS) $(SHLIB)
+
+check:
+
+$(SHLIB): libelf.def $(OBJS) $(LIBOBJS)
+ -@$(RM) $(SHLIB)
+ $(LINK_SHLIB) /OUT:"$(SHLIB)" /DEF:"libelf.def" $(OBJS) $(LIBOBJS) kernel32.lib
+
+install:
+
+mostlyclean:
+ -$(RM) *.obj
+ -$(RM) $(SHLIB)
+ -$(RM) libelf.lib
+ -$(RM) libelf.exp
+
+clean: mostlyclean
+
+distclean: clean
+ -$(RM) $(AUXHDRS)
+
+maintainer-clean: distclean
+
+# dependencies
+$(OBJS): private.h config.h libelf.h gelf.h errors.h $(AUXHDRS)
+32.fsize.obj: ext_types.h
+32.xlatetof.obj: byteswap.h ext_types.h
+64.xlatetof.obj: byteswap.h ext_types.h
+getarsym.obj: byteswap.h
+memset.obj: config.h
+nlist.obj: nlist.h
+swap64.obj: byteswap.h
+$(OBJS_V): byteswap.h ext_types.h $(HDRS_V)
diff --git a/lib/assert.c b/lib/assert.c
new file mode 100644
index 0000000..18bd041
--- /dev/null
+++ b/lib/assert.c
@@ -0,0 +1,33 @@
+/*
+assert.c - assert function for libelf.
+Copyright (C) 1999 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: assert.c,v 1.5 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+
+void
+__elf_assert(const char *file, unsigned line, const char *cond) {
+ fprintf(stderr, "%s:%u: libelf assertion failure: %s\n",
+ file, line, cond);
+ abort();
+}
diff --git a/lib/begin.c b/lib/begin.c
new file mode 100644
index 0000000..1a7a229
--- /dev/null
+++ b/lib/begin.c
@@ -0,0 +1,429 @@
+/*
+ * begin.c - implementation of the elf_begin(3) and elf_memory(3) functions.
+ * Copyright (C) 1995 - 2004 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: begin.c,v 1.22 2009/11/01 13:04:19 michael Exp $";
+#endif /* lint */
+
+static const Elf _elf_init = INIT_ELF;
+static const char fmag[] = ARFMAG;
+
+static unsigned long
+getnum(const char *str, size_t len, int base, size_t *err) {
+ unsigned long result = 0;
+
+ while (len && *str == ' ') {
+ str++; len--;
+ }
+ while (len && *str >= '0' && (*str - '0') < base) {
+ result = base * result + *str++ - '0'; len--;
+ }
+ while (len && *str == ' ') {
+ str++; len--;
+ }
+ if (len) {
+ *err = len;
+ }
+ return result;
+}
+
+static void
+_elf_init_ar(Elf *elf) {
+ struct ar_hdr *hdr;
+ size_t offset;
+ size_t size;
+ size_t err = 0;
+
+ elf->e_kind = ELF_K_AR;
+ elf->e_idlen = SARMAG;
+ elf->e_off = SARMAG;
+
+ /* process special members */
+ offset = SARMAG;
+ while (!elf->e_strtab && offset + sizeof(*hdr) <= elf->e_size) {
+ hdr = (struct ar_hdr*)(elf->e_data + offset);
+ if (memcmp(hdr->ar_fmag, fmag, sizeof(fmag) - 1)) {
+ break;
+ }
+ if (hdr->ar_name[0] != '/') {
+ break;
+ }
+ size = getnum(hdr->ar_size, sizeof(hdr->ar_size), 10, &err);
+ if (err || !size) {
+ break;
+ }
+ offset += sizeof(*hdr);
+ if (offset + size > elf->e_size) {
+ break;
+ }
+ if (hdr->ar_name[1] == '/' && hdr->ar_name[2] == ' ') {
+ elf->e_strtab = elf->e_data + offset;
+ elf->e_strlen = size;
+ break;
+ }
+ if (hdr->ar_name[1] != ' ') {
+ break;
+ }
+ /*
+ * Windows (.lib) archives provide two symbol tables
+ * The first one is the one we want.
+ */
+ if (!elf->e_symtab) {
+ elf->e_symtab = elf->e_data + offset;
+ elf->e_symlen = size;
+ }
+ offset += size + (size & 1);
+ }
+}
+
+static Elf_Arhdr*
+_elf_arhdr(Elf *arf) {
+ struct ar_hdr *hdr;
+ Elf_Arhdr *arhdr;
+ size_t namelen;
+ size_t tmp;
+ char *name;
+ size_t err = 0;
+
+ if (arf->e_off == arf->e_size) {
+ /* no error! */
+ return NULL;
+ }
+ if (arf->e_off < 0 || arf->e_off > arf->e_size) {
+ seterr(ERROR_OUTSIDE);
+ return NULL;
+ }
+ if (arf->e_off + sizeof(*hdr) > arf->e_size) {
+ seterr(ERROR_TRUNC_ARHDR);
+ return NULL;
+ }
+ elf_assert(arf->e_data != NULL);
+ hdr = (struct ar_hdr*)(arf->e_data + arf->e_off);
+ if (memcmp(hdr->ar_fmag, fmag, sizeof(fmag) - 1)) {
+ seterr(ERROR_ARFMAG);
+ return NULL;
+ }
+
+ name = hdr->ar_name;
+ for (namelen = sizeof(hdr->ar_name); namelen > 0; namelen--) {
+ if (name[namelen - 1] != ' ') {
+ break;
+ }
+ }
+ if (name[0] == '/') {
+ if (name[1] >= '0' && name[1] <= '9') {
+ if (!arf->e_strtab) {
+ seterr(ERROR_ARSTRTAB);
+ return NULL;
+ }
+ tmp = getnum(&name[1], namelen - 1, 10, &err);
+ if (err) {
+ seterr(ERROR_ARSPECIAL);
+ return NULL;
+ }
+ if (tmp < 0 || tmp >= arf->e_strlen) {
+ seterr(ERROR_ARSTRTAB);
+ return NULL;
+ }
+ for (namelen = tmp; namelen < arf->e_strlen; namelen++) {
+ if (arf->e_strtab[namelen] == '/') {
+ break;
+ }
+ }
+ if (namelen == arf->e_strlen) {
+ seterr(ERROR_ARSTRTAB);
+ return NULL;
+ }
+ name = arf->e_strtab + tmp;
+ namelen -= tmp;
+ }
+ else if (namelen != 1 && !(namelen == 2 && name[1] == '/')) {
+ seterr(ERROR_ARSPECIAL);
+ return NULL;
+ }
+ }
+ else if (namelen > 0 && name[namelen - 1] == '/') {
+ namelen--;
+ }
+ /* XXX some broken software omits the trailing slash
+ else {
+ namelen = 0;
+ }
+ */
+
+ if (!(arhdr = (Elf_Arhdr*)malloc(sizeof(*arhdr) +
+ sizeof(hdr->ar_name) + namelen + 2))) {
+ seterr(ERROR_MEM_ARHDR);
+ return NULL;
+ }
+
+ arhdr->ar_name = NULL;
+ arhdr->ar_rawname = (char*)(arhdr + 1);
+ arhdr->ar_date = getnum(hdr->ar_date, sizeof(hdr->ar_date), 10, &err);
+ arhdr->ar_uid = getnum(hdr->ar_uid, sizeof(hdr->ar_uid), 10, &err);
+ arhdr->ar_gid = getnum(hdr->ar_gid, sizeof(hdr->ar_gid), 10, &err);
+ arhdr->ar_mode = getnum(hdr->ar_mode, sizeof(hdr->ar_mode), 8, &err);
+ arhdr->ar_size = getnum(hdr->ar_size, sizeof(hdr->ar_size), 10, &err);
+ if (err) {
+ free(arhdr);
+ seterr(ERROR_ARHDR);
+ return NULL;
+ }
+ if (arf->e_off + sizeof(struct ar_hdr) + arhdr->ar_size > arf->e_size) {
+ free(arhdr);
+ seterr(ERROR_TRUNC_MEMBER);
+ return NULL;
+ }
+
+ memcpy(arhdr->ar_rawname, hdr->ar_name, sizeof(hdr->ar_name));
+ arhdr->ar_rawname[sizeof(hdr->ar_name)] = '\0';
+
+ if (namelen) {
+ arhdr->ar_name = arhdr->ar_rawname + sizeof(hdr->ar_name) + 1;
+ memcpy(arhdr->ar_name, name, namelen);
+ arhdr->ar_name[namelen] = '\0';
+ }
+
+ return arhdr;
+}
+
+static void
+_elf_check_type(Elf *elf, size_t size) {
+ elf->e_idlen = size;
+ if (size >= EI_NIDENT && !memcmp(elf->e_data, ELFMAG, SELFMAG)) {
+ elf->e_kind = ELF_K_ELF;
+ elf->e_idlen = EI_NIDENT;
+ elf->e_class = elf->e_data[EI_CLASS];
+ elf->e_encoding = elf->e_data[EI_DATA];
+ elf->e_version = elf->e_data[EI_VERSION];
+ }
+ else if (size >= SARMAG && !memcmp(elf->e_data, ARMAG, SARMAG)) {
+ _elf_init_ar(elf);
+ }
+}
+
+Elf*
+elf_begin(int fd, Elf_Cmd cmd, Elf *ref) {
+ Elf_Arhdr *arhdr = NULL;
+ size_t size = 0;
+ off_t off;
+ Elf *elf;
+
+ elf_assert(_elf_init.e_magic == ELF_MAGIC);
+ if (_elf_version == EV_NONE) {
+ seterr(ERROR_VERSION_UNSET);
+ return NULL;
+ }
+ else if (cmd == ELF_C_NULL) {
+ return NULL;
+ }
+ else if (cmd == ELF_C_WRITE) {
+ ref = NULL;
+ }
+ else if (cmd != ELF_C_READ && cmd != ELF_C_RDWR) {
+ seterr(ERROR_INVALID_CMD);
+ return NULL;
+ }
+ else if (ref) {
+ elf_assert(ref->e_magic == ELF_MAGIC);
+ if (!ref->e_readable || (cmd == ELF_C_RDWR && !ref->e_writable)) {
+ seterr(ERROR_CMDMISMATCH);
+ return NULL;
+ }
+ if (ref->e_kind != ELF_K_AR) {
+ ref->e_count++;
+ return ref;
+ }
+ if (cmd == ELF_C_RDWR) {
+ seterr(ERROR_MEMBERWRITE);
+ return NULL;
+ }
+ if (ref->e_memory) {
+ fd = ref->e_fd;
+ }
+ else if (fd != ref->e_fd) {
+ seterr(ERROR_FDMISMATCH);
+ return NULL;
+ }
+ if (!(arhdr = _elf_arhdr(ref))) {
+ return NULL;
+ }
+ size = arhdr->ar_size;
+ }
+ else if ((off = lseek(fd, (off_t)0, SEEK_END)) == (off_t)-1
+ || (off_t)(size = off) != off) {
+ seterr(ERROR_IO_GETSIZE);
+ return NULL;
+ }
+
+ if (!(elf = (Elf*)malloc(sizeof(Elf)))) {
+ seterr(ERROR_MEM_ELF);
+ return NULL;
+ }
+ *elf = _elf_init;
+ elf->e_fd = fd;
+ elf->e_parent = ref;
+ elf->e_size = elf->e_dsize = size;
+
+ if (cmd != ELF_C_READ) {
+ elf->e_writable = 1;
+ }
+ if (cmd != ELF_C_WRITE) {
+ elf->e_readable = 1;
+ }
+ else {
+ return elf;
+ }
+
+ if (ref) {
+ size_t offset = ref->e_off + sizeof(struct ar_hdr);
+ Elf *xelf;
+
+ elf_assert(arhdr);
+ elf->e_arhdr = arhdr;
+ elf->e_base = ref->e_base + offset;
+ /*
+ * Share the archive's memory image. To avoid
+ * multiple independent elf descriptors if the
+ * same member is requested twice, scan the list
+ * of open members for duplicates.
+ *
+ * I don't know how SVR4 handles this case. Don't rely on it.
+ */
+ for (xelf = ref->e_members; xelf; xelf = xelf->e_link) {
+ elf_assert(xelf->e_parent == ref);
+ if (xelf->e_base == elf->e_base) {
+ free(arhdr);
+ free(elf);
+ xelf->e_count++;
+ return xelf;
+ }
+ }
+ if (size == 0) {
+ elf->e_data = NULL;
+ }
+#if 1
+ else {
+ /*
+ * Archive members may be misaligned. Freezing them will
+ * cause libelf to allocate buffers for translated data,
+ * which should be properly aligned in all cases.
+ */
+ elf_assert(!ref->e_cooked);
+ elf->e_data = elf->e_rawdata = ref->e_data + offset;
+ }
+#else
+ else if (ref->e_data == ref->e_rawdata) {
+ elf_assert(!ref->e_cooked);
+ /*
+ * archive is frozen - freeze member, too
+ */
+ elf->e_data = elf->e_rawdata = ref->e_data + offset;
+ }
+ else {
+ elf_assert(!ref->e_memory);
+ elf->e_data = ref->e_data + offset;
+ /*
+ * The member's memory image may have been modified if
+ * the member has been processed before. Since we need the
+ * original image, we have to re-read the archive file.
+ * Will fail if the archive's file descriptor is disabled.
+ */
+ if (!ref->e_cooked) {
+ ref->e_cooked = 1;
+ }
+ else if (!_elf_read(ref, elf->e_data, offset, size)) {
+ free(arhdr);
+ free(elf);
+ return NULL;
+ }
+ }
+#endif
+ elf->e_next = offset + size + (size & 1);
+ elf->e_disabled = ref->e_disabled;
+ elf->e_memory = ref->e_memory;
+ /* parent/child linking */
+ elf->e_link = ref->e_members;
+ ref->e_members = elf;
+ ref->e_count++;
+ /* Slowaris compatibility - do not rely on this! */
+ ref->e_off = elf->e_next;
+ }
+ else if (size) {
+#if HAVE_MMAP
+ /*
+ * Using mmap on writable files will interfere with elf_update
+ */
+ if (!elf->e_writable && (elf->e_data = _elf_mmap(elf))) {
+ elf->e_unmap_data = 1;
+ }
+ else
+#endif /* HAVE_MMAP */
+ if (!(elf->e_data = _elf_read(elf, NULL, 0, size))) {
+ free(elf);
+ return NULL;
+ }
+ }
+
+ _elf_check_type(elf, size);
+ return elf;
+}
+
+Elf*
+elf_memory(char *image, size_t size) {
+ Elf *elf;
+
+ elf_assert(_elf_init.e_magic == ELF_MAGIC);
+ if (_elf_version == EV_NONE) {
+ seterr(ERROR_VERSION_UNSET);
+ return NULL;
+ }
+ else if (size == 0 || image == NULL) {
+ /* TODO: set error code? */
+ return NULL;
+ }
+
+ if (!(elf = (Elf*)malloc(sizeof(Elf)))) {
+ seterr(ERROR_MEM_ELF);
+ return NULL;
+ }
+ *elf = _elf_init;
+ elf->e_size = elf->e_dsize = size;
+ elf->e_data = elf->e_rawdata = image;
+ elf->e_readable = 1;
+ elf->e_disabled = 1;
+ elf->e_memory = 1;
+
+ _elf_check_type(elf, size);
+ return elf;
+}
+
+#if __LIBELF64
+
+int
+gelf_getclass(Elf *elf) {
+ if (elf && elf->e_kind == ELF_K_ELF && valid_class(elf->e_class)) {
+ return elf->e_class;
+ }
+ return ELFCLASSNONE;
+}
+
+#endif /* __LIBELF64 */
diff --git a/lib/build.bat b/lib/build.bat
new file mode 100644
index 0000000..d930d71
--- /dev/null
+++ b/lib/build.bat
@@ -0,0 +1,36 @@
+@echo off
+
+rem lib/build.bat - build script for W32 port
+rem Copyright (C) 2004 - 2006 Michael Riepe
+rem
+rem This library is free software; you can redistribute it and/or
+rem modify it under the terms of the GNU Library General Public
+rem License as published by the Free Software Foundation; either
+rem version 2 of the License, or (at your option) any later version.
+rem
+rem This library is distributed in the hope that it will be useful,
+rem but WITHOUT ANY WARRANTY; without even the implied warranty of
+rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+rem Library General Public License for more details.
+rem
+rem You should have received a copy of the GNU Library General Public
+rem License along with this library; if not, write to the Free Software
+rem Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+rem @(#) $Id: build.bat,v 1.1 2006/08/21 18:03:48 michael Exp $
+
+rem *** BEGIN EDIT HERE ***
+rem Please uncomment the line that suits your system:
+rem call "C:\Program Files\Microsoft Visual Studio\VC98\bin\vcvars32.bat"
+rem call "C:\Program Files\Microsoft Visual Studio 8\VC\bin\vcvars32.bat"
+rem call "C:\Programme\Microsoft Visual Studio\VC98\bin\vcvars32.bat"
+rem call "C:\Programme\Microsoft Visual Studio 8\VC\bin\vcvars32.bat"
+rem OR, if you have to set the path to the compiler directly:
+rem set PATH="C:\PATH\TO\COMPILER\BINARY;%PATH%"
+rem Of course, you'll have to enter the correct path above.
+rem You may also have to change CC (default: cl.exe) in Makefile.w32.
+rem *** END EDIT HERE ***
+
+copy config.h.w32 config.h
+copy sys_elf.h.w32 sys_elf.h
+nmake /nologo /f Makefile.w32 %1
diff --git a/lib/byteswap.h b/lib/byteswap.h
new file mode 100644
index 0000000..7526d12
--- /dev/null
+++ b/lib/byteswap.h
@@ -0,0 +1,95 @@
+/*
+byteswap.h - functions and macros for byte swapping.
+Copyright (C) 1995 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+/* @(#) $Id: byteswap.h,v 1.7 2008/05/23 08:15:34 michael Exp $ */
+
+#ifndef _BYTESWAP_H
+#define _BYTESWAP_H
+
+#define lu(from,i,s) (((__libelf_u32_t)((unsigned char*)(from))[i])<<(s))
+#define li(from,i,s) (((__libelf_i32_t)(( signed char*)(from))[i])<<(s))
+
+#define __load_u16L(from) ((__libelf_u32_t) \
+ (lu(from,1,8) | lu(from,0,0)))
+#define __load_u16M(from) ((__libelf_u32_t) \
+ (lu(from,0,8) | lu(from,1,0)))
+#define __load_i16L(from) ((__libelf_i32_t) \
+ (li(from,1,8) | lu(from,0,0)))
+#define __load_i16M(from) ((__libelf_i32_t) \
+ (li(from,0,8) | lu(from,1,0)))
+
+#define __load_u32L(from) ((__libelf_u32_t) \
+ (lu(from,3,24) | lu(from,2,16) | lu(from,1,8) | lu(from,0,0)))
+#define __load_u32M(from) ((__libelf_u32_t) \
+ (lu(from,0,24) | lu(from,1,16) | lu(from,2,8) | lu(from,3,0)))
+#define __load_i32L(from) ((__libelf_i32_t) \
+ (li(from,3,24) | lu(from,2,16) | lu(from,1,8) | lu(from,0,0)))
+#define __load_i32M(from) ((__libelf_i32_t) \
+ (li(from,0,24) | lu(from,1,16) | lu(from,2,8) | lu(from,3,0)))
+
+#define su(to,i,v,s) (((char*)(to))[i]=((__libelf_u32_t)(v)>>(s)))
+#define si(to,i,v,s) (((char*)(to))[i]=((__libelf_i32_t)(v)>>(s)))
+
+#define __store_u16L(to,v) \
+ (su(to,1,v,8), su(to,0,v,0))
+#define __store_u16M(to,v) \
+ (su(to,0,v,8), su(to,1,v,0))
+#define __store_i16L(to,v) \
+ (si(to,1,v,8), si(to,0,v,0))
+#define __store_i16M(to,v) \
+ (si(to,0,v,8), si(to,1,v,0))
+
+#define __store_u32L(to,v) \
+ (su(to,3,v,24), su(to,2,v,16), su(to,1,v,8), su(to,0,v,0))
+#define __store_u32M(to,v) \
+ (su(to,0,v,24), su(to,1,v,16), su(to,2,v,8), su(to,3,v,0))
+#define __store_i32L(to,v) \
+ (si(to,3,v,24), si(to,2,v,16), si(to,1,v,8), si(to,0,v,0))
+#define __store_i32M(to,v) \
+ (si(to,0,v,24), si(to,1,v,16), si(to,2,v,8), si(to,3,v,0))
+
+#if __LIBELF64
+
+/*
+ * conversion functions from swap64.c
+ */
+extern __libelf_u64_t _elf_load_u64L(const unsigned char *from);
+extern __libelf_u64_t _elf_load_u64M(const unsigned char *from);
+extern __libelf_i64_t _elf_load_i64L(const unsigned char *from);
+extern __libelf_i64_t _elf_load_i64M(const unsigned char *from);
+extern void _elf_store_u64L(unsigned char *to, __libelf_u64_t v);
+extern void _elf_store_u64M(unsigned char *to, __libelf_u64_t v);
+extern void _elf_store_i64L(unsigned char *to, __libelf_u64_t v);
+extern void _elf_store_i64M(unsigned char *to, __libelf_u64_t v);
+
+/*
+ * aliases for existing conversion code
+ */
+#define __load_u64L _elf_load_u64L
+#define __load_u64M _elf_load_u64M
+#define __load_i64L _elf_load_i64L
+#define __load_i64M _elf_load_i64M
+#define __store_u64L _elf_store_u64L
+#define __store_u64M _elf_store_u64M
+#define __store_i64L _elf_store_i64L
+#define __store_i64M _elf_store_i64M
+
+#endif /* __LIBELF64 */
+
+#endif /* _BYTESWAP_H */
diff --git a/lib/checksum.c b/lib/checksum.c
new file mode 100644
index 0000000..f9e964b
--- /dev/null
+++ b/lib/checksum.c
@@ -0,0 +1,178 @@
+/*
+checksum.c - implementation of the elf{32,64}_checksum(3) functions.
+Copyright (C) 1995 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: checksum.c,v 1.7 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+/*
+ * Compatibility note:
+ *
+ * The algorithm used in {elf32,elf64,gelf}_checksum() does not seem to
+ * be documented. I hope I got it right. My implementation does the
+ * following:
+ *
+ * - skip sections that do not have the SHF_ALLOC flag set
+ * - skip sections of type SHT_NULL, SHT_NOBITS, SHT_DYNSYM and
+ * SHT_DYNAMIC
+ * - add all data bytes from the remaining sections, modulo 2**32
+ * - add upper and lower half of the result
+ * - subtract 0xffff if the result is > 0xffff
+ * - if any error occurs, return 0L
+ */
+
+static int
+skip_section(Elf_Scn *scn, unsigned cls) {
+ if (cls == ELFCLASS32) {
+ Elf32_Shdr *shdr = &scn->s_shdr32;
+
+ if (!(shdr->sh_flags & SHF_ALLOC)) {
+ return 1;
+ }
+ switch (shdr->sh_type) {
+ case SHT_NULL:
+ case SHT_NOBITS:
+ /* Solaris seems to ignore these, too */
+ case SHT_DYNSYM:
+ case SHT_DYNAMIC:
+ return 1;
+ }
+ }
+#if __LIBELF64
+ else if (cls == ELFCLASS64) {
+ Elf64_Shdr *shdr = &scn->s_shdr64;
+
+ if (!(shdr->sh_flags & SHF_ALLOC)) {
+ return 1;
+ }
+ switch (shdr->sh_type) {
+ case SHT_NULL:
+ case SHT_NOBITS:
+ /* Solaris seems to ignore these, too */
+ case SHT_DYNSYM:
+ case SHT_DYNAMIC:
+ return 1;
+ }
+ }
+#endif /* __LIBELF64 */
+ else {
+ seterr(ERROR_UNIMPLEMENTED);
+ }
+ return 0;
+}
+
+static long
+add_bytes(unsigned char *ptr, size_t len) {
+ long csum = 0;
+
+ while (len--) {
+ csum += *ptr++;
+ }
+ return csum;
+}
+
+static long
+_elf_csum(Elf *elf) {
+ long csum = 0;
+ Elf_Data *data;
+ Elf_Scn *scn;
+
+ if (!elf->e_ehdr && !_elf_cook(elf)) {
+ /* propagate errors from _elf_cook */
+ return 0L;
+ }
+ seterr(0);
+ for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+ if (scn->s_index == SHN_UNDEF || skip_section(scn, elf->e_class)) {
+ continue;
+ }
+ data = NULL;
+ while ((data = elf_getdata(scn, data))) {
+ if (data->d_size) {
+ if (data->d_buf == NULL) {
+ seterr(ERROR_NULLBUF);
+ return 0L;
+ }
+ csum += add_bytes(data->d_buf, data->d_size);
+ }
+ }
+ }
+ if (_elf_errno) {
+ return 0L;
+ }
+ csum = (csum & 0xffff) + ((csum >> 16) & 0xffff);
+ if (csum > 0xffff) {
+ csum -= 0xffff;
+ }
+ return csum;
+}
+
+long
+elf32_checksum(Elf *elf) {
+ if (elf) {
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ }
+ else if (elf->e_class != ELFCLASS32) {
+ seterr(ERROR_CLASSMISMATCH);
+ }
+ else {
+ return _elf_csum(elf);
+ }
+ }
+ return 0L;
+}
+
+#if __LIBELF64
+
+long
+elf64_checksum(Elf *elf) {
+ if (elf) {
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ }
+ else if (elf->e_class != ELFCLASS64) {
+ seterr(ERROR_CLASSMISMATCH);
+ }
+ else {
+ return _elf_csum(elf);
+ }
+ }
+ return 0L;
+}
+
+long
+gelf_checksum(Elf *elf) {
+ if (elf) {
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ }
+ else if (!valid_class(elf->e_class)) {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ else {
+ return _elf_csum(elf);
+ }
+ }
+ return 0L;
+}
+
+#endif /* __LIBELF64 */
diff --git a/lib/cntl.c b/lib/cntl.c
new file mode 100644
index 0000000..3f7c5d4
--- /dev/null
+++ b/lib/cntl.c
@@ -0,0 +1,71 @@
+/*
+cntl.c - implementation of the elf_cntl(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: cntl.c,v 1.7 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+int
+elf_cntl(Elf *elf, Elf_Cmd cmd) {
+ Elf_Scn *scn;
+ Elf *child;
+
+ if (!elf) {
+ return -1;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (cmd == ELF_C_FDREAD) {
+ if (!elf->e_readable) {
+ seterr(ERROR_WRONLY);
+ return -1;
+ }
+ }
+ else if (cmd != ELF_C_FDDONE) {
+ seterr(ERROR_INVALID_CMD);
+ return -1;
+ }
+ if (elf->e_disabled) {
+ return 0;
+ }
+ if (elf->e_kind == ELF_K_AR) {
+ for (child = elf->e_members; child; child = child->e_link) {
+ elf_assert(elf == child->e_parent);
+ if (elf_cntl(child, cmd)) {
+ return -1;
+ }
+ }
+ }
+ else if (elf->e_kind == ELF_K_ELF && cmd == ELF_C_FDREAD) {
+ if (!elf->e_ehdr && !_elf_cook(elf)) {
+ return -1;
+ }
+ for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+ if (scn->s_index == SHN_UNDEF || scn->s_type == SHT_NULL) {
+ continue;
+ }
+ else if (!elf_getdata(scn, NULL)) {
+ return -1;
+ }
+ }
+ }
+ elf->e_disabled = 1;
+ return 0;
+}
diff --git a/lib/config.h.w32 b/lib/config.h.w32
new file mode 100644
index 0000000..c4ec0f7
--- /dev/null
+++ b/lib/config.h.w32
@@ -0,0 +1,161 @@
+/*
+ * lib/config.h.w32 - configuration file for W32 port
+ * Copyright (C) 2004 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * @(#) $Id: config.h.w32,v 1.2 2006/09/07 15:55:42 michael Exp $
+ */
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you want to include extra debugging code */
+#define ENABLE_DEBUG 1
+
+/* Define if memmove() does not copy overlapping arrays correctly */
+#undef HAVE_BROKEN_MEMMOVE
+
+/* Define if you have the catgets function. */
+#undef HAVE_CATGETS
+
+/* Define if you have the dgettext function. */
+#undef HAVE_DGETTEXT
+
+/* Define if you have the memset function. */
+#define HAVE_MEMSET 1
+
+/* Define if struct nlist is declared in <elf.h> or <sys/elf.h> */
+#undef HAVE_STRUCT_NLIST_DECLARATION
+
+/* Define if Elf32_Dyn is declared in <link.h> */
+#undef __LIBELF_NEED_LINK_H
+
+/* Define if Elf32_Dyn is declared in <sys/link.h> */
+#undef __LIBELF_NEED_SYS_LINK_H
+
+/* Define to `<elf.h>' or `<sys/elf.h>' if one of them is present */
+#undef __LIBELF_HEADER_ELF_H
+
+/* Define if you want 64-bit support (and your system supports it) */
+#define __LIBELF64 1
+
+/* Define if you want 64-bit support, and are running IRIX */
+#undef __LIBELF64_IRIX
+
+/* Define if you want 64-bit support, and are running Linux */
+#undef __LIBELF64_LINUX
+
+/* Define if you want symbol versioning (and your system supports it) */
+#define __LIBELF_SYMBOL_VERSIONS 1
+
+/* Define if symbol versioning uses Sun section type (SHT_SUNW_*) */
+#define __LIBELF_SUN_SYMBOL_VERSIONS 1
+
+/* Define if symbol versioning uses GNU section types (SHT_GNU_*) */
+#undef __LIBELF_GNU_SYMBOL_VERSIONS
+
+/* Define to a 64-bit signed integer type if one exists */
+#define __libelf_i64_t __int64
+
+/* Define to a 64-bit unsigned integer type if one exists */
+#define __libelf_u64_t unsigned __int64
+
+/* Define to a 32-bit signed integer type if one exists */
+#define __libelf_i32_t int
+
+/* Define to a 32-bit unsigned integer type if one exists */
+#define __libelf_u32_t unsigned int
+
+/* Define to a 16-bit signed integer type if one exists */
+#define __libelf_i16_t short int
+
+/* Define to a 16-bit unsigned integer type if one exists */
+#define __libelf_u16_t unsigned short int
+
+/* The number of bytes in a __int64. */
+#define SIZEOF___INT64 8
+
+/* The number of bytes in a int. */
+#define SIZEOF_INT 4
+
+/* The number of bytes in a long. */
+#define SIZEOF_LONG 4
+
+/* The number of bytes in a long long. */
+#define SIZEOF_LONG_LONG 0
+
+/* The number of bytes in a short. */
+#define SIZEOF_SHORT 2
+
+/* Define if you have the ftruncate function. */
+#undef HAVE_FTRUNCATE
+
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the memcmp function. */
+#define HAVE_MEMCMP 1
+
+/* Define if you have the memcpy function. */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the memmove function. */
+#define HAVE_MEMMOVE 1
+
+/* Define if you have the memset function. */
+#define HAVE_MEMSET 1
+
+/* Define if you have the <ar.h> header file. */
+#undef HAVE_AR_H
+
+/* Define if you have the <elf.h> header file. */
+#undef HAVE_ELF_H
+
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <gelf.h> header file. */
+#undef HAVE_GELF_H
+
+/* Define if you have the <libelf.h> header file. */
+#undef HAVE_LIBELF_H
+
+/* Define if you have the <link.h> header file. */
+#undef HAVE_LINK_H
+
+/* Define if you have the <nlist.h> header file. */
+#undef HAVE_NLIST_H
+
+/* Define if you have the <sys/elf.h> header file. */
+#undef HAVE_SYS_ELF_H
+
+/* Define if you have the <sys/link.h> header file. */
+#undef HAVE_SYS_LINK_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
diff --git a/lib/cook.c b/lib/cook.c
new file mode 100644
index 0000000..066b6f2
--- /dev/null
+++ b/lib/cook.c
@@ -0,0 +1,501 @@
+/*
+ * cook.c - read and translate ELF files.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: cook.c,v 1.29 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+const Elf_Scn _elf_scn_init = INIT_SCN;
+const Scn_Data _elf_data_init = INIT_DATA;
+
+Elf_Type
+_elf_scn_type(unsigned t) {
+ switch (t) {
+ case SHT_DYNAMIC: return ELF_T_DYN;
+ case SHT_DYNSYM: return ELF_T_SYM;
+ case SHT_HASH: return ELF_T_WORD;
+ case SHT_REL: return ELF_T_REL;
+ case SHT_RELA: return ELF_T_RELA;
+ case SHT_SYMTAB: return ELF_T_SYM;
+ case SHT_SYMTAB_SHNDX: return ELF_T_WORD; /* XXX: really? */
+#if __LIBELF_SYMBOL_VERSIONS
+#if __LIBELF_SUN_SYMBOL_VERSIONS
+ case SHT_SUNW_verdef: return ELF_T_VDEF;
+ case SHT_SUNW_verneed: return ELF_T_VNEED;
+ case SHT_SUNW_versym: return ELF_T_HALF;
+#else /* __LIBELF_SUN_SYMBOL_VERSIONS */
+ case SHT_GNU_verdef: return ELF_T_VDEF;
+ case SHT_GNU_verneed: return ELF_T_VNEED;
+ case SHT_GNU_versym: return ELF_T_HALF;
+#endif /* __LIBELF_SUN_SYMBOL_VERSIONS */
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+ }
+ return ELF_T_BYTE;
+}
+
+/*
+ * Check for overflow on 32-bit systems
+ */
+#define overflow(a,b,t) (sizeof(a) < sizeof(t) && (t)(a) != (b))
+
+#define truncerr(t) ((t)==ELF_T_EHDR?ERROR_TRUNC_EHDR: \
+ ((t)==ELF_T_PHDR?ERROR_TRUNC_PHDR: \
+ ERROR_INTERNAL))
+#define memerr(t) ((t)==ELF_T_EHDR?ERROR_MEM_EHDR: \
+ ((t)==ELF_T_PHDR?ERROR_MEM_PHDR: \
+ ERROR_INTERNAL))
+
+Elf_Data*
+_elf_xlatetom(const Elf *elf, Elf_Data *dst, const Elf_Data *src) {
+ if (elf->e_class == ELFCLASS32) {
+ return elf32_xlatetom(dst, src, elf->e_encoding);
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ return elf64_xlatetom(dst, src, elf->e_encoding);
+ }
+#endif /* __LIBELF64 */
+ seterr(ERROR_UNIMPLEMENTED);
+ return NULL;
+}
+
+static char*
+_elf_item(void *buf, Elf *elf, Elf_Type type, size_t off) {
+ Elf_Data src, dst;
+
+ elf_assert(valid_type(type));
+ if (off < 0 || off > elf->e_size) {
+ seterr(ERROR_OUTSIDE);
+ return NULL;
+ }
+
+ src.d_type = type;
+ src.d_version = elf->e_version;
+ src.d_size = _fsize(elf->e_class, src.d_version, type);
+ elf_assert(src.d_size);
+ if ((elf->e_size - off) < src.d_size) {
+ seterr(truncerr(type));
+ return NULL;
+ }
+
+ dst.d_version = _elf_version;
+ dst.d_size = _msize(elf->e_class, dst.d_version, type);
+ elf_assert(dst.d_size);
+
+ if (!(dst.d_buf = buf) && !(dst.d_buf = malloc(dst.d_size))) {
+ seterr(memerr(type));
+ return NULL;
+ }
+
+ elf_assert(elf->e_data);
+ if (elf->e_rawdata) {
+ src.d_buf = elf->e_rawdata + off;
+ }
+ else {
+ src.d_buf = elf->e_data + off;
+ }
+
+ if (_elf_xlatetom(elf, &dst, &src)) {
+ return (char*)dst.d_buf;
+ }
+ if (dst.d_buf != buf) {
+ free(dst.d_buf);
+ }
+ return NULL;
+}
+
+static int
+_elf_cook_phdr(Elf *elf) {
+ size_t num, off, entsz;
+
+ if (elf->e_class == ELFCLASS32) {
+ num = ((Elf32_Ehdr*)elf->e_ehdr)->e_phnum;
+ off = ((Elf32_Ehdr*)elf->e_ehdr)->e_phoff;
+ entsz = ((Elf32_Ehdr*)elf->e_ehdr)->e_phentsize;
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ num = ((Elf64_Ehdr*)elf->e_ehdr)->e_phnum;
+ off = ((Elf64_Ehdr*)elf->e_ehdr)->e_phoff;
+ entsz = ((Elf64_Ehdr*)elf->e_ehdr)->e_phentsize;
+ /*
+ * Check for overflow on 32-bit systems
+ */
+ if (overflow(off, ((Elf64_Ehdr*)elf->e_ehdr)->e_phoff, Elf64_Off)) {
+ seterr(ERROR_OUTSIDE);
+ return 0;
+ }
+ }
+#endif /* __LIBELF64 */
+ else {
+ seterr(ERROR_UNIMPLEMENTED);
+ return 0;
+ }
+ if (off) {
+ Elf_Scn *scn;
+ size_t size;
+ unsigned i;
+ char *p;
+
+ if (num == PN_XNUM) {
+ /*
+ * Overflow in ehdr->e_phnum.
+ * Get real value from first SHDR.
+ */
+ if (!(scn = elf->e_scn_1)) {
+ seterr(ERROR_NOSUCHSCN);
+ return 0;
+ }
+ if (elf->e_class == ELFCLASS32) {
+ num = scn->s_shdr32.sh_info;
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ num = scn->s_shdr64.sh_info;
+ }
+#endif /* __LIBELF64 */
+ /* we already had this
+ else {
+ seterr(ERROR_UNIMPLEMENTED);
+ return 0;
+ }
+ */
+ }
+
+ size = _fsize(elf->e_class, elf->e_version, ELF_T_PHDR);
+ elf_assert(size);
+#if ENABLE_EXTENDED_FORMAT
+ if (entsz < size) {
+#else /* ENABLE_EXTENDED_FORMAT */
+ if (entsz != size) {
+#endif /* ENABLE_EXTENDED_FORMAT */
+ seterr(ERROR_EHDR_PHENTSIZE);
+ return 0;
+ }
+ size = _msize(elf->e_class, _elf_version, ELF_T_PHDR);
+ elf_assert(size);
+ if (!(p = malloc(num * size))) {
+ seterr(memerr(ELF_T_PHDR));
+ return 0;
+ }
+ for (i = 0; i < num; i++) {
+ if (!_elf_item(p + i * size, elf, ELF_T_PHDR, off + i * entsz)) {
+ free(p);
+ return 0;
+ }
+ }
+ elf->e_phdr = p;
+ elf->e_phnum = num;
+ }
+ return 1;
+}
+
+static int
+_elf_cook_shdr(Elf *elf) {
+ size_t num, off, entsz;
+
+ if (elf->e_class == ELFCLASS32) {
+ num = ((Elf32_Ehdr*)elf->e_ehdr)->e_shnum;
+ off = ((Elf32_Ehdr*)elf->e_ehdr)->e_shoff;
+ entsz = ((Elf32_Ehdr*)elf->e_ehdr)->e_shentsize;
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ num = ((Elf64_Ehdr*)elf->e_ehdr)->e_shnum;
+ off = ((Elf64_Ehdr*)elf->e_ehdr)->e_shoff;
+ entsz = ((Elf64_Ehdr*)elf->e_ehdr)->e_shentsize;
+ /*
+ * Check for overflow on 32-bit systems
+ */
+ if (overflow(off, ((Elf64_Ehdr*)elf->e_ehdr)->e_shoff, Elf64_Off)) {
+ seterr(ERROR_OUTSIDE);
+ return 0;
+ }
+ }
+#endif /* __LIBELF64 */
+ else {
+ seterr(ERROR_UNIMPLEMENTED);
+ return 0;
+ }
+ if (off) {
+ struct tmp {
+ Elf_Scn scn;
+ Scn_Data data;
+ } *head;
+ Elf_Data src, dst;
+ Elf_Scn *scn;
+ Scn_Data *sd;
+ unsigned i;
+
+ if (off < 0 || off > elf->e_size) {
+ seterr(ERROR_OUTSIDE);
+ return 0;
+ }
+
+ src.d_type = ELF_T_SHDR;
+ src.d_version = elf->e_version;
+ src.d_size = _fsize(elf->e_class, src.d_version, ELF_T_SHDR);
+ elf_assert(src.d_size);
+#if ENABLE_EXTENDED_FORMAT
+ if (entsz < src.d_size) {
+#else /* ENABLE_EXTENDED_FORMAT */
+ if (entsz != src.d_size) {
+#endif /* ENABLE_EXTENDED_FORMAT */
+ seterr(ERROR_EHDR_SHENTSIZE);
+ return 0;
+ }
+ dst.d_version = EV_CURRENT;
+
+ if (num == 0) {
+ union {
+ Elf32_Shdr sh32;
+#if __LIBELF64
+ Elf64_Shdr sh64;
+#endif /* __LIBELF64 */
+ } u;
+
+ /*
+ * Overflow in ehdr->e_shnum.
+ * Get real value from first SHDR.
+ */
+ if (elf->e_size - off < entsz) {
+ seterr(ERROR_TRUNC_SHDR);
+ return 0;
+ }
+ if (elf->e_rawdata) {
+ src.d_buf = elf->e_rawdata + off;
+ }
+ else {
+ src.d_buf = elf->e_data + off;
+ }
+ dst.d_buf = &u;
+ dst.d_size = sizeof(u);
+ if (!_elf_xlatetom(elf, &dst, &src)) {
+ return 0;
+ }
+ elf_assert(dst.d_size == _msize(elf->e_class, EV_CURRENT, ELF_T_SHDR));
+ elf_assert(dst.d_type == ELF_T_SHDR);
+ if (elf->e_class == ELFCLASS32) {
+ num = u.sh32.sh_size;
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ num = u.sh64.sh_size;
+ /*
+ * Check for overflow on 32-bit systems
+ */
+ if (overflow(num, u.sh64.sh_size, Elf64_Xword)) {
+ seterr(ERROR_OUTSIDE);
+ return 0;
+ }
+ }
+#endif /* __LIBELF64 */
+ }
+
+ if ((elf->e_size - off) / entsz < num) {
+ seterr(ERROR_TRUNC_SHDR);
+ return 0;
+ }
+
+ if (!(head = (struct tmp*)malloc(num * sizeof(struct tmp)))) {
+ seterr(ERROR_MEM_SCN);
+ return 0;
+ }
+ for (scn = NULL, i = num; i-- > 0; ) {
+ head[i].scn = _elf_scn_init;
+ head[i].data = _elf_data_init;
+ head[i].scn.s_link = scn;
+ if (!scn) {
+ elf->e_scn_n = &head[i].scn;
+ }
+ scn = &head[i].scn;
+ sd = &head[i].data;
+
+ if (elf->e_rawdata) {
+ src.d_buf = elf->e_rawdata + off + i * entsz;
+ }
+ else {
+ src.d_buf = elf->e_data + off + i * entsz;
+ }
+ dst.d_buf = &scn->s_uhdr;
+ dst.d_size = sizeof(scn->s_uhdr);
+ if (!_elf_xlatetom(elf, &dst, &src)) {
+ elf->e_scn_n = NULL;
+ free(head);
+ return 0;
+ }
+ elf_assert(dst.d_size == _msize(elf->e_class, EV_CURRENT, ELF_T_SHDR));
+ elf_assert(dst.d_type == ELF_T_SHDR);
+
+ scn->s_elf = elf;
+ scn->s_index = i;
+ scn->s_data_1 = sd;
+ scn->s_data_n = sd;
+
+ sd->sd_scn = scn;
+
+ if (elf->e_class == ELFCLASS32) {
+ Elf32_Shdr *shdr = &scn->s_shdr32;
+
+ scn->s_type = shdr->sh_type;
+ scn->s_size = shdr->sh_size;
+ scn->s_offset = shdr->sh_offset;
+ sd->sd_data.d_align = shdr->sh_addralign;
+ sd->sd_data.d_type = _elf_scn_type(scn->s_type);
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ Elf64_Shdr *shdr = &scn->s_shdr64;
+
+ scn->s_type = shdr->sh_type;
+ scn->s_size = shdr->sh_size;
+ scn->s_offset = shdr->sh_offset;
+ sd->sd_data.d_align = shdr->sh_addralign;
+ /*
+ * Check for overflow on 32-bit systems
+ */
+ if (overflow(scn->s_size, shdr->sh_size, Elf64_Xword)
+ || overflow(scn->s_offset, shdr->sh_offset, Elf64_Off)
+ || overflow(sd->sd_data.d_align, shdr->sh_addralign, Elf64_Xword)) {
+ seterr(ERROR_OUTSIDE);
+ return 0;
+ }
+ sd->sd_data.d_type = _elf_scn_type(scn->s_type);
+ /*
+ * QUIRKS MODE:
+ *
+ * Some 64-bit architectures use 64-bit entries in the
+ * .hash section. This violates the ELF standard, and
+ * should be fixed. It's mostly harmless as long as the
+ * binary and the machine running your program have the
+ * same byte order, but you're in trouble if they don't,
+ * and if the entry size is wrong.
+ *
+ * As a workaround, I let libelf guess the right size
+ * for the binary. This relies pretty much on the fact
+ * that the binary provides correct data in the section
+ * headers. If it doesn't, it's probably broken anyway.
+ * Therefore, libelf uses a standard conforming value
+ * when it's not absolutely sure.
+ */
+ if (scn->s_type == SHT_HASH) {
+ int override = 0;
+
+ /*
+ * sh_entsize must reflect the entry size
+ */
+ if (shdr->sh_entsize == ELF64_FSZ_ADDR) {
+ override++;
+ }
+ /*
+ * sh_size must be a multiple of sh_entsize
+ */
+ if (shdr->sh_size % ELF64_FSZ_ADDR == 0) {
+ override++;
+ }
+ /*
+ * There must be room for at least 2 entries
+ */
+ if (shdr->sh_size >= 2 * ELF64_FSZ_ADDR) {
+ override++;
+ }
+ /*
+ * sh_addralign must be correctly set
+ */
+ if (shdr->sh_addralign == ELF64_FSZ_ADDR) {
+ override++;
+ }
+ /*
+ * The section must be properly aligned
+ */
+ if (shdr->sh_offset % ELF64_FSZ_ADDR == 0) {
+ override++;
+ }
+ /* XXX: also look at the data? */
+ /*
+ * Make a conservative decision...
+ */
+ if (override >= 5) {
+ sd->sd_data.d_type = ELF_T_ADDR;
+ }
+ }
+ /*
+ * END QUIRKS MODE.
+ */
+ }
+#endif /* __LIBELF64 */
+ /* we already had this
+ else {
+ seterr(ERROR_UNIMPLEMENTED);
+ return 0;
+ }
+ */
+
+ sd->sd_data.d_size = scn->s_size;
+ sd->sd_data.d_version = _elf_version;
+ }
+ elf_assert(scn == &head[0].scn);
+ elf->e_scn_1 = &head[0].scn;
+ head[0].scn.s_freeme = 1;
+ }
+ return 1;
+}
+
+static int
+_elf_cook_file(Elf *elf) {
+ elf->e_ehdr = _elf_item(NULL, elf, ELF_T_EHDR, 0);
+ if (!elf->e_ehdr) {
+ return 0;
+ }
+ /*
+ * Note: _elf_cook_phdr may require the first section header!
+ */
+ if (!_elf_cook_shdr(elf)) {
+ return 0;
+ }
+ if (!_elf_cook_phdr(elf)) {
+ return 0;
+ }
+ return 1;
+}
+
+int
+_elf_cook(Elf *elf) {
+ elf_assert(_elf_scn_init.s_magic == SCN_MAGIC);
+ elf_assert(_elf_data_init.sd_magic == DATA_MAGIC);
+ elf_assert(elf);
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ elf_assert(elf->e_kind == ELF_K_ELF);
+ elf_assert(!elf->e_ehdr);
+ if (!valid_version(elf->e_version)) {
+ seterr(ERROR_UNKNOWN_VERSION);
+ }
+ else if (!valid_encoding(elf->e_encoding)) {
+ seterr(ERROR_UNKNOWN_ENCODING);
+ }
+ else if (valid_class(elf->e_class)) {
+ return _elf_cook_file(elf);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ return 0;
+}
diff --git a/lib/data.c b/lib/data.c
new file mode 100644
index 0000000..53d78c3
--- /dev/null
+++ b/lib/data.c
@@ -0,0 +1,36 @@
+/*
+ * data.c - libelf internal variables.
+ * Copyright (C) 1995 - 1998, 2007 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: data.c,v 1.8 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+unsigned _elf_version = EV_NONE;
+int _elf_errno = 0;
+int _elf_fill = 0;
+
+#if ENABLE_SANITY_CHECKS
+#define SANITY_CHECKS -1
+#else
+#define SANITY_CHECKS 0
+#endif
+
+int _elf_sanity_checks = SANITY_CHECKS;
diff --git a/lib/elf_repl.h b/lib/elf_repl.h
new file mode 100644
index 0000000..c5cf90f
--- /dev/null
+++ b/lib/elf_repl.h
@@ -0,0 +1,996 @@
+/*
+ * elf_repl.h - public header file for systems that lack it.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* @(#) $Id: elf_repl.h,v 1.22 2009/11/01 13:04:19 michael Exp $ */
+
+/*
+ * NEVER INCLUDE THIS FILE DIRECTLY - USE <libelf.h> INSTEAD!
+ */
+
+#ifndef _ELF_REPL_H
+#define _ELF_REPL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * Scalar data types
+ */
+typedef __libelf_u32_t Elf32_Addr;
+typedef __libelf_u16_t Elf32_Half;
+typedef __libelf_u32_t Elf32_Off;
+typedef __libelf_i32_t Elf32_Sword;
+typedef __libelf_u32_t Elf32_Word;
+
+#define ELF32_FSZ_ADDR 4
+#define ELF32_FSZ_HALF 2
+#define ELF32_FSZ_OFF 4
+#define ELF32_FSZ_SWORD 4
+#define ELF32_FSZ_WORD 4
+
+#if __LIBELF64
+
+typedef __libelf_u64_t Elf64_Addr;
+typedef __libelf_u16_t Elf64_Half;
+typedef __libelf_u64_t Elf64_Off;
+typedef __libelf_i32_t Elf64_Sword;
+typedef __libelf_u32_t Elf64_Word;
+typedef __libelf_i64_t Elf64_Sxword;
+typedef __libelf_u64_t Elf64_Xword;
+
+#define ELF64_FSZ_ADDR 8
+#define ELF64_FSZ_HALF 2
+#define ELF64_FSZ_OFF 8
+#define ELF64_FSZ_SWORD 4
+#define ELF64_FSZ_WORD 4
+#define ELF64_FSZ_SXWORD 8
+#define ELF64_FSZ_XWORD 8
+
+/*
+ * Blame Sun for this...
+ */
+typedef __libelf_u64_t Elf64_Lword;
+typedef __libelf_u64_t Elf32_Lword;
+
+#endif /* __LIBELF64 */
+
+/*
+ * ELF header
+ */
+#define EI_NIDENT 16
+
+typedef struct {
+ unsigned char e_ident[EI_NIDENT];
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry;
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+#if __LIBELF64
+typedef struct {
+ unsigned char e_ident[EI_NIDENT];
+ Elf64_Half e_type;
+ Elf64_Half e_machine;
+ Elf64_Word e_version;
+ Elf64_Addr e_entry;
+ Elf64_Off e_phoff;
+ Elf64_Off e_shoff;
+ Elf64_Word e_flags;
+ Elf64_Half e_ehsize;
+ Elf64_Half e_phentsize;
+ Elf64_Half e_phnum;
+ Elf64_Half e_shentsize;
+ Elf64_Half e_shnum;
+ Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+#endif /* __LIBELF64 */
+
+/*
+ * e_ident
+ */
+#define EI_MAG0 0
+#define EI_MAG1 1
+#define EI_MAG2 2
+#define EI_MAG3 3
+#define EI_CLASS 4
+#define EI_DATA 5
+#define EI_VERSION 6
+#define EI_OSABI 7
+#define EI_ABIVERSION 8
+#define EI_PAD 9
+
+#define ELFMAG0 0x7f
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+/*
+ * e_ident[EI_CLASS]
+ */
+#define ELFCLASSNONE 0
+#define ELFCLASS32 1
+#define ELFCLASS64 2
+#define ELFCLASSNUM 3
+
+/*
+ * e_ident[EI_DATA]
+ */
+#define ELFDATANONE 0
+#define ELFDATA2LSB 1
+#define ELFDATA2MSB 2
+#define ELFDATANUM 3
+
+/*
+ * e_ident[EI_OSABI]
+ */
+#define ELFOSABI_NONE 0 /* No extensions or unspecified */
+#define ELFOSABI_SYSV ELFOSABI_NONE
+#define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */
+#define ELFOSABI_NETBSD 2 /* NetBSD */
+#define ELFOSABI_LINUX 3 /* Linux */
+#define ELFOSABI_SOLARIS 6 /* Sun Solaris */
+#define ELFOSABI_AIX 7 /* AIX */
+#define ELFOSABI_IRIX 8 /* IRIX */
+#define ELFOSABI_FREEBSD 9 /* FreeBSD */
+#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */
+#define ELFOSABI_MODESTO 11 /* Novell Modesto */
+#define ELFOSABI_OPENBSD 12 /* Open BSD */
+#define ELFOSABI_OPENVMS 13 /* Open VMS */
+#define ELFOSABI_NSK 14 /* Hewlett-Packard Non-Stop Kernel */
+#define ELFOSABI_AROS 15 /* Amiga Research OS */
+/* these are probably obsolete: */
+#define ELFOSABI_ARM 97 /* ARM */
+#define ELFOSABI_STANDALONE 255 /* standalone (embedded) application */
+
+
+/*
+ * e_type
+ */
+#define ET_NONE 0
+#define ET_REL 1
+#define ET_EXEC 2
+#define ET_DYN 3
+#define ET_CORE 4
+#define ET_NUM 5
+#define ET_LOOS 0xfe00
+#define ET_HIOS 0xfeff
+#define ET_LOPROC 0xff00
+#define ET_HIPROC 0xffff
+
+/*
+ * e_machine
+ */
+#define EM_NONE 0 /* No machine */
+#define EM_M32 1 /* AT&T WE 32100 */
+#define EM_SPARC 2 /* SPARC */
+#define EM_386 3 /* Intel 80386 */
+#define EM_68K 4 /* Motorola 68000 */
+#define EM_88K 5 /* Motorola 88000 */
+#define EM_486 6 /* Intel i486 (DO NOT USE THIS ONE) */
+#define EM_860 7 /* Intel 80860 */
+#define EM_MIPS 8 /* MIPS I Architecture */
+#define EM_S370 9 /* IBM System/370 Processor */
+#define EM_MIPS_RS3_LE 10 /* MIPS RS3000 Little-endian */
+#define EM_SPARC64 11 /* SPARC 64-bit */
+#define EM_PARISC 15 /* Hewlett-Packard PA-RISC */
+#define EM_VPP500 17 /* Fujitsu VPP500 */
+#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */
+#define EM_960 19 /* Intel 80960 */
+#define EM_PPC 20 /* PowerPC */
+#define EM_PPC64 21 /* 64-bit PowerPC */
+#define EM_S390 22 /* IBM System/390 Processor */
+#define EM_V800 36 /* NEC V800 */
+#define EM_FR20 37 /* Fujitsu FR20 */
+#define EM_RH32 38 /* TRW RH-32 */
+#define EM_RCE 39 /* Motorola RCE */
+#define EM_ARM 40 /* Advanced RISC Machines ARM */
+#define EM_ALPHA 41 /* Digital Alpha */
+#define EM_SH 42 /* Hitachi SH */
+#define EM_SPARCV9 43 /* SPARC Version 9 */
+#define EM_TRICORE 44 /* Siemens TriCore embedded processor */
+#define EM_ARC 45 /* Argonaut RISC Core, Argonaut Technologies Inc. */
+#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 IA-64 processor architecture */
+#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 embedded RISC processor */
+#define EM_NDR1 57 /* Denso NDR1 microprocessor */
+#define EM_STARCORE 58 /* Motorola Star*Core processor */
+#define EM_ME16 59 /* Toyota ME16 processor */
+#define EM_ST100 60 /* STMicroelectronics ST100 processor */
+#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ embedded processor family */
+#define EM_X86_64 62 /* AMD x86-64 architecture */
+#define EM_AMD64 EM_X86_64
+#define EM_PDSP 63 /* Sony DSP Processor */
+#define EM_FX66 66 /* Siemens FX66 microcontroller */
+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 bit microcontroller */
+#define EM_ST7 68 /* STMicroelectronics ST7 8-bit microcontroller */
+#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 microcontroller */
+#define EM_VAX 75 /* Digital VAX */
+#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */
+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */
+#define EM_HUANY 81 /* Harvard University machine-independent object files */
+#define EM_PRISM 82 /* SiTera Prism */
+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
+#define EM_FR30 84 /* Fujitsu FR30 */
+#define EM_D10V 85 /* Mitsubishi D10V */
+#define EM_D30V 86 /* Mitsubishi D30V */
+#define EM_V850 87 /* NEC v850 */
+#define EM_M32R 88 /* Mitsubishi M32R */
+#define EM_MN10300 89 /* Matsushita MN10300 */
+#define EM_MN10200 90 /* Matsushita MN10200 */
+#define EM_PJ 91 /* picoJava */
+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
+#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
+#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor */
+#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose Processor */
+#define EM_NS32K 97 /* National Semiconductor 32000 series */
+#define EM_TPC 98 /* Tenor Network TPC processor */
+#define EM_SNP1K 99 /* Trebia SNP 1000 processor */
+#define EM_ST200 100 /* STMicroelectronics (www.st.com) ST200 microcontroller */
+#define EM_IP2K 101 /* Ubicom IP2xxx microcontroller family */
+#define EM_MAX 102 /* MAX Processor */
+#define EM_CR 103 /* National Semiconductor CompactRISC microprocessor */
+#define EM_F2MC16 104 /* Fujitsu F2MC16 */
+#define EM_MSP430 105 /* Texas Instruments embedded microcontroller msp430 */
+#define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor */
+#define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors */
+#define EM_SEP 108 /* Sharp embedded microprocessor */
+#define EM_ARCA 109 /* Arca RISC Microprocessor */
+#define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University */
+#define EM_NUM 111
+
+/*
+ * e_ident[EI_VERSION], e_version
+ */
+#define EV_NONE 0
+#define EV_CURRENT 1
+#define EV_NUM 2
+
+/*
+ * Section header
+ */
+typedef struct {
+ Elf32_Word sh_name;
+ Elf32_Word sh_type;
+ Elf32_Word sh_flags;
+ Elf32_Addr sh_addr;
+ Elf32_Off sh_offset;
+ Elf32_Word sh_size;
+ Elf32_Word sh_link;
+ Elf32_Word sh_info;
+ Elf32_Word sh_addralign;
+ Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+#if __LIBELF64
+typedef struct {
+ Elf64_Word sh_name;
+ Elf64_Word sh_type;
+ Elf64_Xword sh_flags;
+ Elf64_Addr sh_addr;
+ Elf64_Off sh_offset;
+ Elf64_Xword sh_size;
+ Elf64_Word sh_link;
+ Elf64_Word sh_info;
+ Elf64_Xword sh_addralign;
+ Elf64_Xword sh_entsize;
+} Elf64_Shdr;
+#endif /* __LIBELF64 */
+
+/*
+ * Special section indices
+ */
+#define SHN_UNDEF 0
+#define SHN_LORESERVE 0xff00
+#define SHN_LOPROC 0xff00
+#define SHN_HIPROC 0xff1f
+#define SHN_LOOS 0xff20
+#define SHN_HIOS 0xff3f
+#define SHN_ABS 0xfff1
+#define SHN_COMMON 0xfff2
+#define SHN_XINDEX 0xffff
+#define SHN_HIRESERVE 0xffff
+
+/*
+ * sh_type
+ */
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+#define SHT_SYMTAB 2
+#define SHT_STRTAB 3
+#define SHT_RELA 4
+#define SHT_HASH 5
+#define SHT_DYNAMIC 6
+#define SHT_NOTE 7
+#define SHT_NOBITS 8
+#define SHT_REL 9
+#define SHT_SHLIB 10
+#define SHT_DYNSYM 11
+#define SHT_INIT_ARRAY 14
+#define SHT_FINI_ARRAY 15
+#define SHT_PREINIT_ARRAY 16
+#define SHT_GROUP 17
+#define SHT_SYMTAB_SHNDX 18
+#define SHT_NUM 19
+#define SHT_LOOS 0x60000000
+#define SHT_HIOS 0x6fffffff
+#define SHT_LOPROC 0x70000000
+#define SHT_HIPROC 0x7fffffff
+#define SHT_LOUSER 0x80000000
+#define SHT_HIUSER 0xffffffff
+
+/*
+ * Solaris extensions
+ */
+#define SHT_LOSUNW 0x6ffffff4
+#define SHT_SUNW_dof 0x6ffffff4
+#define SHT_SUNW_cap 0x6ffffff5
+#define SHT_SUNW_SIGNATURE 0x6ffffff6
+#define SHT_SUNW_ANNOTATE 0x6ffffff7
+#define SHT_SUNW_DEBUGSTR 0x6ffffff8
+#define SHT_SUNW_DEBUG 0x6ffffff9
+#define SHT_SUNW_move 0x6ffffffa
+#define SHT_SUNW_COMDAT 0x6ffffffb
+#define SHT_SUNW_syminfo 0x6ffffffc
+#define SHT_SUNW_verdef 0x6ffffffd
+#define SHT_SUNW_verneed 0x6ffffffe
+#define SHT_SUNW_versym 0x6fffffff
+#define SHT_HISUNW 0x6fffffff
+
+#define SHT_SPARC_GOTDATA 0x70000000
+#define SHT_AMD64_UNWIND 0x70000001
+
+/*
+ * GNU extensions
+ */
+#define SHT_GNU_verdef 0x6ffffffd
+#define SHT_GNU_verneed 0x6ffffffe
+#define SHT_GNU_versym 0x6fffffff
+
+/*
+ * sh_flags
+ */
+#define SHF_WRITE 0x1
+#define SHF_ALLOC 0x2
+#define SHF_EXECINSTR 0x4
+#define SHF_MERGE 0x10
+#define SHF_STRINGS 0x20
+#define SHF_INFO_LINK 0x40
+#define SHF_LINK_ORDER 0x80
+#define SHF_OS_NONCONFORMING 0x100
+#define SHF_GROUP 0x200
+#define SHF_TLS 0x400
+#define SHF_MASKOS 0x0ff00000
+#define SHF_MASKPROC 0xf0000000
+
+/*
+ * Solaris extensions
+ */
+#define SHF_AMD64_LARGE 0x10000000
+#define SHF_ORDERED 0x40000000
+#define SHF_EXCLUDE 0x80000000
+
+/*
+ * Section group flags
+ */
+#define GRP_COMDAT 0x1
+#define GRP_MASKOS 0x0ff00000
+#define GRP_MASKPROC 0xf0000000
+
+/*
+ * Symbol table
+ */
+typedef struct {
+ Elf32_Word st_name;
+ Elf32_Addr st_value;
+ Elf32_Word st_size;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf32_Half st_shndx;
+} Elf32_Sym;
+
+#if __LIBELF64
+typedef struct {
+ Elf64_Word st_name;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf64_Half st_shndx;
+ Elf64_Addr st_value;
+ Elf64_Xword st_size;
+} Elf64_Sym;
+#endif /* __LIBELF64 */
+
+/*
+ * Special symbol indices
+ */
+#define STN_UNDEF 0
+
+/*
+ * Macros for manipulating st_info
+ */
+#define ELF32_ST_BIND(i) ((i)>>4)
+#define ELF32_ST_TYPE(i) ((i)&0xf)
+#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
+
+#if __LIBELF64
+#define ELF64_ST_BIND(i) ((i)>>4)
+#define ELF64_ST_TYPE(i) ((i)&0xf)
+#define ELF64_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
+#endif /* __LIBELF64 */
+
+/*
+ * Symbol binding
+ */
+#define STB_LOCAL 0
+#define STB_GLOBAL 1
+#define STB_WEAK 2
+#define STB_NUM 3
+#define STB_LOOS 10
+#define STB_HIOS 12
+#define STB_LOPROC 13
+#define STB_HIPROC 15
+
+/*
+ * Symbol types
+ */
+#define STT_NOTYPE 0
+#define STT_OBJECT 1
+#define STT_FUNC 2
+#define STT_SECTION 3
+#define STT_FILE 4
+#define STT_COMMON 5
+#define STT_TLS 6
+#define STT_NUM 7
+#define STT_LOOS 10
+#define STT_HIOS 12
+#define STT_LOPROC 13
+#define STT_HIPROC 15
+
+/*
+ * Macros for manipulating st_other
+ */
+#define ELF32_ST_VISIBILITY(o) ((o)&0x3)
+#if __LIBELF64
+#define ELF64_ST_VISIBILITY(o) ((o)&0x3)
+#endif /* __LIBELF64 */
+
+/*
+ * Symbol visibility
+ */
+#define STV_DEFAULT 0
+#define STV_INTERNAL 1
+#define STV_HIDDEN 2
+#define STV_PROTECTED 3
+
+/*
+ * Relocation
+ */
+typedef struct {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+} Elf32_Rel;
+
+typedef struct {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+ Elf32_Sword r_addend;
+} Elf32_Rela;
+
+#if __LIBELF64
+typedef struct {
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+} Elf64_Rel;
+
+typedef struct {
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+ Elf64_Sxword r_addend;
+} Elf64_Rela;
+#endif /* __LIBELF64 */
+
+/*
+ * Macros for manipulating r_info
+ */
+#define ELF32_R_SYM(i) ((i)>>8)
+#define ELF32_R_TYPE(i) ((unsigned char)(i))
+#define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t))
+
+#if __LIBELF64
+#define ELF64_R_SYM(i) ((Elf64_Xword)(i)>>32)
+#define ELF64_R_TYPE(i) ((i)&0xffffffffL)
+#define ELF64_R_INFO(s,t) (((Elf64_Xword)(s)<<32)+((t)&0xffffffffL))
+#endif /* __LIBELF64 */
+
+/*
+ * Note entry header
+ */
+typedef struct {
+ Elf32_Word n_namesz; /* name size */
+ Elf32_Word n_descsz; /* descriptor size */
+ Elf32_Word n_type; /* descriptor type */
+} Elf32_Nhdr;
+
+#if __LIBELF64
+/* Solaris and GNU use this layout. Be compatible. */
+/* XXX: Latest ELF specs say it's 64-bit!!! */
+typedef struct {
+ Elf64_Word n_namesz; /* name size */
+ Elf64_Word n_descsz; /* descriptor size */
+ Elf64_Word n_type; /* descriptor type */
+} Elf64_Nhdr;
+#endif /* __LIBELF64 */
+
+/*
+ * Well-known descriptor types for ET_CORE files
+ */
+#define NT_PRSTATUS 1
+#define NT_PRFPREG 2
+#define NT_PRPSINFO 3
+
+/*
+ * Program header
+ */
+typedef struct {
+ Elf32_Word p_type;
+ Elf32_Off p_offset;
+ Elf32_Addr p_vaddr;
+ Elf32_Addr p_paddr;
+ Elf32_Word p_filesz;
+ Elf32_Word p_memsz;
+ Elf32_Word p_flags;
+ Elf32_Word p_align;
+} Elf32_Phdr;
+
+#if __LIBELF64
+typedef struct {
+ Elf64_Word p_type;
+ Elf64_Word p_flags;
+ Elf64_Off p_offset;
+ Elf64_Addr p_vaddr;
+ Elf64_Addr p_paddr;
+ Elf64_Xword p_filesz;
+ Elf64_Xword p_memsz;
+ Elf64_Xword p_align;
+} Elf64_Phdr;
+#endif /* __LIBELF64 */
+
+/*
+ * Special numbers
+ */
+#define PN_XNUM 0xffff
+
+/*
+ * p_type
+ */
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_TLS 7
+#define PT_NUM 8
+#define PT_LOOS 0x60000000
+#define PT_HIOS 0x6fffffff
+#define PT_LOPROC 0x70000000
+#define PT_HIPROC 0x7fffffff
+
+/*
+ * Solaris extensions
+ */
+
+#define PT_SUNW_UNWIND 0x6464e550
+#define PT_LOSUNW 0x6ffffffa
+#define PT_SUNWBSS 0x6ffffffa
+#define PT_SUNWSTACK 0x6ffffffb
+#define PT_SUNWDTRACE 0x6ffffffc
+#define PT_SUNWCAP 0x6ffffffd
+#define PT_HISUNW 0x6fffffff
+
+/*
+ * p_flags
+ */
+#define PF_X 0x1
+#define PF_W 0x2
+#define PF_R 0x4
+#define PF_MASKOS 0x0ff00000
+#define PF_MASKPROC 0xf0000000
+
+/*
+ * Dynamic structure
+ */
+typedef struct {
+ Elf32_Sword d_tag;
+ union {
+ Elf32_Word d_val;
+ Elf32_Addr d_ptr;
+ } d_un;
+} Elf32_Dyn;
+
+#if __LIBELF64
+typedef struct {
+ Elf64_Sxword d_tag;
+ union {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } d_un;
+} Elf64_Dyn;
+#endif /* __LIBELF64 */
+
+/*
+ * Dynamic array tags
+ */
+ /* d_un exec shared */
+#define DT_NULL 0 /* ign. mand. mand. */
+#define DT_NEEDED 1 /* d_val opt. opt. */
+#define DT_PLTRELSZ 2 /* d_val opt. opt. */
+#define DT_PLTGOT 3 /* d_ptr opt. opt. */
+#define DT_HASH 4 /* d_ptr mand. mand. */
+#define DT_STRTAB 5 /* d_ptr mand. mand. */
+#define DT_SYMTAB 6 /* d_ptr mand. mand. */
+#define DT_RELA 7 /* d_ptr mand. opt. */
+#define DT_RELASZ 8 /* d_val mand. opt. */
+#define DT_RELAENT 9 /* d_val mand. opt. */
+#define DT_STRSZ 10 /* d_val mand. mand. */
+#define DT_SYMENT 11 /* d_val mand. mand. */
+#define DT_INIT 12 /* d_ptr opt. opt. */
+#define DT_FINI 13 /* d_ptr opt. opt. */
+#define DT_SONAME 14 /* d_val ign. opt. */
+#define DT_RPATH 15 /* d_val opt. ign. */
+#define DT_SYMBOLIC 16 /* ign. ign. opt. */
+#define DT_REL 17 /* d_ptr mand. opt. */
+#define DT_RELSZ 18 /* d_val mand. opt. */
+#define DT_RELENT 19 /* d_val mand. opt. */
+#define DT_PLTREL 20 /* d_val opt. opt. */
+#define DT_DEBUG 21 /* d_ptr opt. ign. */
+#define DT_TEXTREL 22 /* ign. opt. opt. */
+#define DT_JMPREL 23 /* d_ptr opt. opt. */
+#define DT_BIND_NOW 24 /* ign. opt. opt. */
+#define DT_INIT_ARRAY 25 /* d_ptr opt. opt. */
+#define DT_FINI_ARRAY 26 /* d_ptr opt. opt. */
+#define DT_INIT_ARRAYSZ 27 /* d_val opt. opt. */
+#define DT_FINI_ARRAYSZ 28 /* d_val opt. opt. */
+#define DT_RUNPATH 29 /* d_val opt. opt. */
+#define DT_FLAGS 30 /* d_val opt. opt. */
+#define DT_ENCODING 32 /* odd/even encoding rule starts here */
+#define DT_PREINIT_ARRAY 32 /* d_ptr opt. ign. */
+#define DT_PREINIT_ARRAYSZ 33 /* d_val opt. ign. */
+#define DT_NUM 34
+#define DT_LOOS 0x6000000D
+#define DT_HIOS 0x6ffff000
+#define DT_LOPROC 0x70000000
+#define DT_HIPROC 0x7fffffff
+
+/*
+ * DT_FLAGS values
+ */
+#define DF_ORIGIN 0x1
+#define DF_SYMBOLIC 0x2
+#define DF_TEXTREL 0x4
+#define DF_BIND_NOW 0x8
+#define DF_STATIC_TLS 0x10
+
+/*
+ * Solaris extensions
+ */
+#define DT_VALRNGLO 0x6ffffd00
+#define DT_CHECKSUM 0x6ffffdf8
+#define DT_PLTPADSZ 0x6ffffdf9
+#define DT_MOVEENT 0x6ffffdfa
+#define DT_MOVESZ 0x6ffffdfb
+#define DT_FEATURE_1 0x6ffffdfc
+#define DT_POSFLAG_1 0x6ffffdfd
+#define DT_SYMINSZ 0x6ffffdfe
+#define DT_SYMINENT 0x6ffffdff
+#define DT_VALRNGHI 0x6ffffdff
+
+#define DT_ADDRRNGLO 0x6ffffe00
+#define DT_CONFIG 0x6ffffefa
+#define DT_DEPAUDIT 0x6ffffefb
+#define DT_AUDIT 0x6ffffefc
+#define DT_PLTPAD 0x6ffffefd
+#define DT_MOVETAB 0x6ffffefe
+#define DT_SYMINFO 0x6ffffeff
+#define DT_ADDRRNGHI 0x6ffffeff
+
+#define DT_RELACOUNT 0x6ffffff9
+#define DT_RELCOUNT 0x6ffffffa
+#define DT_FLAGS_1 0x6ffffffb
+#define DT_VERDEF 0x6ffffffc
+#define DT_VERDEFNUM 0x6ffffffd
+#define DT_VERNEED 0x6ffffffe
+#define DT_VERNEEDNUM 0x6fffffff
+
+#define DT_AUXILIARY 0x7ffffffd
+#define DT_USED 0x7ffffffe
+#define DT_FILTER 0x7fffffff
+
+/*
+ * GNU extensions
+ */
+#define DT_VERSYM 0x6ffffff0
+
+/*
+ * DT_FEATURE_1 values
+ */
+#define DTF_1_PARINIT 0x1
+#define DTF_1_CONFEXP 0x2
+
+/*
+ * DT_POSFLAG_1 values
+ */
+#define DF_P1_LAZYLOAD 0x1
+#define DF_P1_GROUPPERM 0x2
+
+/*
+ * DT_FLAGS_1 values
+ */
+#define DF_1_NOW 0x00000001
+#define DF_1_GLOBAL 0x00000002
+#define DF_1_GROUP 0x00000004
+#define DF_1_NODELETE 0x00000008
+#define DF_1_LOADFLTR 0x00000010
+#define DF_1_INITFIRST 0x00000020
+#define DF_1_NOOPEN 0x00000040
+#define DF_1_ORIGIN 0x00000080
+#define DF_1_DIRECT 0x00000100
+#define DF_1_TRANS 0x00000200
+#define DF_1_INTERPOSE 0x00000400
+#define DF_1_NODEFLIB 0x00000800
+#define DF_1_NODUMP 0x00001000
+#define DF_1_CONFALT 0x00002000
+#define DF_1_ENDFILTEE 0x00004000
+#define DF_1_DISPRELDNE 0x00008000
+#define DF_1_DISPRELPND 0x00010000
+
+/*
+ * Syminfo structure
+ */
+typedef struct {
+ Elf32_Half si_boundto;
+ Elf32_Half si_flags;
+} Elf32_Syminfo;
+
+#if __LIBELF64
+typedef struct {
+ Elf64_Half si_boundto;
+ Elf64_Half si_flags;
+} Elf64_Syminfo;
+#endif /* __LIBELF64 */
+
+/*
+ * Syminfo version (stored in unused first entry)
+ */
+#define SYMINFO_NONE 0
+#define SYMINFO_CURRENT 1
+#define SYMINFO_NUM 2
+
+/*
+ * si_boundto special values
+ */
+#define SYMINFO_BT_LOWRESERVE 0xff00
+#define SYMINFO_BT_PARENT 0xfffe /* bound to parent */
+#define SYMINFO_BT_SELF 0xffff /* bound to self */
+
+/*
+ * si_flags
+ */
+#define SYMINFO_FLG_DIRECT 0x01 /* bound to an object */
+#define SYMINFO_FLG_PASSTHRU 0x02 /* pass-thru symbol */
+#define SYMINFO_FLG_COPY 0x04 /* result of a copy relocation */
+#define SYMINFO_FLG_LAZYLOAD 0x08 /* bound to lazy-loaded object */
+
+/*
+ * Version definitions
+ */
+typedef struct {
+ Elf32_Half vd_version;
+ Elf32_Half vd_flags;
+ Elf32_Half vd_ndx;
+ Elf32_Half vd_cnt;
+ Elf32_Word vd_hash;
+ Elf32_Word vd_aux;
+ Elf32_Word vd_next;
+} Elf32_Verdef;
+
+typedef struct {
+ Elf32_Word vda_name;
+ Elf32_Word vda_next;
+} Elf32_Verdaux;
+
+typedef struct {
+ Elf32_Half vn_version;
+ Elf32_Half vn_cnt;
+ Elf32_Word vn_file;
+ Elf32_Word vn_aux;
+ Elf32_Word vn_next;
+} Elf32_Verneed;
+
+typedef struct {
+ Elf32_Word vna_hash;
+ Elf32_Half vna_flags;
+ Elf32_Half vna_other;
+ Elf32_Word vna_name;
+ Elf32_Word vna_next;
+} Elf32_Vernaux;
+
+typedef Elf32_Half Elf32_Versym;
+
+#if __LIBELF64
+
+typedef struct {
+ Elf64_Half vd_version;
+ Elf64_Half vd_flags;
+ Elf64_Half vd_ndx;
+ Elf64_Half vd_cnt;
+ Elf64_Word vd_hash;
+ Elf64_Word vd_aux;
+ Elf64_Word vd_next;
+} Elf64_Verdef;
+
+typedef struct {
+ Elf64_Word vda_name;
+ Elf64_Word vda_next;
+} Elf64_Verdaux;
+
+typedef struct {
+ Elf64_Half vn_version;
+ Elf64_Half vn_cnt;
+ Elf64_Word vn_file;
+ Elf64_Word vn_aux;
+ Elf64_Word vn_next;
+} Elf64_Verneed;
+
+typedef struct {
+ Elf64_Word vna_hash;
+ Elf64_Half vna_flags;
+ Elf64_Half vna_other;
+ Elf64_Word vna_name;
+ Elf64_Word vna_next;
+} Elf64_Vernaux;
+
+typedef Elf64_Half Elf64_Versym;
+
+#endif /* __LIBELF64 */
+
+/*
+ * vd_version
+ */
+#define VER_DEF_NONE 0
+#define VER_DEF_CURRENT 1
+#define VER_DEF_NUM 2
+
+/*
+ * vn_version
+ */
+#define VER_NEED_NONE 0
+#define VER_NEED_CURRENT 1
+#define VER_NEED_NUM 2
+
+/*
+ * vd_flags / vna_flags
+ */
+#define VER_FLG_BASE 0x1 /* vd_flags only */
+#define VER_FLG_WEAK 0x2
+
+/*
+ * Elf*_Versym special values
+ */
+#define VER_NDX_LOCAL 0
+#define VER_NDX_GLOBAL 1
+
+/*
+ * Solaris extensions
+ */
+
+/*
+ * Move section
+ */
+#if __LIBELF64
+
+typedef struct {
+ Elf32_Lword m_value;
+ Elf32_Word m_info;
+ Elf32_Word m_poffset;
+ Elf32_Half m_repeat;
+ Elf32_Half m_stride;
+} Elf32_Move;
+
+typedef struct {
+ Elf64_Lword m_value;
+ Elf64_Xword m_info;
+ Elf64_Xword m_poffset;
+ Elf64_Half m_repeat;
+ Elf64_Half m_stride;
+} Elf64_Move;
+
+#define ELF32_M_SYM(info) ((info)>>8)
+#define ELF32_M_SIZE(info) ((unsigned char)(info))
+#define ELF32_M_INFO(sym, sz) (((sym)<<8)+(unsigned char)(sz))
+
+#define ELF64_M_SYM(info) ((Elf64_Xword)(info)>>8)
+#define ELF64_M_SIZE(info) ((unsigned char)(info))
+#define ELF64_M_INFO(sym, sz) (((Elf64_Xword)(sym)<<8)+(unsigned char)(sz))
+
+#endif /* __LIBELF64 */
+
+/*
+ * Capabilities
+ */
+
+typedef struct {
+ Elf32_Word c_tag;
+ union {
+ Elf32_Word c_val;
+ Elf32_Addr c_ptr;
+ } c_un;
+} Elf32_Cap;
+
+#if __LIBELF64
+
+typedef struct {
+ Elf64_Xword c_tag;
+ union {
+ Elf64_Xword c_val;
+ Elf64_Addr c_ptr;
+ } c_un;
+} Elf64_Cap;
+
+#endif /* __LIBELF64 */
+
+#define CA_SUNW_NULL 0 /* c_un ignored */
+#define CA_SUNW_HW_1 1 /* c_un.c_val */
+#define CA_SUNW_SF_1 2 /* c_un.c_val */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _ELF_REPL_H */
diff --git a/lib/end.c b/lib/end.c
new file mode 100644
index 0000000..c604239
--- /dev/null
+++ b/lib/end.c
@@ -0,0 +1,118 @@
+/*
+ * end.c - implementation of the elf_end(3) function.
+ * Copyright (C) 1995 - 2004 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: end.c,v 1.12 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+#if HAVE_MMAP
+#include <sys/mman.h>
+#endif /* HAVE_MMAP */
+
+static void
+_elf_free(void *ptr) {
+ if (ptr) {
+ free(ptr);
+ }
+}
+
+static void
+_elf_free_scns(Elf *elf, Elf_Scn *scn) {
+ Scn_Data *sd, *tmp;
+ Elf_Scn *freescn;
+
+ for (freescn = NULL; scn; scn = scn->s_link) {
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ elf_assert(scn->s_elf == elf);
+ for (sd = scn->s_data_1; sd; sd = tmp) {
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ elf_assert(sd->sd_scn == scn);
+ tmp = sd->sd_link;
+ if (sd->sd_free_data) {
+ _elf_free(sd->sd_memdata);
+ }
+ if (sd->sd_freeme) {
+ free(sd);
+ }
+ }
+ if ((sd = scn->s_rawdata)) {
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ elf_assert(sd->sd_scn == scn);
+ if (sd->sd_free_data) {
+ _elf_free(sd->sd_memdata);
+ }
+ if (sd->sd_freeme) {
+ free(sd);
+ }
+ }
+ if (scn->s_freeme) {
+ _elf_free(freescn);
+ freescn = scn;
+ }
+ }
+ _elf_free(freescn);
+}
+
+int
+elf_end(Elf *elf) {
+ Elf **siblings;
+
+ if (!elf) {
+ return 0;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (--elf->e_count) {
+ return elf->e_count;
+ }
+ if (elf->e_parent) {
+ elf_assert(elf->e_parent->e_magic == ELF_MAGIC);
+ elf_assert(elf->e_parent->e_kind == ELF_K_AR);
+ siblings = &elf->e_parent->e_members;
+ while (*siblings) {
+ if (*siblings == elf) {
+ *siblings = elf->e_link;
+ break;
+ }
+ siblings = &(*siblings)->e_link;
+ }
+ elf_end(elf->e_parent);
+ _elf_free(elf->e_arhdr);
+ }
+#if HAVE_MMAP
+ else if (elf->e_unmap_data) {
+ munmap(elf->e_data, elf->e_size);
+ }
+#endif /* HAVE_MMAP */
+ else if (!elf->e_memory) {
+ _elf_free(elf->e_data);
+ }
+ _elf_free_scns(elf, elf->e_scn_1);
+ if (elf->e_rawdata != elf->e_data) {
+ _elf_free(elf->e_rawdata);
+ }
+ if (elf->e_free_syms) {
+ _elf_free(elf->e_symtab);
+ }
+ _elf_free(elf->e_ehdr);
+ _elf_free(elf->e_phdr);
+ free(elf);
+ return 0;
+}
diff --git a/lib/errmsg.c b/lib/errmsg.c
new file mode 100644
index 0000000..883243f
--- /dev/null
+++ b/lib/errmsg.c
@@ -0,0 +1,77 @@
+/*
+ * errmsg.c - implementation of the elf_errmsg(3) function.
+ * Copyright (C) 1995 - 1999, 2004 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: errmsg.c,v 1.11 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+#if HAVE_DGETTEXT
+# undef HAVE_CATGETS
+# include <libintl.h>
+#else /* HAVE_DGETTEXT */
+# define dgettext(dom, str) str
+#endif /* HAVE_DGETTEXT */
+
+#if HAVE_CATGETS
+# include <nl_types.h>
+static nl_catd _libelf_cat = (nl_catd)0;
+#endif /* HAVE_CATGETS */
+
+#if HAVE_DGETTEXT || HAVE_CATGETS
+static const char domain[] = "libelf";
+#endif /* HAVE_DGETTEXT || HAVE_CATGETS */
+
+#if PIC
+static const char *_messages[] = {
+#else /* PIC */
+static const char *const _messages[] = {
+#endif /* PIC */
+#define __err__(a,b) b,
+#include <errors.h> /* include string tables from errors.h */
+#undef __err__
+};
+
+const char*
+elf_errmsg(int err) {
+ if (err == 0) {
+ err = _elf_errno;
+ if (err == 0) {
+ return NULL;
+ }
+ }
+ else if (err == -1) {
+ err = _elf_errno;
+ }
+
+ if (err < 0 || err >= ERROR_NUM || _messages[err] == NULL) {
+ err = ERROR_UNKNOWN;
+ }
+
+#if HAVE_CATGETS
+ if (_libelf_cat == (nl_catd)0) {
+ _libelf_cat = catopen(domain, 0);
+ }
+ if (_libelf_cat != (nl_catd)-1) {
+ return catgets(_libelf_cat, 1, err + 1, _messages[err]);
+ }
+#endif /* HAVE_CATGETS */
+ return dgettext(domain, _messages[err]);
+}
diff --git a/lib/errno.c b/lib/errno.c
new file mode 100644
index 0000000..1902322
--- /dev/null
+++ b/lib/errno.c
@@ -0,0 +1,32 @@
+/*
+errno.c - implementation of the elf_errno(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: errno.c,v 1.7 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+int
+elf_errno(void) {
+ int tmp = _elf_errno;
+
+ _elf_errno = 0;
+ return tmp;
+}
diff --git a/lib/errors.h b/lib/errors.h
new file mode 100644
index 0000000..80ee70b
--- /dev/null
+++ b/lib/errors.h
@@ -0,0 +1,100 @@
+/*
+ * errors.h - exhaustive list of all error codes and messages for libelf.
+ * Copyright (C) 1995 - 2003, 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* @(#) $Id: errors.h,v 1.18 2008/05/23 08:15:34 michael Exp $ */
+
+/* dummy for xgettext */
+#define _(str) str
+
+__err__(ERROR_OK, _("no error"))
+__err__(ERROR_UNKNOWN, _("unknown error"))
+__err__(ERROR_INTERNAL, _("Internal error: unknown reason"))
+__err__(ERROR_UNIMPLEMENTED, _("Internal error: not implemented"))
+__err__(ERROR_WRONLY, _("Request error: cntl(ELF_C_FDREAD) on write-only file"))
+__err__(ERROR_INVALID_CMD, _("Request error: invalid ELF_C_* argument"))
+__err__(ERROR_FDDISABLED, _("Request error: file descriptor disabled"))
+__err__(ERROR_NOTARCHIVE, _("Request error: not an archive"))
+__err__(ERROR_BADOFF, _("Request error: offset out of range"))
+__err__(ERROR_UNKNOWN_VERSION, _("Request error: unknown ELF version"))
+__err__(ERROR_CMDMISMATCH, _("Request error: ELF_C_* argument does not match"))
+__err__(ERROR_MEMBERWRITE, _("Request error: archive member begin() for writing"))
+__err__(ERROR_FDMISMATCH, _("Request error: archive/member file descriptor mismatch"))
+__err__(ERROR_NOTELF, _("Request error: not an ELF file"))
+__err__(ERROR_CLASSMISMATCH, _("Request error: class file/memory mismatch"))
+__err__(ERROR_UNKNOWN_TYPE, _("Request error: invalid ELF_T_* argument"))
+__err__(ERROR_UNKNOWN_ENCODING, _("Request error: unknown data encoding"))
+__err__(ERROR_DST2SMALL, _("Request error: destination buffer too small"))
+__err__(ERROR_NULLBUF, _("Request error: d_buf is NULL"))
+__err__(ERROR_UNKNOWN_CLASS, _("Request error: unknown ELF class"))
+__err__(ERROR_ELFSCNMISMATCH, _("Request error: section does not belong to file"))
+__err__(ERROR_NOSUCHSCN, _("Request error: no section at index"))
+__err__(ERROR_NULLSCN, _("Request error: can't manipulate null section"))
+__err__(ERROR_SCNDATAMISMATCH, _("Request error: data does not belong to section"))
+__err__(ERROR_NOSTRTAB, _("Request error: no string table"))
+__err__(ERROR_BADSTROFF, _("Request error: string table offset out of range"))
+__err__(ERROR_RDONLY, _("Request error: update(ELF_C_WRITE) on read-only file"))
+__err__(ERROR_IO_SEEK, _("I/O error: seek"))
+__err__(ERROR_IO_2BIG, _("I/O error: file too big for memory"))
+__err__(ERROR_IO_READ, _("I/O error: raw read"))
+__err__(ERROR_IO_GETSIZE, _("I/O error: get file size"))
+__err__(ERROR_IO_WRITE, _("I/O error: output write"))
+__err__(ERROR_IO_TRUNC, _("I/O error: can't truncate output file"))
+__err__(ERROR_VERSION_UNSET, _("Sequence error: must set ELF version first"))
+__err__(ERROR_NOEHDR, _("Sequence error: must create ELF header first"))
+__err__(ERROR_OUTSIDE, _("Format error: reference outside file"))
+__err__(ERROR_TRUNC_ARHDR, _("Format error: archive header truncated"))
+__err__(ERROR_ARFMAG, _("Format error: archive fmag"))
+__err__(ERROR_ARHDR, _("Format error: archive header"))
+__err__(ERROR_TRUNC_MEMBER, _("Format error: archive member truncated"))
+__err__(ERROR_SIZE_ARSYMTAB, _("Format error: archive symbol table size"))
+__err__(ERROR_ARSTRTAB, _("Format error: archive string table"))
+__err__(ERROR_ARSPECIAL, _("Format error: archive special name unknown"))
+__err__(ERROR_TRUNC_EHDR, _("Format error: ELF header truncated"))
+__err__(ERROR_TRUNC_PHDR, _("Format error: program header table truncated"))
+__err__(ERROR_TRUNC_SHDR, _("Format error: section header table truncated"))
+__err__(ERROR_TRUNC_SCN, _("Format error: data region truncated"))
+__err__(ERROR_ALIGN_PHDR, _("Format error: program header table alignment"))
+__err__(ERROR_ALIGN_SHDR, _("Format error: section header table alignment"))
+__err__(ERROR_VERDEF_FORMAT, _("Format error: bad parameter in Verdef record"))
+__err__(ERROR_VERDEF_VERSION, _("Format error: unknown Verdef version"))
+__err__(ERROR_VERNEED_FORMAT, _("Format error: bad parameter in Verneed record"))
+__err__(ERROR_VERNEED_VERSION, _("Format error: unknown Verneed version"))
+__err__(ERROR_EHDR_SHNUM, _("Format error: bad e_shnum value"))
+__err__(ERROR_EHDR_SHENTSIZE, _("Format error: bad e_shentsize value"))
+__err__(ERROR_EHDR_PHENTSIZE, _("Format error: bad e_phentsize value"))
+__err__(ERROR_UNTERM, _("Format error: unterminated string in string table"))
+__err__(ERROR_SCN2SMALL, _("Layout error: section size too small for data"))
+__err__(ERROR_SCN_OVERLAP, _("Layout error: overlapping sections"))
+__err__(ERROR_MEM_ELF, _("Memory error: elf descriptor"))
+__err__(ERROR_MEM_ARSYMTAB, _("Memory error: archive symbol table"))
+__err__(ERROR_MEM_ARHDR, _("Memory error: archive member header"))
+__err__(ERROR_MEM_EHDR, _("Memory error: ELF header"))
+__err__(ERROR_MEM_PHDR, _("Memory error: program header table"))
+__err__(ERROR_MEM_SHDR, _("Memory error: section header table"))
+__err__(ERROR_MEM_SCN, _("Memory error: section descriptor"))
+__err__(ERROR_MEM_SCNDATA, _("Memory error: section data"))
+__err__(ERROR_MEM_OUTBUF, _("Memory error: output file space"))
+__err__(ERROR_MEM_TEMPORARY, _("Memory error: temporary buffer"))
+__err__(ERROR_BADVALUE, _("GElf error: value out of range"))
+__err__(ERROR_BADINDEX, _("GElf error: index out of range"))
+__err__(ERROR_BADTYPE, _("GElf error: type mismatch"))
+__err__(ERROR_MEM_SYM, _("GElf error: not enough memory for GElf_Sym"))
+__err__(ERROR_MEM_DYN, _("GElf error: not enough memory for GElf_Dyn"))
+__err__(ERROR_MEM_RELA, _("GElf error: not enough memory for GElf_Rela"))
+__err__(ERROR_MEM_REL, _("GElf error: not enough memory for GElf_Rel"))
diff --git a/lib/ext_types.h b/lib/ext_types.h
new file mode 100644
index 0000000..ead116d
--- /dev/null
+++ b/lib/ext_types.h
@@ -0,0 +1,334 @@
+/*
+ext_types.h - external representation of ELF data types.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+/* @(#) $Id: ext_types.h,v 1.9 2008/05/23 08:15:34 michael Exp $ */
+
+#ifndef _EXT_TYPES_H
+#define _EXT_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * Scalar data types
+ */
+typedef unsigned char __ext_Elf32_Addr [ELF32_FSZ_ADDR];
+typedef unsigned char __ext_Elf32_Half [ELF32_FSZ_HALF];
+typedef unsigned char __ext_Elf32_Off [ELF32_FSZ_OFF];
+typedef unsigned char __ext_Elf32_Sword [ELF32_FSZ_SWORD];
+typedef unsigned char __ext_Elf32_Word [ELF32_FSZ_WORD];
+
+#if __LIBELF64
+
+typedef unsigned char __ext_Elf32_Lword [8];
+
+typedef unsigned char __ext_Elf64_Addr [ELF64_FSZ_ADDR];
+typedef unsigned char __ext_Elf64_Half [ELF64_FSZ_HALF];
+typedef unsigned char __ext_Elf64_Off [ELF64_FSZ_OFF];
+typedef unsigned char __ext_Elf64_Sword [ELF64_FSZ_SWORD];
+typedef unsigned char __ext_Elf64_Word [ELF64_FSZ_WORD];
+typedef unsigned char __ext_Elf64_Sxword[ELF64_FSZ_SXWORD];
+typedef unsigned char __ext_Elf64_Xword [ELF64_FSZ_XWORD];
+
+typedef unsigned char __ext_Elf64_Lword [8];
+
+#endif /* __LIBELF64 */
+
+/*
+ * ELF header
+ */
+typedef struct {
+ unsigned char e_ident[EI_NIDENT];
+ __ext_Elf32_Half e_type;
+ __ext_Elf32_Half e_machine;
+ __ext_Elf32_Word e_version;
+ __ext_Elf32_Addr e_entry;
+ __ext_Elf32_Off e_phoff;
+ __ext_Elf32_Off e_shoff;
+ __ext_Elf32_Word e_flags;
+ __ext_Elf32_Half e_ehsize;
+ __ext_Elf32_Half e_phentsize;
+ __ext_Elf32_Half e_phnum;
+ __ext_Elf32_Half e_shentsize;
+ __ext_Elf32_Half e_shnum;
+ __ext_Elf32_Half e_shstrndx;
+} __ext_Elf32_Ehdr;
+
+#if __LIBELF64
+typedef struct {
+ unsigned char e_ident[EI_NIDENT];
+ __ext_Elf64_Half e_type;
+ __ext_Elf64_Half e_machine;
+ __ext_Elf64_Word e_version;
+ __ext_Elf64_Addr e_entry;
+ __ext_Elf64_Off e_phoff;
+ __ext_Elf64_Off e_shoff;
+ __ext_Elf64_Word e_flags;
+ __ext_Elf64_Half e_ehsize;
+ __ext_Elf64_Half e_phentsize;
+ __ext_Elf64_Half e_phnum;
+ __ext_Elf64_Half e_shentsize;
+ __ext_Elf64_Half e_shnum;
+ __ext_Elf64_Half e_shstrndx;
+} __ext_Elf64_Ehdr;
+#endif /* __LIBELF64 */
+
+/*
+ * Section header
+ */
+typedef struct {
+ __ext_Elf32_Word sh_name;
+ __ext_Elf32_Word sh_type;
+ __ext_Elf32_Word sh_flags;
+ __ext_Elf32_Addr sh_addr;
+ __ext_Elf32_Off sh_offset;
+ __ext_Elf32_Word sh_size;
+ __ext_Elf32_Word sh_link;
+ __ext_Elf32_Word sh_info;
+ __ext_Elf32_Word sh_addralign;
+ __ext_Elf32_Word sh_entsize;
+} __ext_Elf32_Shdr;
+
+#if __LIBELF64
+typedef struct {
+ __ext_Elf64_Word sh_name;
+ __ext_Elf64_Word sh_type;
+ __ext_Elf64_Xword sh_flags;
+ __ext_Elf64_Addr sh_addr;
+ __ext_Elf64_Off sh_offset;
+ __ext_Elf64_Xword sh_size;
+ __ext_Elf64_Word sh_link;
+ __ext_Elf64_Word sh_info;
+ __ext_Elf64_Xword sh_addralign;
+ __ext_Elf64_Xword sh_entsize;
+} __ext_Elf64_Shdr;
+#endif /* __LIBELF64 */
+
+/*
+ * Symbol table
+ */
+typedef struct {
+ __ext_Elf32_Word st_name;
+ __ext_Elf32_Addr st_value;
+ __ext_Elf32_Word st_size;
+ unsigned char st_info;
+ unsigned char st_other;
+ __ext_Elf32_Half st_shndx;
+} __ext_Elf32_Sym;
+
+#if __LIBELF64
+typedef struct {
+ __ext_Elf64_Word st_name;
+ unsigned char st_info;
+ unsigned char st_other;
+ __ext_Elf64_Half st_shndx;
+ __ext_Elf64_Addr st_value;
+ __ext_Elf64_Xword st_size;
+} __ext_Elf64_Sym;
+#endif /* __LIBELF64 */
+
+/*
+ * Relocation
+ */
+typedef struct {
+ __ext_Elf32_Addr r_offset;
+ __ext_Elf32_Word r_info;
+} __ext_Elf32_Rel;
+
+typedef struct {
+ __ext_Elf32_Addr r_offset;
+ __ext_Elf32_Word r_info;
+ __ext_Elf32_Sword r_addend;
+} __ext_Elf32_Rela;
+
+#if __LIBELF64
+typedef struct {
+ __ext_Elf64_Addr r_offset;
+#if __LIBELF64_IRIX
+ __ext_Elf64_Word r_sym;
+ unsigned char r_ssym;
+ unsigned char r_type3;
+ unsigned char r_type2;
+ unsigned char r_type;
+#else /* __LIBELF64_IRIX */
+ __ext_Elf64_Xword r_info;
+#endif /* __LIBELF64_IRIX */
+} __ext_Elf64_Rel;
+
+typedef struct {
+ __ext_Elf64_Addr r_offset;
+#if __LIBELF64_IRIX
+ __ext_Elf64_Word r_sym;
+ unsigned char r_ssym;
+ unsigned char r_type3;
+ unsigned char r_type2;
+ unsigned char r_type;
+#else /* __LIBELF64_IRIX */
+ __ext_Elf64_Xword r_info;
+#endif /* __LIBELF64_IRIX */
+ __ext_Elf64_Sxword r_addend;
+} __ext_Elf64_Rela;
+#endif /* __LIBELF64 */
+
+/*
+ * Program header
+ */
+typedef struct {
+ __ext_Elf32_Word p_type;
+ __ext_Elf32_Off p_offset;
+ __ext_Elf32_Addr p_vaddr;
+ __ext_Elf32_Addr p_paddr;
+ __ext_Elf32_Word p_filesz;
+ __ext_Elf32_Word p_memsz;
+ __ext_Elf32_Word p_flags;
+ __ext_Elf32_Word p_align;
+} __ext_Elf32_Phdr;
+
+#if __LIBELF64
+typedef struct {
+ __ext_Elf64_Word p_type;
+ __ext_Elf64_Word p_flags;
+ __ext_Elf64_Off p_offset;
+ __ext_Elf64_Addr p_vaddr;
+ __ext_Elf64_Addr p_paddr;
+ __ext_Elf64_Xword p_filesz;
+ __ext_Elf64_Xword p_memsz;
+ __ext_Elf64_Xword p_align;
+} __ext_Elf64_Phdr;
+#endif /* __LIBELF64 */
+
+/*
+ * Dynamic structure
+ */
+typedef struct {
+ __ext_Elf32_Sword d_tag;
+ union {
+ __ext_Elf32_Word d_val;
+ __ext_Elf32_Addr d_ptr;
+ } d_un;
+} __ext_Elf32_Dyn;
+
+#if __LIBELF64
+typedef struct {
+ __ext_Elf64_Sxword d_tag;
+ union {
+ __ext_Elf64_Xword d_val;
+ __ext_Elf64_Addr d_ptr;
+ } d_un;
+} __ext_Elf64_Dyn;
+#endif /* __LIBELF64 */
+
+/*
+ * Version definitions
+ */
+typedef struct {
+ __ext_Elf32_Half vd_version;
+ __ext_Elf32_Half vd_flags;
+ __ext_Elf32_Half vd_ndx;
+ __ext_Elf32_Half vd_cnt;
+ __ext_Elf32_Word vd_hash;
+ __ext_Elf32_Word vd_aux;
+ __ext_Elf32_Word vd_next;
+} __ext_Elf32_Verdef;
+
+typedef struct {
+ __ext_Elf32_Word vda_name;
+ __ext_Elf32_Word vda_next;
+} __ext_Elf32_Verdaux;
+
+typedef struct {
+ __ext_Elf32_Half vn_version;
+ __ext_Elf32_Half vn_cnt;
+ __ext_Elf32_Word vn_file;
+ __ext_Elf32_Word vn_aux;
+ __ext_Elf32_Word vn_next;
+} __ext_Elf32_Verneed;
+
+typedef struct {
+ __ext_Elf32_Word vna_hash;
+ __ext_Elf32_Half vna_flags;
+ __ext_Elf32_Half vna_other;
+ __ext_Elf32_Word vna_name;
+ __ext_Elf32_Word vna_next;
+} __ext_Elf32_Vernaux;
+
+#if __LIBELF64
+
+typedef struct {
+ __ext_Elf64_Half vd_version;
+ __ext_Elf64_Half vd_flags;
+ __ext_Elf64_Half vd_ndx;
+ __ext_Elf64_Half vd_cnt;
+ __ext_Elf64_Word vd_hash;
+ __ext_Elf64_Word vd_aux;
+ __ext_Elf64_Word vd_next;
+} __ext_Elf64_Verdef;
+
+typedef struct {
+ __ext_Elf64_Word vda_name;
+ __ext_Elf64_Word vda_next;
+} __ext_Elf64_Verdaux;
+
+typedef struct {
+ __ext_Elf64_Half vn_version;
+ __ext_Elf64_Half vn_cnt;
+ __ext_Elf64_Word vn_file;
+ __ext_Elf64_Word vn_aux;
+ __ext_Elf64_Word vn_next;
+} __ext_Elf64_Verneed;
+
+typedef struct {
+ __ext_Elf64_Word vna_hash;
+ __ext_Elf64_Half vna_flags;
+ __ext_Elf64_Half vna_other;
+ __ext_Elf64_Word vna_name;
+ __ext_Elf64_Word vna_next;
+} __ext_Elf64_Vernaux;
+
+#endif /* __LIBELF64 */
+
+/*
+ * Move section
+ */
+#if __LIBELF64
+
+typedef struct {
+ __ext_Elf32_Lword m_value;
+ __ext_Elf32_Word m_info;
+ __ext_Elf32_Word m_poffset;
+ __ext_Elf32_Half m_repeat;
+ __ext_Elf32_Half m_stride;
+} __ext_Elf32_Move;
+
+typedef struct {
+ __ext_Elf64_Lword m_value;
+ __ext_Elf64_Xword m_info;
+ __ext_Elf64_Xword m_poffset;
+ __ext_Elf64_Half m_repeat;
+ __ext_Elf64_Half m_stride;
+} __ext_Elf64_Move;
+
+#endif /* __LIBELF64 */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _EXT_TYPES_H */
diff --git a/lib/fill.c b/lib/fill.c
new file mode 100644
index 0000000..e64cc14
--- /dev/null
+++ b/lib/fill.c
@@ -0,0 +1,29 @@
+/*
+fill.c - implementation of the elf_fill(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: fill.c,v 1.7 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+void
+elf_fill(int fill) {
+ _elf_fill = fill;
+}
diff --git a/lib/flag.c b/lib/flag.c
new file mode 100644
index 0000000..1845ff9
--- /dev/null
+++ b/lib/flag.c
@@ -0,0 +1,92 @@
+/*
+flag.c - implementation of the elf_flag*(3) functions.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: flag.c,v 1.7 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+static unsigned
+_elf_flag(unsigned *f, Elf_Cmd cmd, unsigned flags) {
+ if (cmd == ELF_C_SET) {
+ return *f |= flags;
+ }
+ if (cmd == ELF_C_CLR) {
+ return *f &= ~flags;
+ }
+ seterr(ERROR_INVALID_CMD);
+ return 0;
+}
+
+unsigned
+elf_flagdata(Elf_Data *data, Elf_Cmd cmd, unsigned flags) {
+ Scn_Data *sd = (Scn_Data*)data;
+
+ if (!sd) {
+ return 0;
+ }
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ return _elf_flag(&sd->sd_data_flags, cmd, flags);
+}
+
+unsigned
+elf_flagehdr(Elf *elf, Elf_Cmd cmd, unsigned flags) {
+ if (!elf) {
+ return 0;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ return _elf_flag(&elf->e_ehdr_flags, cmd, flags);
+}
+
+unsigned
+elf_flagelf(Elf *elf, Elf_Cmd cmd, unsigned flags) {
+ if (!elf) {
+ return 0;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ return _elf_flag(&elf->e_elf_flags, cmd, flags);
+}
+
+unsigned
+elf_flagphdr(Elf *elf, Elf_Cmd cmd, unsigned flags) {
+ if (!elf) {
+ return 0;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ return _elf_flag(&elf->e_phdr_flags, cmd, flags);
+}
+
+unsigned
+elf_flagscn(Elf_Scn *scn, Elf_Cmd cmd, unsigned flags) {
+ if (!scn) {
+ return 0;
+ }
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ return _elf_flag(&scn->s_scn_flags, cmd, flags);
+}
+
+unsigned
+elf_flagshdr(Elf_Scn *scn, Elf_Cmd cmd, unsigned flags) {
+ if (!scn) {
+ return 0;
+ }
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ return _elf_flag(&scn->s_shdr_flags, cmd, flags);
+}
diff --git a/lib/gelf.h b/lib/gelf.h
new file mode 100644
index 0000000..5af0558
--- /dev/null
+++ b/lib/gelf.h
@@ -0,0 +1,155 @@
+/*
+ * gelf.h - public header file for libelf.
+ * Copyright (C) 2000 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* @(#) $Id: gelf.h,v 1.16 2008/05/23 08:15:34 michael Exp $ */
+
+#ifndef _GELF_H
+#define _GELF_H
+
+#if __LIBELF_INTERNAL__
+#include <libelf.h>
+#else /* __LIBELF_INTERNAL__ */
+#include <libelf/libelf.h>
+#endif /* __LIBELF_INTERNAL__ */
+
+#if __LIBELF_NEED_LINK_H
+#include <link.h>
+#elif __LIBELF_NEED_SYS_LINK_H
+#include <sys/link.h>
+#endif /* __LIBELF_NEED_LINK_H */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef __P
+# if (__STDC__ + 0) || defined(__cplusplus) || defined(_WIN32)
+# define __P(args) args
+# else /* __STDC__ || defined(__cplusplus) */
+# define __P(args) ()
+# endif /* __STDC__ || defined(__cplusplus) */
+#endif /* __P */
+
+#if !__LIBELF64
+
+#error "GElf is not supported on this system."
+
+#else /* __LIBELF64 */
+
+typedef Elf64_Addr GElf_Addr;
+typedef Elf64_Half GElf_Half;
+typedef Elf64_Off GElf_Off;
+typedef Elf64_Sword GElf_Sword;
+typedef Elf64_Word GElf_Word;
+typedef Elf64_Sxword GElf_Sxword;
+typedef Elf64_Xword GElf_Xword;
+
+typedef Elf64_Ehdr GElf_Ehdr;
+typedef Elf64_Phdr GElf_Phdr;
+typedef Elf64_Shdr GElf_Shdr;
+typedef Elf64_Dyn GElf_Dyn;
+typedef Elf64_Rel GElf_Rel;
+typedef Elf64_Rela GElf_Rela;
+typedef Elf64_Sym GElf_Sym;
+
+/*
+ * Symbol versioning
+ */
+#if __LIBELF_SYMBOL_VERSIONS
+typedef Elf64_Verdef GElf_Verdef;
+typedef Elf64_Verneed GElf_Verneed;
+typedef Elf64_Verdaux GElf_Verdaux;
+typedef Elf64_Vernaux GElf_Vernaux;
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+
+/*
+ * These types aren't implemented (yet)
+ *
+typedef Elf64_Move GElf_Move;
+typedef Elf64_Syminfo GElf_Syminfo;
+ */
+
+/*
+ * Generic macros
+ */
+#define GELF_ST_BIND ELF64_ST_BIND
+#define GELF_ST_TYPE ELF64_ST_TYPE
+#define GELF_ST_INFO ELF64_ST_INFO
+
+#define GELF_R_TYPE ELF64_R_TYPE
+#define GELF_R_SYM ELF64_R_SYM
+#define GELF_R_INFO ELF64_R_INFO
+
+/*
+ * Function declarations
+ */
+extern int gelf_getclass __P((Elf *__elf));
+
+extern size_t gelf_fsize __P((Elf *__elf, Elf_Type __type, size_t __count, unsigned __ver));
+
+extern Elf_Data *gelf_xlatetof __P((Elf *__elf, Elf_Data *__dst, const Elf_Data *__src, unsigned __encode));
+extern Elf_Data *gelf_xlatetom __P((Elf *__elf, Elf_Data *__dst, const Elf_Data *__src, unsigned __encode));
+
+extern GElf_Ehdr *gelf_getehdr __P((Elf *__elf, GElf_Ehdr *__dst));
+extern int gelf_update_ehdr __P((Elf *__elf, GElf_Ehdr *__src));
+extern unsigned long gelf_newehdr __P((Elf *__elf, int __elfclass));
+
+extern GElf_Phdr *gelf_getphdr __P((Elf *__elf, int ndx, GElf_Phdr *__dst));
+extern int gelf_update_phdr __P((Elf *__elf, int ndx, GElf_Phdr *__src));
+extern unsigned long gelf_newphdr __P((Elf *__elf, size_t __phnum));
+
+extern GElf_Shdr *gelf_getshdr __P((Elf_Scn *__scn, GElf_Shdr *__dst));
+extern int gelf_update_shdr __P((Elf_Scn *__scn, GElf_Shdr *__src));
+
+extern GElf_Dyn *gelf_getdyn __P((Elf_Data *__src, int __ndx, GElf_Dyn *__dst));
+extern int gelf_update_dyn __P((Elf_Data *__dst, int __ndx, GElf_Dyn *__src));
+
+extern GElf_Rel *gelf_getrel __P((Elf_Data *__src, int __ndx, GElf_Rel *__dst));
+extern int gelf_update_rel __P((Elf_Data *__dst, int __ndx, GElf_Rel *__src));
+
+extern GElf_Rela *gelf_getrela __P((Elf_Data *__src, int __ndx, GElf_Rela *__dst));
+extern int gelf_update_rela __P((Elf_Data *__dst, int __ndx, GElf_Rela *__src));
+
+extern GElf_Sym *gelf_getsym __P((Elf_Data *__src, int __ndx, GElf_Sym *__dst));
+extern int gelf_update_sym __P((Elf_Data *__dst, int __ndx, GElf_Sym *__src));
+
+extern long gelf_checksum __P((Elf *__elf));
+
+/*
+ * These functions aren't implemented (yet)
+ *
+extern GElf_Move *gelf_getmove __P((Elf_Data *__src, int __ndx, GElf_Move *__src));
+extern int gelf_update_move __P((Elf_Data *__dst, int __ndx, GElf_Move *__src));
+ *
+extern GElf_Syminfo* gelf_getsyminfo __P((Elf_Data *__src, int __ndx, GElf_Syminfo *__dst));
+extern int gelf_update_syminfo __P((Elf_Data *__dst, int __ndx, GElf_Syminfo *__src));
+ */
+
+/*
+ * Extensions (not available in other versions of libelf)
+ */
+extern size_t gelf_msize __P((Elf *__elf, Elf_Type __type, size_t __count, unsigned __ver));
+
+#endif /* __LIBELF64 */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _GELF_H */
diff --git a/lib/gelfehdr.c b/lib/gelfehdr.c
new file mode 100644
index 0000000..fa7c019
--- /dev/null
+++ b/lib/gelfehdr.c
@@ -0,0 +1,140 @@
+/*
+ * gelfehdr.c - gelf_* translation functions.
+ * Copyright (C) 2000 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#if __LIBELF64
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: gelfehdr.c,v 1.9 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+#define check_and_copy(type, d, s, name, eret) \
+ do { \
+ if (sizeof((d)->name) < sizeof((s)->name) \
+ && (type)(s)->name != (s)->name) { \
+ seterr(ERROR_BADVALUE); \
+ return (eret); \
+ } \
+ (d)->name = (type)(s)->name; \
+ } while (0)
+
+GElf_Ehdr*
+gelf_getehdr(Elf *elf, GElf_Ehdr *dst) {
+ GElf_Ehdr buf;
+ char *tmp;
+
+ if (!elf) {
+ return NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ tmp = _elf_getehdr(elf, elf->e_class);
+ if (!tmp) {
+ return NULL;
+ }
+ if (!dst) {
+ dst = &buf;
+ }
+ if (elf->e_class == ELFCLASS64) {
+ *dst = *(Elf64_Ehdr*)tmp;
+ }
+ else if (elf->e_class == ELFCLASS32) {
+ Elf32_Ehdr *src = (Elf32_Ehdr*)tmp;
+
+ memcpy(dst->e_ident, src->e_ident, EI_NIDENT);
+ check_and_copy(GElf_Half, dst, src, e_type, NULL);
+ check_and_copy(GElf_Half, dst, src, e_machine, NULL);
+ check_and_copy(GElf_Word, dst, src, e_version, NULL);
+ check_and_copy(GElf_Addr, dst, src, e_entry, NULL);
+ check_and_copy(GElf_Off, dst, src, e_phoff, NULL);
+ check_and_copy(GElf_Off, dst, src, e_shoff, NULL);
+ check_and_copy(GElf_Word, dst, src, e_flags, NULL);
+ check_and_copy(GElf_Half, dst, src, e_ehsize, NULL);
+ check_and_copy(GElf_Half, dst, src, e_phentsize, NULL);
+ check_and_copy(GElf_Half, dst, src, e_phnum, NULL);
+ check_and_copy(GElf_Half, dst, src, e_shentsize, NULL);
+ check_and_copy(GElf_Half, dst, src, e_shnum, NULL);
+ check_and_copy(GElf_Half, dst, src, e_shstrndx, NULL);
+ }
+ else {
+ if (valid_class(elf->e_class)) {
+ seterr(ERROR_UNIMPLEMENTED);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ return NULL;
+ }
+ if (dst == &buf) {
+ dst = (GElf_Ehdr*)malloc(sizeof(GElf_Ehdr));
+ if (!dst) {
+ seterr(ERROR_MEM_EHDR);
+ return NULL;
+ }
+ *dst = buf;
+ }
+ return dst;
+}
+
+int
+gelf_update_ehdr(Elf *elf, GElf_Ehdr *src) {
+ char *tmp;
+
+ if (!elf || !src) {
+ return 0;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ tmp = _elf_getehdr(elf, elf->e_class);
+ if (!tmp) {
+ return 0;
+ }
+ if (elf->e_class == ELFCLASS64) {
+ *(Elf64_Ehdr*)tmp = *src;
+ }
+ else if (elf->e_class == ELFCLASS32) {
+ Elf32_Ehdr *dst = (Elf32_Ehdr*)tmp;
+
+ memcpy(dst->e_ident, src->e_ident, EI_NIDENT);
+ check_and_copy(Elf32_Half, dst, src, e_type, 0);
+ check_and_copy(Elf32_Half, dst, src, e_machine, 0);
+ check_and_copy(Elf32_Word, dst, src, e_version, 0);
+ check_and_copy(Elf32_Addr, dst, src, e_entry, 0);
+ check_and_copy(Elf32_Off, dst, src, e_phoff, 0);
+ check_and_copy(Elf32_Off, dst, src, e_shoff, 0);
+ check_and_copy(Elf32_Word, dst, src, e_flags, 0);
+ check_and_copy(Elf32_Half, dst, src, e_ehsize, 0);
+ check_and_copy(Elf32_Half, dst, src, e_phentsize, 0);
+ check_and_copy(Elf32_Half, dst, src, e_phnum, 0);
+ check_and_copy(Elf32_Half, dst, src, e_shentsize, 0);
+ check_and_copy(Elf32_Half, dst, src, e_shnum, 0);
+ check_and_copy(Elf32_Half, dst, src, e_shstrndx, 0);
+ }
+ else {
+ if (valid_class(elf->e_class)) {
+ seterr(ERROR_UNIMPLEMENTED);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ return 0;
+ }
+ return 1;
+}
+
+#endif /* __LIBELF64 */
diff --git a/lib/gelfphdr.c b/lib/gelfphdr.c
new file mode 100644
index 0000000..2635b4a
--- /dev/null
+++ b/lib/gelfphdr.c
@@ -0,0 +1,148 @@
+/*
+ * gelfphdr.c - gelf_* translation functions.
+ * Copyright (C) 2000 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#if __LIBELF64
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: gelfphdr.c,v 1.9 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+#define check_and_copy(type, d, s, name, eret) \
+ do { \
+ if (sizeof((d)->name) < sizeof((s)->name) \
+ && (type)(s)->name != (s)->name) { \
+ seterr(ERROR_BADVALUE); \
+ return (eret); \
+ } \
+ (d)->name = (type)(s)->name; \
+ } while (0)
+
+GElf_Phdr*
+gelf_getphdr(Elf *elf, int ndx, GElf_Phdr *dst) {
+ GElf_Phdr buf;
+ char *tmp;
+ size_t n;
+
+ if (!elf) {
+ return NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ tmp = _elf_getphdr(elf, elf->e_class);
+ if (!tmp) {
+ return NULL;
+ }
+ if (ndx < 0 || ndx >= elf->e_phnum) {
+ seterr(ERROR_BADINDEX);
+ return NULL;
+ }
+ n = _msize(elf->e_class, _elf_version, ELF_T_PHDR);
+ if (n == 0) {
+ seterr(ERROR_UNIMPLEMENTED);
+ return NULL;
+ }
+ if (!dst) {
+ dst = &buf;
+ }
+ if (elf->e_class == ELFCLASS64) {
+ *dst = *(Elf64_Phdr*)(tmp + ndx * n);
+ }
+ else if (elf->e_class == ELFCLASS32) {
+ Elf32_Phdr *src = (Elf32_Phdr*)(tmp + ndx * n);
+
+ check_and_copy(GElf_Word, dst, src, p_type, NULL);
+ check_and_copy(GElf_Word, dst, src, p_flags, NULL);
+ check_and_copy(GElf_Off, dst, src, p_offset, NULL);
+ check_and_copy(GElf_Addr, dst, src, p_vaddr, NULL);
+ check_and_copy(GElf_Addr, dst, src, p_paddr, NULL);
+ check_and_copy(GElf_Xword, dst, src, p_filesz, NULL);
+ check_and_copy(GElf_Xword, dst, src, p_memsz, NULL);
+ check_and_copy(GElf_Xword, dst, src, p_align, NULL);
+ }
+ else {
+ if (valid_class(elf->e_class)) {
+ seterr(ERROR_UNIMPLEMENTED);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ return NULL;
+ }
+ if (dst == &buf) {
+ dst = (GElf_Phdr*)malloc(sizeof(GElf_Phdr));
+ if (!dst) {
+ seterr(ERROR_MEM_PHDR);
+ return NULL;
+ }
+ *dst = buf;
+ }
+ return dst;
+}
+
+int
+gelf_update_phdr(Elf *elf, int ndx, GElf_Phdr *src) {
+ char *tmp;
+ size_t n;
+
+ if (!elf || !src) {
+ return 0;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ tmp = _elf_getphdr(elf, elf->e_class);
+ if (!tmp) {
+ return 0;
+ }
+ if (ndx < 0 || ndx >= elf->e_phnum) {
+ seterr(ERROR_BADINDEX);
+ return 0;
+ }
+ n = _msize(elf->e_class, _elf_version, ELF_T_PHDR);
+ if (n == 0) {
+ seterr(ERROR_UNIMPLEMENTED);
+ return 0;
+ }
+ if (elf->e_class == ELFCLASS64) {
+ *(Elf64_Phdr*)(tmp + ndx * n) = *src;
+ }
+ else if (elf->e_class == ELFCLASS32) {
+ Elf32_Phdr *dst = (Elf32_Phdr*)(tmp + ndx * n);
+
+ check_and_copy(Elf32_Word, dst, src, p_type, 0);
+ check_and_copy(Elf32_Off, dst, src, p_offset, 0);
+ check_and_copy(Elf32_Addr, dst, src, p_vaddr, 0);
+ check_and_copy(Elf32_Addr, dst, src, p_paddr, 0);
+ check_and_copy(Elf32_Word, dst, src, p_filesz, 0);
+ check_and_copy(Elf32_Word, dst, src, p_memsz, 0);
+ check_and_copy(Elf32_Word, dst, src, p_flags, 0);
+ check_and_copy(Elf32_Word, dst, src, p_align, 0);
+ }
+ else {
+ if (valid_class(elf->e_class)) {
+ seterr(ERROR_UNIMPLEMENTED);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ return 0;
+ }
+ return 1;
+}
+
+#endif /* __LIBELF64 */
diff --git a/lib/gelfshdr.c b/lib/gelfshdr.c
new file mode 100644
index 0000000..c295c18
--- /dev/null
+++ b/lib/gelfshdr.c
@@ -0,0 +1,125 @@
+/*
+ * gelfshdr.c - gelf_* translation functions.
+ * Copyright (C) 2000 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#if __LIBELF64
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: gelfshdr.c,v 1.10 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+#define check_and_copy(type, d, s, name, eret) \
+ do { \
+ if (sizeof((d)->name) < sizeof((s)->name) \
+ && (type)(s)->name != (s)->name) { \
+ seterr(ERROR_BADVALUE); \
+ return (eret); \
+ } \
+ (d)->name = (type)(s)->name; \
+ } while (0)
+
+GElf_Shdr*
+gelf_getshdr(Elf_Scn *scn, GElf_Shdr *dst) {
+ GElf_Shdr buf;
+
+ if (!scn) {
+ return NULL;
+ }
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ elf_assert(scn->s_elf);
+ elf_assert(scn->s_elf->e_magic == ELF_MAGIC);
+ if (!dst) {
+ dst = &buf;
+ }
+ if (scn->s_elf->e_class == ELFCLASS64) {
+ *dst = scn->s_shdr64;
+ }
+ else if (scn->s_elf->e_class == ELFCLASS32) {
+ Elf32_Shdr *src = &scn->s_shdr32;
+
+ check_and_copy(GElf_Word, dst, src, sh_name, NULL);
+ check_and_copy(GElf_Word, dst, src, sh_type, NULL);
+ check_and_copy(GElf_Xword, dst, src, sh_flags, NULL);
+ check_and_copy(GElf_Addr, dst, src, sh_addr, NULL);
+ check_and_copy(GElf_Off, dst, src, sh_offset, NULL);
+ check_and_copy(GElf_Xword, dst, src, sh_size, NULL);
+ check_and_copy(GElf_Word, dst, src, sh_link, NULL);
+ check_and_copy(GElf_Word, dst, src, sh_info, NULL);
+ check_and_copy(GElf_Xword, dst, src, sh_addralign, NULL);
+ check_and_copy(GElf_Xword, dst, src, sh_entsize, NULL);
+ }
+ else {
+ if (valid_class(scn->s_elf->e_class)) {
+ seterr(ERROR_UNIMPLEMENTED);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ return NULL;
+ }
+ if (dst == &buf) {
+ dst = (GElf_Shdr*)malloc(sizeof(GElf_Shdr));
+ if (!dst) {
+ seterr(ERROR_MEM_SHDR);
+ return NULL;
+ }
+ *dst = buf;
+ }
+ return dst;
+}
+
+int
+gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *src) {
+ if (!scn || !src) {
+ return 0;
+ }
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ elf_assert(scn->s_elf);
+ elf_assert(scn->s_elf->e_magic == ELF_MAGIC);
+ if (scn->s_elf->e_class == ELFCLASS64) {
+ scn->s_shdr64 = *src;
+ }
+ else if (scn->s_elf->e_class == ELFCLASS32) {
+ Elf32_Shdr *dst = &scn->s_shdr32;
+
+ check_and_copy(Elf32_Word, dst, src, sh_name, 0);
+ check_and_copy(Elf32_Word, dst, src, sh_type, 0);
+ check_and_copy(Elf32_Word, dst, src, sh_flags, 0);
+ check_and_copy(Elf32_Addr, dst, src, sh_addr, 0);
+ check_and_copy(Elf32_Off, dst, src, sh_offset, 0);
+ check_and_copy(Elf32_Word, dst, src, sh_size, 0);
+ check_and_copy(Elf32_Word, dst, src, sh_link, 0);
+ check_and_copy(Elf32_Word, dst, src, sh_info, 0);
+ check_and_copy(Elf32_Word, dst, src, sh_addralign, 0);
+ check_and_copy(Elf32_Word, dst, src, sh_entsize, 0);
+ }
+ else {
+ if (valid_class(scn->s_elf->e_class)) {
+ seterr(ERROR_UNIMPLEMENTED);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ return 0;
+ }
+ return 1;
+}
+
+#endif /* __LIBELF64 */
diff --git a/lib/gelftrans.c b/lib/gelftrans.c
new file mode 100644
index 0000000..dcd0cdd
--- /dev/null
+++ b/lib/gelftrans.c
@@ -0,0 +1,407 @@
+/*
+gelftrans.c - gelf_* translation functions.
+Copyright (C) 2000 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#if __LIBELF64
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: gelftrans.c,v 1.10 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+#define check_and_copy(type, d, s, name, eret) \
+ do { \
+ if (sizeof((d)->name) < sizeof((s)->name) \
+ && (type)(s)->name != (s)->name) { \
+ seterr(ERROR_BADVALUE); \
+ return (eret); \
+ } \
+ (d)->name = (type)(s)->name; \
+ } while (0)
+
+/*
+ * These macros are missing on some Linux systems
+ */
+#if !defined(ELF32_R_SYM) || !defined(ELF32_R_TYPE) || !defined(ELF32_R_INFO)
+# undef ELF32_R_SYM
+# undef ELF32_R_TYPE
+# undef ELF32_R_INFO
+# define ELF32_R_SYM(i) ((i)>>8)
+# define ELF32_R_TYPE(i) ((unsigned char)(i))
+# define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t))
+#endif /* !defined(...) */
+
+#if !defined(ELF64_R_SYM) || !defined(ELF64_R_TYPE) || !defined(ELF64_R_INFO)
+# undef ELF64_R_SYM
+# undef ELF64_R_TYPE
+# undef ELF64_R_INFO
+# define ELF64_R_SYM(i) ((i)>>32)
+# define ELF64_R_TYPE(i) ((i)&0xffffffffL)
+# define ELF64_R_INFO(s,t) (((Elf64_Xword)(s)<<32)+((t)&0xffffffffL))
+#endif /* !defined(...) */
+
+static char*
+get_addr_and_class(const Elf_Data *data, int ndx, Elf_Type type, unsigned *cls) {
+ Scn_Data *sd = (Scn_Data*)data;
+ Elf_Scn *scn;
+ Elf *elf;
+ size_t n;
+
+ if (!sd) {
+ return NULL;
+ }
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ scn = sd->sd_scn;
+ elf_assert(scn);
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ elf = scn->s_elf;
+ elf_assert(elf);
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ return NULL;
+ }
+ if (!valid_class(elf->e_class)) {
+ seterr(ERROR_UNKNOWN_CLASS);
+ return NULL;
+ }
+ if (data->d_type != type) {
+ seterr(ERROR_BADTYPE);
+ return NULL;
+ }
+ n = _msize(elf->e_class, data->d_version, type);
+ if (n == 0) {
+ seterr(ERROR_UNIMPLEMENTED);
+ return NULL;
+ }
+ if (ndx < 0 || data->d_size < (ndx + 1) * n) {
+ seterr(ERROR_BADINDEX);
+ return NULL;
+ }
+ if (!data->d_buf) {
+ seterr(ERROR_NULLBUF);
+ return NULL;
+ }
+ if (cls) {
+ *cls = elf->e_class;
+ }
+ return (char*)data->d_buf + n * ndx;
+}
+
+GElf_Sym*
+gelf_getsym(Elf_Data *src, int ndx, GElf_Sym *dst) {
+ GElf_Sym buf;
+ unsigned cls;
+ char *tmp;
+
+ if (!dst) {
+ dst = &buf;
+ }
+ tmp = get_addr_and_class(src, ndx, ELF_T_SYM, &cls);
+ if (!tmp) {
+ return NULL;
+ }
+ if (cls == ELFCLASS64) {
+ *dst = *(Elf64_Sym*)tmp;
+ }
+ else if (cls == ELFCLASS32) {
+ Elf32_Sym *src = (Elf32_Sym*)tmp;
+
+ check_and_copy(GElf_Word, dst, src, st_name, NULL);
+ check_and_copy(unsigned char, dst, src, st_info, NULL);
+ check_and_copy(unsigned char, dst, src, st_other, NULL);
+ check_and_copy(GElf_Half, dst, src, st_shndx, NULL);
+ check_and_copy(GElf_Addr, dst, src, st_value, NULL);
+ check_and_copy(GElf_Xword, dst, src, st_size, NULL);
+ }
+ else {
+ seterr(ERROR_UNIMPLEMENTED);
+ return NULL;
+ }
+ if (dst == &buf) {
+ dst = (GElf_Sym*)malloc(sizeof(GElf_Sym));
+ if (!dst) {
+ seterr(ERROR_MEM_SYM);
+ return NULL;
+ }
+ *dst = buf;
+ }
+ return dst;
+}
+
+int
+gelf_update_sym(Elf_Data *dst, int ndx, GElf_Sym *src) {
+ unsigned cls;
+ char *tmp;
+
+ tmp = get_addr_and_class(dst, ndx, ELF_T_SYM, &cls);
+ if (!tmp) {
+ return 0;
+ }
+ if (cls == ELFCLASS64) {
+ *(Elf64_Sym*)tmp = *src;
+ }
+ else if (cls == ELFCLASS32) {
+ Elf32_Sym *dst = (Elf32_Sym*)tmp;
+
+ check_and_copy(Elf32_Word, dst, src, st_name, 0);
+ check_and_copy(Elf32_Addr, dst, src, st_value, 0);
+ check_and_copy(Elf32_Word, dst, src, st_size, 0);
+ check_and_copy(unsigned char, dst, src, st_info, 0);
+ check_and_copy(unsigned char, dst, src, st_other, 0);
+ check_and_copy(Elf32_Half, dst, src, st_shndx, 0);
+ }
+ else {
+ seterr(ERROR_UNIMPLEMENTED);
+ return 0;
+ }
+ return 1;
+}
+
+GElf_Dyn*
+gelf_getdyn(Elf_Data *src, int ndx, GElf_Dyn *dst) {
+ GElf_Dyn buf;
+ unsigned cls;
+ char *tmp;
+
+ if (!dst) {
+ dst = &buf;
+ }
+ tmp = get_addr_and_class(src, ndx, ELF_T_DYN, &cls);
+ if (!tmp) {
+ return NULL;
+ }
+ if (cls == ELFCLASS64) {
+ *dst = *(Elf64_Dyn*)tmp;
+ }
+ else if (cls == ELFCLASS32) {
+ Elf32_Dyn *src = (Elf32_Dyn*)tmp;
+
+ check_and_copy(GElf_Sxword, dst, src, d_tag, NULL);
+ check_and_copy(GElf_Xword, dst, src, d_un.d_val, NULL);
+ }
+ else {
+ seterr(ERROR_UNIMPLEMENTED);
+ return NULL;
+ }
+ if (dst == &buf) {
+ dst = (GElf_Dyn*)malloc(sizeof(GElf_Dyn));
+ if (!dst) {
+ seterr(ERROR_MEM_DYN);
+ return NULL;
+ }
+ *dst = buf;
+ }
+ return dst;
+}
+
+int
+gelf_update_dyn(Elf_Data *dst, int ndx, GElf_Dyn *src) {
+ unsigned cls;
+ char *tmp;
+
+ tmp = get_addr_and_class(dst, ndx, ELF_T_DYN, &cls);
+ if (!tmp) {
+ return 0;
+ }
+ if (cls == ELFCLASS64) {
+ *(Elf64_Dyn*)tmp = *src;
+ }
+ else if (cls == ELFCLASS32) {
+ Elf32_Dyn *dst = (Elf32_Dyn*)tmp;
+
+ check_and_copy(Elf32_Sword, dst, src, d_tag, 0);
+ check_and_copy(Elf32_Word, dst, src, d_un.d_val, 0);
+ }
+ else {
+ seterr(ERROR_UNIMPLEMENTED);
+ return 0;
+ }
+ return 1;
+}
+
+GElf_Rela*
+gelf_getrela(Elf_Data *src, int ndx, GElf_Rela *dst) {
+ GElf_Rela buf;
+ unsigned cls;
+ char *tmp;
+
+ if (!dst) {
+ dst = &buf;
+ }
+ tmp = get_addr_and_class(src, ndx, ELF_T_RELA, &cls);
+ if (!tmp) {
+ return NULL;
+ }
+ if (cls == ELFCLASS64) {
+ *dst = *(Elf64_Rela*)tmp;
+ }
+ else if (cls == ELFCLASS32) {
+ Elf32_Rela *src = (Elf32_Rela*)tmp;
+
+ check_and_copy(GElf_Addr, dst, src, r_offset, NULL);
+ dst->r_info = ELF64_R_INFO((Elf64_Xword)ELF32_R_SYM(src->r_info),
+ (Elf64_Xword)ELF32_R_TYPE(src->r_info));
+ check_and_copy(GElf_Sxword, dst, src, r_addend, NULL);
+ }
+ else {
+ seterr(ERROR_UNIMPLEMENTED);
+ return NULL;
+ }
+ if (dst == &buf) {
+ dst = (GElf_Rela*)malloc(sizeof(GElf_Rela));
+ if (!dst) {
+ seterr(ERROR_MEM_RELA);
+ return NULL;
+ }
+ *dst = buf;
+ }
+ return dst;
+}
+
+int
+gelf_update_rela(Elf_Data *dst, int ndx, GElf_Rela *src) {
+ unsigned cls;
+ char *tmp;
+
+ tmp = get_addr_and_class(dst, ndx, ELF_T_RELA, &cls);
+ if (!tmp) {
+ return 0;
+ }
+ if (cls == ELFCLASS64) {
+ *(Elf64_Rela*)tmp = *src;
+ }
+ else if (cls == ELFCLASS32) {
+ Elf32_Rela *dst = (Elf32_Rela*)tmp;
+
+ check_and_copy(Elf32_Addr, dst, src, r_offset, 0);
+ if (ELF64_R_SYM(src->r_info) > 0xffffffUL
+ || ELF64_R_TYPE(src->r_info) > 0xffUL) {
+ seterr(ERROR_BADVALUE);
+ return 0;
+ }
+ dst->r_info = ELF32_R_INFO((Elf32_Word)ELF64_R_SYM(src->r_info),
+ (Elf32_Word)ELF64_R_TYPE(src->r_info));
+ check_and_copy(Elf32_Sword, dst, src, r_addend, 0);
+ }
+ else {
+ seterr(ERROR_UNIMPLEMENTED);
+ return 0;
+ }
+ return 1;
+}
+
+GElf_Rel*
+gelf_getrel(Elf_Data *src, int ndx, GElf_Rel *dst) {
+ GElf_Rel buf;
+ unsigned cls;
+ char *tmp;
+
+ if (!dst) {
+ dst = &buf;
+ }
+ tmp = get_addr_and_class(src, ndx, ELF_T_REL, &cls);
+ if (!tmp) {
+ return NULL;
+ }
+ if (cls == ELFCLASS64) {
+ *dst = *(Elf64_Rel*)tmp;
+ }
+ else if (cls == ELFCLASS32) {
+ Elf32_Rel *src = (Elf32_Rel*)tmp;
+
+ check_and_copy(GElf_Addr, dst, src, r_offset, NULL);
+ dst->r_info = ELF64_R_INFO((Elf64_Xword)ELF32_R_SYM(src->r_info),
+ (Elf64_Xword)ELF32_R_TYPE(src->r_info));
+ }
+ else {
+ seterr(ERROR_UNIMPLEMENTED);
+ return NULL;
+ }
+ if (dst == &buf) {
+ dst = (GElf_Rel*)malloc(sizeof(GElf_Rel));
+ if (!dst) {
+ seterr(ERROR_MEM_REL);
+ return NULL;
+ }
+ *dst = buf;
+ }
+ return dst;
+}
+
+int
+gelf_update_rel(Elf_Data *dst, int ndx, GElf_Rel *src) {
+ unsigned cls;
+ char *tmp;
+
+ tmp = get_addr_and_class(dst, ndx, ELF_T_REL, &cls);
+ if (!tmp) {
+ return 0;
+ }
+ if (cls == ELFCLASS64) {
+ *(Elf64_Rel*)tmp = *src;
+ }
+ else if (cls == ELFCLASS32) {
+ Elf32_Rel *dst = (Elf32_Rel*)tmp;
+
+ check_and_copy(Elf32_Addr, dst, src, r_offset, 0);
+ if (ELF64_R_SYM(src->r_info) > 0xffffffUL
+ || ELF64_R_TYPE(src->r_info) > 0xffUL) {
+ seterr(ERROR_BADVALUE);
+ return 0;
+ }
+ dst->r_info = ELF32_R_INFO((Elf32_Word)ELF64_R_SYM(src->r_info),
+ (Elf32_Word)ELF64_R_TYPE(src->r_info));
+ }
+ else {
+ seterr(ERROR_UNIMPLEMENTED);
+ return 0;
+ }
+ return 1;
+}
+
+#if 0
+
+GElf_Syminfo*
+gelf_getsyminfo(Elf_Data *src, int ndx, GElf_Syminfo *dst) {
+ seterr(ERROR_UNIMPLEMENTED);
+ return NULL;
+}
+
+int
+gelf_update_syminfo(Elf_Data *dst, int ndx, GElf_Syminfo *src) {
+ seterr(ERROR_UNIMPLEMENTED);
+ return 0;
+}
+
+GElf_Move*
+gelf_getmove(Elf_Data *src, int ndx, GElf_Move *src) {
+ seterr(ERROR_UNIMPLEMENTED);
+ return NULL;
+}
+
+int
+gelf_update_move(Elf_Data *dst, int ndx, GElf_Move *src) {
+ seterr(ERROR_UNIMPLEMENTED);
+ return 0;
+}
+
+#endif
+
+#endif /* __LIBELF64 */
diff --git a/lib/getarhdr.c b/lib/getarhdr.c
new file mode 100644
index 0000000..874b337
--- /dev/null
+++ b/lib/getarhdr.c
@@ -0,0 +1,37 @@
+/*
+getarhdr.c - implementation of the elf_getarhdr(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: getarhdr.c,v 1.7 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+Elf_Arhdr*
+elf_getarhdr(Elf *elf) {
+ if (!elf) {
+ return NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (elf->e_arhdr) {
+ return elf->e_arhdr;
+ }
+ seterr(ERROR_NOTARCHIVE);
+ return NULL;
+}
diff --git a/lib/getaroff.c b/lib/getaroff.c
new file mode 100644
index 0000000..fce977d
--- /dev/null
+++ b/lib/getaroff.c
@@ -0,0 +1,40 @@
+/*
+ * getaroff.c - implementation of the elf_getaroff(3) function.
+ * Copyright (C) 2009 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: getaroff.c,v 1.1 2009/11/01 13:04:19 michael Exp $";
+#endif /* lint */
+
+off_t
+elf_getaroff(Elf *elf) {
+ Elf *ref;
+
+ if (!elf) {
+ return (off_t)-1;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (!(ref = elf->e_parent)) {
+ return (off_t)-1;
+ }
+ elf_assert(ref->e_magic == ELF_MAGIC);
+ elf_assert(elf->e_base >= ref->e_base + SARMAG + sizeof(struct ar_hdr));
+ return (off_t)(elf->e_base - ref->e_base - sizeof(struct ar_hdr));
+}
diff --git a/lib/getarsym.c b/lib/getarsym.c
new file mode 100644
index 0000000..6069676
--- /dev/null
+++ b/lib/getarsym.c
@@ -0,0 +1,87 @@
+/*
+ * getarsym.c - implementation of the elf_getarsym(3) function.
+ * Copyright (C) 1995 - 1998, 2004 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+#include <byteswap.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: getarsym.c,v 1.9 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+Elf_Arsym*
+elf_getarsym(Elf *elf, size_t *ptr) {
+ Elf_Arsym *syms;
+ size_t count;
+ size_t tmp;
+ size_t i;
+ char *s;
+ char *e;
+
+ if (!ptr) {
+ ptr = &tmp;
+ }
+ *ptr = 0;
+ if (!elf) {
+ return NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (elf->e_kind != ELF_K_AR) {
+ seterr(ERROR_NOTARCHIVE);
+ return NULL;
+ }
+ if (elf->e_symtab && !elf->e_free_syms) {
+ if (elf->e_symlen < 4) {
+ seterr(ERROR_SIZE_ARSYMTAB);
+ return NULL;
+ }
+ count = __load_u32M(elf->e_symtab);
+ if (elf->e_symlen < 4 * (count + 1)) {
+ seterr(ERROR_SIZE_ARSYMTAB);
+ return NULL;
+ }
+ if (!(syms = (Elf_Arsym*)malloc((count + 1) * sizeof(*syms)))) {
+ seterr(ERROR_MEM_ARSYMTAB);
+ return NULL;
+ }
+ s = elf->e_symtab + 4 * (count + 1);
+ e = elf->e_symtab + elf->e_symlen;
+ for (i = 0; i < count; i++, s++) {
+ syms[i].as_name = s;
+ while (s < e && *s) {
+ s++;
+ }
+ if (s >= e) {
+ seterr(ERROR_SIZE_ARSYMTAB);
+ free(syms);
+ return NULL;
+ }
+ elf_assert(!*s);
+ syms[i].as_hash = elf_hash((unsigned char*)syms[i].as_name);
+ syms[i].as_off = __load_u32M(elf->e_symtab + 4 * (i + 1));
+ }
+ syms[count].as_name = NULL;
+ syms[count].as_hash = ~0UL;
+ syms[count].as_off = 0;
+ elf->e_symtab = (char*)syms;
+ elf->e_symlen = count + 1;
+ elf->e_free_syms = 1;
+ }
+ *ptr = elf->e_symlen;
+ return (Elf_Arsym*)elf->e_symtab;
+}
diff --git a/lib/getbase.c b/lib/getbase.c
new file mode 100644
index 0000000..6831629
--- /dev/null
+++ b/lib/getbase.c
@@ -0,0 +1,33 @@
+/*
+getbase.c - implementation of the elf_getbase(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: getbase.c,v 1.7 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+off_t
+elf_getbase(Elf *elf) {
+ if (!elf) {
+ return -1;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ return (off_t)elf->e_base;
+}
diff --git a/lib/getdata.c b/lib/getdata.c
new file mode 100644
index 0000000..a65b7aa
--- /dev/null
+++ b/lib/getdata.c
@@ -0,0 +1,157 @@
+/*
+getdata.c - implementation of the elf_getdata(3) function.
+Copyright (C) 1995 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: getdata.c,v 1.13 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+static Elf_Data*
+_elf_cook_scn(Elf *elf, Elf_Scn *scn, Scn_Data *sd) {
+ Elf_Data dst;
+ Elf_Data src;
+ int flag = 0;
+ size_t dlen;
+
+ elf_assert(elf->e_data);
+
+ /*
+ * Prepare source
+ */
+ src = sd->sd_data;
+ src.d_version = elf->e_version;
+ if (elf->e_rawdata) {
+ src.d_buf = elf->e_rawdata + scn->s_offset;
+ }
+ else {
+ src.d_buf = elf->e_data + scn->s_offset;
+ }
+
+ /*
+ * Prepare destination (needs prepared source!)
+ */
+ dst = sd->sd_data;
+ if (elf->e_class == ELFCLASS32) {
+ dlen = _elf32_xltsize(&src, dst.d_version, elf->e_encoding, 0);
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ dlen = _elf64_xltsize(&src, dst.d_version, elf->e_encoding, 0);
+ }
+#endif /* __LIBELF64 */
+ else {
+ elf_assert(valid_class(elf->e_class));
+ seterr(ERROR_UNIMPLEMENTED);
+ return NULL;
+ }
+ if (dlen == (size_t)-1) {
+ return NULL;
+ }
+ dst.d_size = dlen;
+ if (elf->e_rawdata != elf->e_data && dst.d_size <= src.d_size) {
+ dst.d_buf = elf->e_data + scn->s_offset;
+ }
+ else if (!(dst.d_buf = malloc(dst.d_size))) {
+ seterr(ERROR_MEM_SCNDATA);
+ return NULL;
+ }
+ else {
+ flag = 1;
+ }
+
+ /*
+ * Translate data
+ */
+ if (_elf_xlatetom(elf, &dst, &src)) {
+ sd->sd_memdata = (char*)dst.d_buf;
+ sd->sd_data = dst;
+ if (!(sd->sd_free_data = flag)) {
+ elf->e_cooked = 1;
+ }
+ return &sd->sd_data;
+ }
+
+ if (flag) {
+ free(dst.d_buf);
+ }
+ return NULL;
+}
+
+Elf_Data*
+elf_getdata(Elf_Scn *scn, Elf_Data *data) {
+ Scn_Data *sd;
+ Elf *elf;
+
+ if (!scn) {
+ return NULL;
+ }
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ if (scn->s_index == SHN_UNDEF) {
+ seterr(ERROR_NULLSCN);
+ }
+ else if (data) {
+ for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ elf_assert(sd->sd_scn == scn);
+ if (data == &sd->sd_data) {
+ /*
+ * sd_link allocated by elf_newdata().
+ */
+ return &sd->sd_link->sd_data;
+ }
+ }
+ seterr(ERROR_SCNDATAMISMATCH);
+ }
+ else if ((sd = scn->s_data_1)) {
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ elf_assert(sd->sd_scn == scn);
+ elf = scn->s_elf;
+ elf_assert(elf);
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (sd->sd_freeme) {
+ /* allocated by elf_newdata() */
+ return &sd->sd_data;
+ }
+ else if (scn->s_type == SHT_NULL) {
+ seterr(ERROR_NULLSCN);
+ }
+ else if (sd->sd_memdata) {
+ /* already cooked */
+ return &sd->sd_data;
+ }
+ else if (scn->s_offset < 0 || scn->s_offset > elf->e_size) {
+ seterr(ERROR_OUTSIDE);
+ }
+ else if (scn->s_type == SHT_NOBITS || !scn->s_size) {
+ /* no data to read */
+ return &sd->sd_data;
+ }
+ else if (scn->s_offset + scn->s_size > elf->e_size) {
+ seterr(ERROR_TRUNC_SCN);
+ }
+ else if (valid_class(elf->e_class)) {
+ return _elf_cook_scn(elf, scn, sd);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ }
+ return NULL;
+}
diff --git a/lib/getident.c b/lib/getident.c
new file mode 100644
index 0000000..d9758f4
--- /dev/null
+++ b/lib/getident.c
@@ -0,0 +1,48 @@
+/*
+getident.c - implementation of the elf_getident(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: getident.c,v 1.7 2008/05/23 08:15:34 michael Exp $";
+#endif /* lint */
+
+char*
+elf_getident(Elf *elf, size_t *ptr) {
+ size_t tmp;
+
+ if (!ptr) {
+ ptr = &tmp;
+ }
+ if (!elf) {
+ *ptr = 0;
+ return NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (elf->e_kind != ELF_K_ELF) {
+ *ptr = elf->e_idlen;
+ return elf->e_data;
+ }
+ if (elf->e_ehdr || _elf_cook(elf)) {
+ *ptr = elf->e_idlen;
+ return elf->e_ehdr;
+ }
+ *ptr = 0;
+ return NULL;
+}
diff --git a/lib/getscn.c b/lib/getscn.c
new file mode 100644
index 0000000..a78eae9
--- /dev/null
+++ b/lib/getscn.c
@@ -0,0 +1,48 @@
+/*
+getscn.c - implementation of the elf_getscn(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: getscn.c,v 1.7 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+Elf_Scn*
+elf_getscn(Elf *elf, size_t index) {
+ Elf_Scn *scn;
+
+ if (!elf) {
+ return NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ }
+ else if (elf->e_ehdr || _elf_cook(elf)) {
+ for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ elf_assert(scn->s_elf == elf);
+ if (scn->s_index == index) {
+ return scn;
+ }
+ }
+ seterr(ERROR_NOSUCHSCN);
+ }
+ return NULL;
+}
diff --git a/lib/hash.c b/lib/hash.c
new file mode 100644
index 0000000..a2555b6
--- /dev/null
+++ b/lib/hash.c
@@ -0,0 +1,38 @@
+/*
+hash.c - implementation of the elf_hash(3) function.
+Copyright (C) 1995 - 2002 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: hash.c,v 1.10 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+unsigned long
+elf_hash(const unsigned char *name) {
+ unsigned long hash = 0;
+ unsigned long tmp;
+
+ while (*name) {
+ hash = (hash << 4) + (unsigned char)*name++;
+ if ((tmp = hash & 0xf0000000)) {
+ hash ^= tmp | (tmp >> 24);
+ }
+ }
+ return hash;
+}
diff --git a/lib/input.c b/lib/input.c
new file mode 100644
index 0000000..751970a
--- /dev/null
+++ b/lib/input.c
@@ -0,0 +1,106 @@
+/*
+ * input.c - low-level input for libelf.
+ * Copyright (C) 1995 - 2001, 2005 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: input.c,v 1.11 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+#include <errno.h>
+
+#if HAVE_MMAP
+#include <sys/mman.h>
+#endif /* HAVE_MMAP */
+
+static int
+xread(int fd, char *buffer, size_t len) {
+ size_t done = 0;
+ size_t n;
+
+ while (done < len) {
+ n = read(fd, buffer + done, len - done);
+ if (n == 0) {
+ /* premature end of file */
+ return -1;
+ }
+ else if (n != (size_t)-1) {
+ /* some bytes read, continue */
+ done += n;
+ }
+ else if (errno != EAGAIN && errno != EINTR) {
+ /* real error */
+ return -1;
+ }
+ }
+ return 0;
+}
+
+void*
+_elf_read(Elf *elf, void *buffer, size_t off, size_t len) {
+ void *tmp;
+
+ elf_assert(elf);
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ elf_assert(off >= 0 && off + len <= elf->e_size);
+ if (elf->e_disabled) {
+ seterr(ERROR_FDDISABLED);
+ }
+ else if (len) {
+ off += elf->e_base;
+ if (lseek(elf->e_fd, (off_t)off, SEEK_SET) != (off_t)off) {
+ seterr(ERROR_IO_SEEK);
+ }
+ else if (!(tmp = buffer) && !(tmp = malloc(len))) {
+ seterr(ERROR_IO_2BIG);
+ }
+ else if (xread(elf->e_fd, tmp, len)) {
+ seterr(ERROR_IO_READ);
+ if (tmp != buffer) {
+ free(tmp);
+ }
+ }
+ else {
+ return tmp;
+ }
+ }
+ return NULL;
+}
+
+void*
+_elf_mmap(Elf *elf) {
+#if HAVE_MMAP
+ void *tmp;
+
+ elf_assert(elf);
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ elf_assert(elf->e_base == 0);
+ if (elf->e_disabled) {
+ seterr(ERROR_FDDISABLED);
+ }
+ else if (elf->e_size) {
+ tmp = (void*)mmap(0, elf->e_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE, elf->e_fd, 0);
+ if (tmp != (void*)-1) {
+ return tmp;
+ }
+ }
+#endif /* HAVE_MMAP */
+ return NULL;
+}
diff --git a/lib/kind.c b/lib/kind.c
new file mode 100644
index 0000000..6f84f32
--- /dev/null
+++ b/lib/kind.c
@@ -0,0 +1,33 @@
+/*
+kind.c - implementation of the elf_kind(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: kind.c,v 1.7 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+Elf_Kind
+elf_kind(Elf *elf) {
+ if (!elf) {
+ return ELF_K_NONE;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ return elf->e_kind;
+}
diff --git a/lib/libelf.def b/lib/libelf.def
new file mode 100644
index 0000000..d77897b
--- /dev/null
+++ b/lib/libelf.def
@@ -0,0 +1,82 @@
+LIBRARY libelf
+VERSION 0.8
+EXPORTS
+ elf_begin
+ elf_cntl
+ elf_delscn
+ 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_hash
+ elf_kind
+ elf_memory
+ elf_ndxscn
+ elf_newdata
+ elf_newscn
+ elf_next
+ elf_nextscn
+ elf_rand
+ elf_rawdata
+ elf_rawfile
+ elf_strptr
+ elf_update
+ elf_version
+ 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
+ elfx_movscn
+ elfx_remscn
+ gelf_checksum
+ gelf_fsize
+ gelf_getclass
+ gelf_getdyn
+ gelf_getehdr
+ gelf_getphdr
+ gelf_getrel
+ gelf_getrela
+ gelf_getshdr
+ gelf_getsym
+ gelf_msize
+ gelf_newehdr
+ gelf_newphdr
+ gelf_update_dyn
+ gelf_update_ehdr
+ gelf_update_phdr
+ gelf_update_rel
+ gelf_update_rela
+ gelf_update_shdr
+ gelf_update_sym
+ gelf_xlatetof
+ gelf_xlatetom
+ elf_getphnum
+ elf_getshnum
+ elf_getshstrndx
+ elfx_update_shstrndx
diff --git a/lib/libelf.h b/lib/libelf.h
new file mode 100644
index 0000000..3ebd0f3
--- /dev/null
+++ b/lib/libelf.h
@@ -0,0 +1,305 @@
+/*
+ * libelf.h - public header file for libelf.
+ * Copyright (C) 1995 - 2008 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* @(#) $Id: libelf.h,v 1.29 2009/07/07 17:57:43 michael Exp $ */
+
+#ifndef _LIBELF_H
+#define _LIBELF_H
+
+#include <stddef.h> /* for size_t */
+#include <sys/types.h>
+
+#if __LIBELF_INTERNAL__
+#include <sys_elf.h>
+#else /* __LIBELF_INTERNAL__ */
+#include <libelf/sys_elf.h>
+#endif /* __LIBELF_INTERNAL__ */
+
+#if defined __GNUC__ && !defined __cplusplus
+#define DEPRECATED __attribute__((deprecated))
+#else
+#define DEPRECATED /* nothing */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef __P
+# if (__STDC__ + 0) || defined(__cplusplus) || defined(_WIN32)
+# define __P(args) args
+# else /* __STDC__ || defined(__cplusplus) */
+# define __P(args) ()
+# endif /* __STDC__ || defined(__cplusplus) */
+#endif /* __P */
+
+/*
+ * Commands
+ */
+typedef enum {
+ ELF_C_NULL = 0, /* must be first, 0 */
+ ELF_C_READ,
+ ELF_C_WRITE,
+ ELF_C_CLR,
+ ELF_C_SET,
+ ELF_C_FDDONE,
+ ELF_C_FDREAD,
+ ELF_C_RDWR,
+ ELF_C_NUM /* must be last */
+} Elf_Cmd;
+
+/*
+ * Flags
+ */
+#define ELF_F_DIRTY 0x1
+#define ELF_F_LAYOUT 0x4
+/*
+ * Allow sections to overlap when ELF_F_LAYOUT is in effect.
+ * Note that this flag ist NOT portable, and that it may render
+ * the output file unusable. Use with extreme caution!
+ */
+#define ELF_F_LAYOUT_OVERLAP 0x10000000
+
+/*
+ * File types
+ */
+typedef enum {
+ ELF_K_NONE = 0, /* must be first, 0 */
+ ELF_K_AR,
+ ELF_K_COFF,
+ ELF_K_ELF,
+ ELF_K_NUM /* must be last */
+} Elf_Kind;
+
+/*
+ * Data types
+ */
+typedef enum {
+ ELF_T_BYTE = 0, /* must be first, 0 */
+ ELF_T_ADDR,
+ ELF_T_DYN,
+ ELF_T_EHDR,
+ ELF_T_HALF,
+ ELF_T_OFF,
+ ELF_T_PHDR,
+ ELF_T_RELA,
+ ELF_T_REL,
+ ELF_T_SHDR,
+ ELF_T_SWORD,
+ ELF_T_SYM,
+ ELF_T_WORD,
+ /*
+ * New stuff for 64-bit.
+ *
+ * Most implementations add ELF_T_SXWORD after ELF_T_SWORD
+ * which breaks binary compatibility with earlier versions.
+ * If this causes problems for you, contact me.
+ */
+ ELF_T_SXWORD,
+ ELF_T_XWORD,
+ /*
+ * Symbol versioning. Sun broke binary compatibility (again!),
+ * but I won't.
+ */
+ ELF_T_VDEF,
+ ELF_T_VNEED,
+ ELF_T_NUM /* must be last */
+} Elf_Type;
+
+/*
+ * Elf descriptor
+ */
+typedef struct Elf Elf;
+
+/*
+ * Section descriptor
+ */
+typedef struct Elf_Scn Elf_Scn;
+
+/*
+ * Archive member header
+ */
+typedef struct {
+ char* ar_name;
+ time_t ar_date;
+ long ar_uid;
+ long ar_gid;
+ unsigned long ar_mode;
+ off_t ar_size;
+ char* ar_rawname;
+} Elf_Arhdr;
+
+/*
+ * Archive symbol table
+ */
+typedef struct {
+ char* as_name;
+ size_t as_off;
+ unsigned long as_hash;
+} Elf_Arsym;
+
+/*
+ * Data descriptor
+ */
+typedef struct {
+ void* d_buf;
+ Elf_Type d_type;
+ size_t d_size;
+ off_t d_off;
+ size_t d_align;
+ unsigned d_version;
+} Elf_Data;
+
+/*
+ * Function declarations
+ */
+extern Elf *elf_begin __P((int __fd, Elf_Cmd __cmd, Elf *__ref));
+extern Elf *elf_memory __P((char *__image, size_t __size));
+extern int elf_cntl __P((Elf *__elf, Elf_Cmd __cmd));
+extern int elf_end __P((Elf *__elf));
+extern const char *elf_errmsg __P((int __err));
+extern int elf_errno __P((void));
+extern void elf_fill __P((int __fill));
+extern unsigned elf_flagdata __P((Elf_Data *__data, Elf_Cmd __cmd,
+ unsigned __flags));
+extern unsigned elf_flagehdr __P((Elf *__elf, Elf_Cmd __cmd,
+ unsigned __flags));
+extern unsigned elf_flagelf __P((Elf *__elf, Elf_Cmd __cmd,
+ unsigned __flags));
+extern unsigned elf_flagphdr __P((Elf *__elf, Elf_Cmd __cmd,
+ unsigned __flags));
+extern unsigned elf_flagscn __P((Elf_Scn *__scn, Elf_Cmd __cmd,
+ unsigned __flags));
+extern unsigned elf_flagshdr __P((Elf_Scn *__scn, Elf_Cmd __cmd,
+ unsigned __flags));
+extern size_t elf32_fsize __P((Elf_Type __type, size_t __count,
+ unsigned __ver));
+extern Elf_Arhdr *elf_getarhdr __P((Elf *__elf));
+extern Elf_Arsym *elf_getarsym __P((Elf *__elf, size_t *__ptr));
+extern off_t elf_getbase __P((Elf *__elf));
+extern Elf_Data *elf_getdata __P((Elf_Scn *__scn, Elf_Data *__data));
+extern Elf32_Ehdr *elf32_getehdr __P((Elf *__elf));
+extern char *elf_getident __P((Elf *__elf, size_t *__ptr));
+extern Elf32_Phdr *elf32_getphdr __P((Elf *__elf));
+extern Elf_Scn *elf_getscn __P((Elf *__elf, size_t __index));
+extern Elf32_Shdr *elf32_getshdr __P((Elf_Scn *__scn));
+extern unsigned long elf_hash __P((const unsigned char *__name));
+extern Elf_Kind elf_kind __P((Elf *__elf));
+extern size_t elf_ndxscn __P((Elf_Scn *__scn));
+extern Elf_Data *elf_newdata __P((Elf_Scn *__scn));
+extern Elf32_Ehdr *elf32_newehdr __P((Elf *__elf));
+extern Elf32_Phdr *elf32_newphdr __P((Elf *__elf, size_t __count));
+extern Elf_Scn *elf_newscn __P((Elf *__elf));
+extern Elf_Cmd elf_next __P((Elf *__elf));
+extern Elf_Scn *elf_nextscn __P((Elf *__elf, Elf_Scn *__scn));
+extern size_t elf_rand __P((Elf *__elf, size_t __offset));
+extern Elf_Data *elf_rawdata __P((Elf_Scn *__scn, Elf_Data *__data));
+extern char *elf_rawfile __P((Elf *__elf, size_t *__ptr));
+extern char *elf_strptr __P((Elf *__elf, size_t __section, size_t __offset));
+extern off_t elf_update __P((Elf *__elf, Elf_Cmd __cmd));
+extern unsigned elf_version __P((unsigned __ver));
+extern Elf_Data *elf32_xlatetof __P((Elf_Data *__dst, const Elf_Data *__src,
+ unsigned __encode));
+extern Elf_Data *elf32_xlatetom __P((Elf_Data *__dst, const Elf_Data *__src,
+ unsigned __encode));
+
+/*
+ * Additional functions found on Solaris
+ */
+extern long elf32_checksum __P((Elf *__elf));
+
+#if __LIBELF64
+/*
+ * 64-bit ELF functions
+ * Not available on all platforms
+ */
+extern Elf64_Ehdr *elf64_getehdr __P((Elf *__elf));
+extern Elf64_Ehdr *elf64_newehdr __P((Elf *__elf));
+extern Elf64_Phdr *elf64_getphdr __P((Elf *__elf));
+extern Elf64_Phdr *elf64_newphdr __P((Elf *__elf, size_t __count));
+extern Elf64_Shdr *elf64_getshdr __P((Elf_Scn *__scn));
+extern size_t elf64_fsize __P((Elf_Type __type, size_t __count,
+ unsigned __ver));
+extern Elf_Data *elf64_xlatetof __P((Elf_Data *__dst, const Elf_Data *__src,
+ unsigned __encode));
+extern Elf_Data *elf64_xlatetom __P((Elf_Data *__dst, const Elf_Data *__src,
+ unsigned __encode));
+
+/*
+ * Additional functions found on Solaris
+ */
+extern long elf64_checksum __P((Elf *__elf));
+
+#endif /* __LIBELF64 */
+
+/*
+ * ELF format extensions
+ *
+ * These functions return 0 on failure, 1 on success. Since other
+ * implementations of libelf may behave differently (there was quite
+ * some confusion about the correct values), they are now officially
+ * deprecated and should be replaced with the three new functions below.
+ */
+DEPRECATED extern int elf_getphnum __P((Elf *__elf, size_t *__resultp));
+DEPRECATED extern int elf_getshnum __P((Elf *__elf, size_t *__resultp));
+DEPRECATED extern int elf_getshstrndx __P((Elf *__elf, size_t *__resultp));
+/*
+ * Replacement functions (return -1 on failure, 0 on success).
+ */
+extern int elf_getphdrnum __P((Elf *__elf, size_t *__resultp));
+extern int elf_getshdrnum __P((Elf *__elf, size_t *__resultp));
+extern int elf_getshdrstrndx __P((Elf *__elf, size_t *__resultp));
+
+/*
+ * Convenience functions
+ *
+ * elfx_update_shstrndx is elf_getshstrndx's counterpart.
+ * It should be used to set the e_shstrndx member.
+ * There is no update function for e_shnum or e_phnum
+ * because libelf handles them internally.
+ */
+extern int elfx_update_shstrndx __P((Elf *__elf, size_t __index));
+
+/*
+ * Experimental extensions:
+ *
+ * elfx_movscn() moves section `__scn' directly after section `__after'.
+ * elfx_remscn() removes section `__scn'. Both functions update
+ * the section indices; elfx_remscn() also adjusts the ELF header's
+ * e_shnum member. The application is responsible for updating other
+ * data (in particular, e_shstrndx and the section headers' sh_link and
+ * sh_info members).
+ *
+ * elfx_movscn() returns the new index of the moved section.
+ * elfx_remscn() returns the original index of the removed section.
+ * A return value of zero indicates an error.
+ */
+extern size_t elfx_movscn __P((Elf *__elf, Elf_Scn *__scn, Elf_Scn *__after));
+extern size_t elfx_remscn __P((Elf *__elf, Elf_Scn *__scn));
+
+/*
+ * elf_delscn() is obsolete. Please use elfx_remscn() instead.
+ */
+extern size_t elf_delscn __P((Elf *__elf, Elf_Scn *__scn));
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LIBELF_H */
diff --git a/lib/memset.c b/lib/memset.c
new file mode 100644
index 0000000..e398bb5
--- /dev/null
+++ b/lib/memset.c
@@ -0,0 +1,53 @@
+/*
+ * memset.c - replacement for memset(3), using duff's device.
+ * Copyright (C) 1995 - 2004 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: memset.c,v 1.11 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+#include <stddef.h> /* for size_t */
+#include <sys/types.h>
+
+void*
+_elf_memset(void *s, int c, size_t n) {
+ char *t = (char*)s;
+
+ if (n) {
+ switch (n % 8u) {
+ do {
+ n -= 8;
+ default:
+ case 0: *t++ = (char)c;
+ case 7: *t++ = (char)c;
+ case 6: *t++ = (char)c;
+ case 5: *t++ = (char)c;
+ case 4: *t++ = (char)c;
+ case 3: *t++ = (char)c;
+ case 2: *t++ = (char)c;
+ case 1: *t++ = (char)c;
+ }
+ while (n > 8);
+ }
+ }
+ return s;
+}
diff --git a/lib/ndxscn.c b/lib/ndxscn.c
new file mode 100644
index 0000000..c9ab9a8
--- /dev/null
+++ b/lib/ndxscn.c
@@ -0,0 +1,33 @@
+/*
+ndxscn.c - implementation of the elf_ndxscn(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: ndxscn.c,v 1.7 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+size_t
+elf_ndxscn(Elf_Scn *scn) {
+ if (!scn) {
+ return SHN_UNDEF;
+ }
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ return scn->s_index;
+}
diff --git a/lib/newdata.c b/lib/newdata.c
new file mode 100644
index 0000000..2a6eeba
--- /dev/null
+++ b/lib/newdata.c
@@ -0,0 +1,56 @@
+/*
+newdata.c - implementation of the elf_newdata(3) function.
+Copyright (C) 1995 - 2000 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: newdata.c,v 1.10 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+Elf_Data*
+elf_newdata(Elf_Scn *scn) {
+ Scn_Data *sd;
+
+ if (!scn) {
+ return NULL;
+ }
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ if (scn->s_index == SHN_UNDEF) {
+ seterr(ERROR_NULLSCN);
+ }
+ else if (!(sd = (Scn_Data*)malloc(sizeof(*sd)))) {
+ seterr(ERROR_MEM_SCNDATA);
+ }
+ else {
+ *sd = _elf_data_init;
+ sd->sd_scn = scn;
+ sd->sd_data_flags = ELF_F_DIRTY;
+ sd->sd_freeme = 1;
+ sd->sd_data.d_version = _elf_version;
+ if (scn->s_data_n) {
+ scn->s_data_n->sd_link = sd;
+ }
+ else {
+ scn->s_data_1 = sd;
+ }
+ scn->s_data_n = sd;
+ return &sd->sd_data;
+ }
+ return NULL;
+}
diff --git a/lib/newscn.c b/lib/newscn.c
new file mode 100644
index 0000000..69ba65d
--- /dev/null
+++ b/lib/newscn.c
@@ -0,0 +1,145 @@
+/*
+ * newscn.c - implementation of the elf_newscn(3) function.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: newscn.c,v 1.13 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+int
+_elf_update_shnum(Elf *elf, size_t shnum) {
+ size_t extshnum = 0;
+ Elf_Scn *scn;
+
+ elf_assert(elf);
+ elf_assert(elf->e_ehdr);
+ scn = elf->e_scn_1;
+ elf_assert(scn);
+ elf_assert(scn->s_index == 0);
+ if (shnum >= SHN_LORESERVE) {
+ extshnum = shnum;
+ shnum = 0;
+ }
+ if (elf->e_class == ELFCLASS32) {
+ ((Elf32_Ehdr*)elf->e_ehdr)->e_shnum = shnum;
+ scn->s_shdr32.sh_size = extshnum;
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ ((Elf64_Ehdr*)elf->e_ehdr)->e_shnum = shnum;
+ scn->s_shdr64.sh_size = extshnum;
+ }
+#endif /* __LIBELF64 */
+ else {
+ if (valid_class(elf->e_class)) {
+ seterr(ERROR_UNIMPLEMENTED);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ return -1;
+ }
+ elf->e_ehdr_flags |= ELF_F_DIRTY;
+ scn->s_shdr_flags |= ELF_F_DIRTY;
+ return 0;
+}
+
+static Elf_Scn*
+_makescn(Elf *elf, size_t index) {
+ Elf_Scn *scn;
+
+ elf_assert(elf);
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ elf_assert(elf->e_ehdr);
+ elf_assert(_elf_scn_init.s_magic == SCN_MAGIC);
+ if (!(scn = (Elf_Scn*)malloc(sizeof(*scn)))) {
+ seterr(ERROR_MEM_SCN);
+ return NULL;
+ }
+ *scn = _elf_scn_init;
+ scn->s_elf = elf;
+ scn->s_scn_flags = ELF_F_DIRTY;
+ scn->s_shdr_flags = ELF_F_DIRTY;
+ scn->s_freeme = 1;
+ scn->s_index = index;
+ return scn;
+}
+
+Elf_Scn*
+_elf_first_scn(Elf *elf) {
+ Elf_Scn *scn;
+
+ elf_assert(elf);
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if ((scn = elf->e_scn_1)) {
+ return scn;
+ }
+ if ((scn = _makescn(elf, 0))) {
+ elf->e_scn_1 = elf->e_scn_n = scn;
+ if (_elf_update_shnum(elf, 1)) {
+ free(scn);
+ elf->e_scn_1 = elf->e_scn_n = scn = NULL;
+ }
+ }
+ return scn;
+}
+
+static Elf_Scn*
+_buildscn(Elf *elf) {
+ Elf_Scn *scn;
+
+ if (!_elf_first_scn(elf)) {
+ return NULL;
+ }
+ scn = elf->e_scn_n;
+ elf_assert(scn);
+ if (!(scn = _makescn(elf, scn->s_index + 1))) {
+ return NULL;
+ }
+ if (_elf_update_shnum(elf, scn->s_index + 1)) {
+ free(scn);
+ return NULL;
+ }
+ elf->e_scn_n = elf->e_scn_n->s_link = scn;
+ return scn;
+}
+
+Elf_Scn*
+elf_newscn(Elf *elf) {
+ Elf_Scn *scn;
+
+ if (!elf) {
+ return NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (!elf->e_readable && !elf->e_ehdr) {
+ seterr(ERROR_NOEHDR);
+ }
+ else if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ }
+ else if (!elf->e_ehdr && !_elf_cook(elf)) {
+ return NULL;
+ }
+ else if ((scn = _buildscn(elf))) {
+ return scn;
+ }
+ return NULL;
+}
diff --git a/lib/next.c b/lib/next.c
new file mode 100644
index 0000000..bf9a67b
--- /dev/null
+++ b/lib/next.c
@@ -0,0 +1,42 @@
+/*
+next.c - implementation of the elf_next(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: next.c,v 1.7 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+Elf_Cmd
+elf_next(Elf *elf) {
+ if (!elf) {
+ return ELF_C_NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (!elf->e_parent) {
+ return ELF_C_NULL;
+ }
+ elf_assert(elf->e_parent->e_magic == ELF_MAGIC);
+ elf_assert(elf->e_parent->e_kind == ELF_K_AR);
+ elf->e_parent->e_off = elf->e_next;
+ if (elf->e_next == elf->e_parent->e_size) {
+ return ELF_C_NULL;
+ }
+ return ELF_C_READ;
+}
diff --git a/lib/nextscn.c b/lib/nextscn.c
new file mode 100644
index 0000000..4543f83
--- /dev/null
+++ b/lib/nextscn.c
@@ -0,0 +1,54 @@
+/*
+nextscn.c - implementation of the elf_nextscn(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: nextscn.c,v 1.7 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+Elf_Scn*
+elf_nextscn(Elf *elf, Elf_Scn *scn) {
+ if (!elf) {
+ return NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (scn) {
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ if (scn->s_elf == elf) {
+ return scn->s_link;
+ }
+ seterr(ERROR_ELFSCNMISMATCH);
+ }
+ else if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ }
+ else if (elf->e_ehdr || _elf_cook(elf)) {
+ elf_assert(elf->e_ehdr);
+ for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ elf_assert(scn->s_elf == elf);
+ if (scn->s_index == 1) {
+ return scn;
+ }
+ }
+ seterr(ERROR_NOSUCHSCN);
+ }
+ return NULL;
+}
diff --git a/lib/nlist.c b/lib/nlist.c
new file mode 100644
index 0000000..933d33f
--- /dev/null
+++ b/lib/nlist.c
@@ -0,0 +1,253 @@
+/*
+ * nlist.c - implementation of the nlist(3) function.
+ * Copyright (C) 1995 - 2004 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+#include <nlist.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: nlist.c,v 1.15 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+#if !defined(_WIN32)
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#else
+extern int open();
+#endif /* HAVE_FCNTL_H */
+#endif /* defined(_WIN32) */
+
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#endif /* O_RDONLY */
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif /* O_BINARY */
+
+#define FILE_OPEN_MODE (O_RDONLY | O_BINARY)
+
+#define PRIME 217
+
+struct hash {
+ const char* name;
+ unsigned long hash;
+ unsigned next;
+};
+
+static const char*
+symbol_name(Elf *elf, const void *syms, const char *names, size_t nlimit, size_t index) {
+ size_t off;
+
+ if (elf->e_class == ELFCLASS32) {
+ off = ((Elf32_Sym*)syms)[index].st_name;
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ off = ((Elf64_Sym*)syms)[index].st_name;
+ }
+#endif /* __LIBELF64 */
+ else {
+ return NULL;
+ }
+ if (off >= 0 && off < nlimit) {
+ return &names[off];
+ }
+ return NULL;
+}
+
+static void
+copy_symbol(Elf *elf, struct nlist *np, const void *syms, size_t index) {
+ if (elf->e_class == ELFCLASS32) {
+ np->n_value = ((Elf32_Sym*)syms)[index].st_value;
+ np->n_scnum = ((Elf32_Sym*)syms)[index].st_shndx;
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ np->n_value = ((Elf64_Sym*)syms)[index].st_value;
+ np->n_scnum = ((Elf64_Sym*)syms)[index].st_shndx;
+ }
+#endif /* __LIBELF64 */
+ /*
+ * this needs more work
+ */
+ np->n_type = 0;
+ np->n_sclass = 0;
+ np->n_numaux = 0;
+}
+
+static int
+_elf_nlist(Elf *elf, struct nlist *nl) {
+ unsigned first[PRIME];
+ Elf_Scn *symtab = NULL;
+ Elf_Scn *strtab = NULL;
+ Elf_Data *symdata;
+ Elf_Data *strdata;
+ size_t symsize;
+ size_t nsymbols;
+ const char *name;
+ struct hash *table;
+ unsigned long hash;
+ unsigned i;
+ struct nlist *np;
+
+ /*
+ * Get and translate ELF header, section table and so on.
+ * Must be class independent, so don't use elf32_get*().
+ */
+ if (elf->e_kind != ELF_K_ELF) {
+ return -1;
+ }
+ if (!elf->e_ehdr && !_elf_cook(elf)) {
+ return -1;
+ }
+
+ /*
+ * Find symbol table. If there is none, try dynamic symbols.
+ */
+ for (symtab = elf->e_scn_1; symtab; symtab = symtab->s_link) {
+ if (symtab->s_type == SHT_SYMTAB) {
+ break;
+ }
+ if (symtab->s_type == SHT_DYNSYM) {
+ strtab = symtab;
+ }
+ }
+ if (!symtab && !(symtab = strtab)) {
+ return -1;
+ }
+
+ /*
+ * Get associated string table.
+ */
+ i = 0;
+ if (elf->e_class == ELFCLASS32) {
+ i = symtab->s_shdr32.sh_link;
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ i = symtab->s_shdr64.sh_link;
+ }
+#endif /* __LIBELF64 */
+ if (i == 0) {
+ return -1;
+ }
+ for (strtab = elf->e_scn_1; strtab; strtab = strtab->s_link) {
+ if (strtab->s_index == i) {
+ break;
+ }
+ }
+ if (!strtab || strtab->s_type != SHT_STRTAB) {
+ return -1;
+ }
+
+ /*
+ * Get and translate section data.
+ */
+ symdata = elf_getdata(symtab, NULL);
+ strdata = elf_getdata(strtab, NULL);
+ if (!symdata || !strdata) {
+ return -1;
+ }
+ symsize = _msize(elf->e_class, _elf_version, ELF_T_SYM);
+ elf_assert(symsize);
+ nsymbols = symdata->d_size / symsize;
+ if (!symdata->d_buf || !strdata->d_buf || !nsymbols || !strdata->d_size) {
+ return -1;
+ }
+
+ /*
+ * Build a simple hash table.
+ */
+ if (!(table = (struct hash*)malloc(nsymbols * sizeof(*table)))) {
+ return -1;
+ }
+ for (i = 0; i < PRIME; i++) {
+ first[i] = 0;
+ }
+ for (i = 0; i < nsymbols; i++) {
+ table[i].name = NULL;
+ table[i].hash = 0;
+ table[i].next = 0;
+ }
+ for (i = 1; i < nsymbols; i++) {
+ name = symbol_name(elf, symdata->d_buf, strdata->d_buf,
+ strdata->d_size, i);
+ if (name == NULL) {
+ free(table);
+ return -1;
+ }
+ if (*name != '\0') {
+ table[i].name = name;
+ table[i].hash = elf_hash((unsigned char*)name);
+ hash = table[i].hash % PRIME;
+ table[i].next = first[hash];
+ first[hash] = i;
+ }
+ }
+
+ /*
+ * Lookup symbols, one by one.
+ */
+ for (np = nl; (name = np->n_name) && *name; np++) {
+ hash = elf_hash((unsigned char*)name);
+ for (i = first[hash % PRIME]; i; i = table[i].next) {
+ if (table[i].hash == hash && !strcmp(table[i].name, name)) {
+ break;
+ }
+ }
+ if (i) {
+ copy_symbol(elf, np, symdata->d_buf, i);
+ }
+ else {
+ np->n_value = 0;
+ np->n_scnum = 0;
+ np->n_type = 0;
+ np->n_sclass = 0;
+ np->n_numaux = 0;
+ }
+ }
+ free(table);
+ return 0;
+}
+
+int
+nlist(const char *filename, struct nlist *nl) {
+ int result = -1;
+ unsigned oldver;
+ Elf *elf;
+ int fd;
+
+ if ((oldver = elf_version(EV_CURRENT)) != EV_NONE) {
+ if ((fd = open(filename, FILE_OPEN_MODE)) != -1) {
+ if ((elf = elf_begin(fd, ELF_C_READ, NULL))) {
+ result = _elf_nlist(elf, nl);
+ elf_end(elf);
+ }
+ close(fd);
+ }
+ elf_version(oldver);
+ }
+ if (result) {
+ while (nl->n_name && *nl->n_name) {
+ nl->n_value = 0;
+ nl++;
+ }
+ }
+ return result;
+}
diff --git a/lib/nlist.h b/lib/nlist.h
new file mode 100644
index 0000000..27a452e
--- /dev/null
+++ b/lib/nlist.h
@@ -0,0 +1,48 @@
+/*
+ * nlist.h - public header file for nlist(3).
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* @(#) $Id: nlist.h,v 1.10 2008/05/23 08:15:35 michael Exp $ */
+
+#ifndef _NLIST_H
+#define _NLIST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct nlist {
+ char* n_name;
+ long n_value;
+ short n_scnum;
+ unsigned short n_type;
+ char n_sclass;
+ char n_numaux;
+};
+
+#if (__STDC__ + 0) || defined(__cplusplus) || defined(_WIN32)
+extern int nlist(const char *__filename, struct nlist *__nl);
+#else /* __STDC__ || defined(__cplusplus) */
+extern int nlist();
+#endif /* __STDC__ || defined(__cplusplus) */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _NLIST_H */
diff --git a/lib/opt.delscn.c b/lib/opt.delscn.c
new file mode 100644
index 0000000..2201155
--- /dev/null
+++ b/lib/opt.delscn.c
@@ -0,0 +1,205 @@
+/*
+opt.delscn.c - implementation of the elf_delscn(3) function.
+Copyright (C) 1995 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: opt.delscn.c,v 1.12 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+static size_t
+_newindex(size_t old, size_t index) {
+ return old == index ? SHN_UNDEF : (old > index ? old - 1 : old);
+}
+
+static void
+_elf32_update_shdr(Elf *elf, size_t index) {
+ Elf32_Shdr *shdr;
+ Elf_Scn *scn;
+
+ ((Elf32_Ehdr*)elf->e_ehdr)->e_shnum = elf->e_scn_n->s_index + 1;
+ for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+ shdr = &scn->s_shdr32;
+ switch (shdr->sh_type) {
+ case SHT_REL:
+ case SHT_RELA:
+ shdr->sh_info = _newindex(shdr->sh_info, index);
+ /* fall through */
+ case SHT_DYNSYM:
+ case SHT_DYNAMIC:
+ case SHT_HASH:
+ case SHT_SYMTAB:
+#if __LIBELF_SYMBOL_VERSIONS
+#if __LIBELF_SUN_SYMBOL_VERSIONS
+ case SHT_SUNW_verdef:
+ case SHT_SUNW_verneed:
+ case SHT_SUNW_versym:
+#else /* __LIBELF_SUN_SYMBOL_VERSIONS */
+ case SHT_GNU_verdef:
+ case SHT_GNU_verneed:
+ case SHT_GNU_versym:
+#endif /* __LIBELF_SUN_SYMBOL_VERSIONS */
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+ shdr->sh_link = _newindex(shdr->sh_link, index);
+ /* fall through */
+ default:
+ break;
+ }
+ }
+}
+
+#if __LIBELF64
+
+static void
+_elf64_update_shdr(Elf *elf, size_t index) {
+ Elf64_Shdr *shdr;
+ Elf_Scn *scn;
+
+ ((Elf64_Ehdr*)elf->e_ehdr)->e_shnum = elf->e_scn_n->s_index + 1;
+ for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+ shdr = &scn->s_shdr64;
+ switch (shdr->sh_type) {
+ case SHT_REL:
+ case SHT_RELA:
+ shdr->sh_info = _newindex(shdr->sh_info, index);
+ /* fall through */
+ case SHT_DYNSYM:
+ case SHT_DYNAMIC:
+ case SHT_HASH:
+ case SHT_SYMTAB:
+#if __LIBELF_SYMBOL_VERSIONS
+#if __LIBELF_SUN_SYMBOL_VERSIONS
+ case SHT_SUNW_verdef:
+ case SHT_SUNW_verneed:
+ case SHT_SUNW_versym:
+#else /* __LIBELF_SUN_SYMBOL_VERSIONS */
+ case SHT_GNU_verdef:
+ case SHT_GNU_verneed:
+ case SHT_GNU_versym:
+#endif /* __LIBELF_SUN_SYMBOL_VERSIONS */
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+ shdr->sh_link = _newindex(shdr->sh_link, index);
+ /* fall through */
+ default:
+ break;
+ }
+ }
+}
+
+#endif /* __LIBELF64 */
+
+size_t
+elf_delscn(Elf *elf, Elf_Scn *scn) {
+ Elf_Scn *pscn;
+ Scn_Data *sd;
+ Scn_Data *tmp;
+ size_t index;
+
+ if (!elf || !scn) {
+ return SHN_UNDEF;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ elf_assert(elf->e_ehdr);
+ if (scn->s_elf != elf) {
+ seterr(ERROR_ELFSCNMISMATCH);
+ return SHN_UNDEF;
+ }
+ elf_assert(elf->e_scn_1);
+ if (scn == elf->e_scn_1) {
+ seterr(ERROR_NULLSCN);
+ return SHN_UNDEF;
+ }
+
+ /*
+ * Find previous section.
+ */
+ for (pscn = elf->e_scn_1; pscn->s_link; pscn = pscn->s_link) {
+ if (pscn->s_link == scn) {
+ break;
+ }
+ }
+ if (pscn->s_link != scn) {
+ seterr(ERROR_ELFSCNMISMATCH);
+ return SHN_UNDEF;
+ }
+ /*
+ * Unlink section.
+ */
+ if (elf->e_scn_n == scn) {
+ elf->e_scn_n = pscn;
+ }
+ pscn->s_link = scn->s_link;
+ index = scn->s_index;
+ /*
+ * Free section descriptor and data.
+ */
+ for (sd = scn->s_data_1; sd; sd = tmp) {
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ elf_assert(sd->sd_scn == scn);
+ tmp = sd->sd_link;
+ if (sd->sd_free_data && sd->sd_memdata) {
+ free(sd->sd_memdata);
+ }
+ if (sd->sd_freeme) {
+ free(sd);
+ }
+ }
+ if ((sd = scn->s_rawdata)) {
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ elf_assert(sd->sd_scn == scn);
+ if (sd->sd_free_data && sd->sd_memdata) {
+ free(sd->sd_memdata);
+ }
+ if (sd->sd_freeme) {
+ free(sd);
+ }
+ }
+ if (scn->s_freeme) {
+ elf_assert(scn->s_index > 0);
+ free(scn);
+ }
+ /*
+ * Adjust section indices.
+ */
+ for (scn = pscn->s_link; scn; scn = scn->s_link) {
+ elf_assert(scn->s_index > index);
+ scn->s_index--;
+ }
+ /*
+ * Adjust ELF header and well-known section headers.
+ */
+ if (elf->e_class == ELFCLASS32) {
+ _elf32_update_shdr(elf, index);
+ return index;
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ _elf64_update_shdr(elf, index);
+ return index;
+ }
+#endif /* __LIBELF64 */
+ else if (valid_class(elf->e_class)) {
+ seterr(ERROR_UNIMPLEMENTED);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ return SHN_UNDEF;
+}
diff --git a/lib/private.h b/lib/private.h
new file mode 100644
index 0000000..2b772dc
--- /dev/null
+++ b/lib/private.h
@@ -0,0 +1,446 @@
+/*
+ * private.h - private definitions for libelf.
+ * Copyright (C) 1995 - 2007 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* @(#) $Id: private.h,v 1.40 2009/11/01 13:04:19 michael Exp $ */
+
+#ifndef _PRIVATE_H
+#define _PRIVATE_H
+
+#define __LIBELF_INTERNAL__ 1
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+/*
+ * Workaround for GLIBC bug:
+ * include <stdint.h> before <sys/types.h>
+ */
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <sys/types.h>
+
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else /* STDC_HEADERS */
+extern void *malloc(), *realloc();
+extern void free(), bcopy(), abort();
+extern int strcmp(), strncmp(), memcmp();
+extern void *memcpy(), *memmove(), *memset();
+#endif /* STDC_HEADERS */
+
+#if defined(_WIN32)
+#include <io.h>
+#else
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#else /* HAVE_UNISTD_H */
+extern int read(), write(), close();
+extern off_t lseek();
+#if HAVE_FTRUNCATE
+extern int ftruncate();
+#endif /* HAVE_FTRUNCATE */
+#endif /* HAVE_UNISTD_H */
+#endif /* defined(_WIN32) */
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif /* SEEK_SET */
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif /* SEEK_CUR */
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif /* SEEK_END */
+
+#if !HAVE_MEMCMP
+# define memcmp strncmp
+#endif /* !HAVE_MEMCMP */
+#if !HAVE_MEMCPY
+# define memcpy(d,s,n) bcopy(s,d,n)
+#endif /* !HAVE_MEMCPY */
+#if !HAVE_MEMMOVE
+# define memmove(d,s,n) bcopy(s,d,n)
+#endif /* !HAVE_MEMMOVE */
+
+#if !HAVE_MEMSET
+# define memset _elf_memset
+extern void *_elf_memset();
+#endif /* !HAVE_MEMSET */
+
+#if HAVE_STRUCT_NLIST_DECLARATION
+# define nlist __override_nlist_declaration
+#endif /* HAVE_STRUCT_NLIST_DECLARATION */
+
+#if __LIBELF_NEED_LINK_H
+# include <link.h>
+#elif __LIBELF_NEED_SYS_LINK_H
+# include <sys/link.h>
+#endif /* __LIBELF_NEED_LINK_H */
+
+#if HAVE_AR_H
+#include <ar.h>
+#else /* HAVE_AR_H */
+
+#define ARMAG "!<arch>\n"
+#define SARMAG 8
+
+struct ar_hdr {
+ char ar_name[16];
+ char ar_date[12];
+ char ar_uid[6];
+ char ar_gid[6];
+ char ar_mode[8];
+ char ar_size[10];
+ char ar_fmag[2];
+};
+
+#define ARFMAG "`\n"
+
+#endif /* HAVE_AR_H */
+
+#include <libelf.h>
+
+#if HAVE_STRUCT_NLIST_DECLARATION
+# undef nlist
+#endif /* HAVE_STRUCT_NLIST_DECLARATION */
+
+#if __LIBELF64
+#include <gelf.h>
+#endif /* __LIBELF64 */
+
+typedef struct Scn_Data Scn_Data;
+
+/*
+ * ELF descriptor
+ */
+struct Elf {
+ /* common */
+ size_t e_size; /* file/member size */
+ size_t e_dsize; /* size of memory image */
+ Elf_Kind e_kind; /* kind of file */
+ char* e_data; /* file/member data */
+ char* e_rawdata; /* file/member raw data */
+ size_t e_idlen; /* identifier size */
+ int e_fd; /* file descriptor */
+ unsigned e_count; /* activation count */
+ /* archive members (still common) */
+ Elf* e_parent; /* NULL if not an archive member */
+ size_t e_next; /* 0 if not an archive member */
+ size_t e_base; /* 0 if not an archive member */
+ Elf* e_link; /* next archive member or NULL */
+ Elf_Arhdr* e_arhdr; /* archive member header or NULL */
+ /* archives */
+ size_t e_off; /* current member offset (for elf_begin) */
+ Elf* e_members; /* linked list of active archive members */
+ char* e_symtab; /* archive symbol table */
+ size_t e_symlen; /* length of archive symbol table */
+ char* e_strtab; /* archive string table */
+ size_t e_strlen; /* length of archive string table */
+ /* ELF files */
+ unsigned e_class; /* ELF class */
+ unsigned e_encoding; /* ELF data encoding */
+ unsigned e_version; /* ELF version */
+ char* e_ehdr; /* ELF header */
+ char* e_phdr; /* ELF program header table */
+ size_t e_phnum; /* size of program header table */
+ Elf_Scn* e_scn_1; /* first section */
+ Elf_Scn* e_scn_n; /* last section */
+ unsigned e_elf_flags; /* elf flags (ELF_F_*) */
+ unsigned e_ehdr_flags; /* ehdr flags (ELF_F_*) */
+ unsigned e_phdr_flags; /* phdr flags (ELF_F_*) */
+ /* misc flags */
+ unsigned e_readable : 1; /* file is readable */
+ unsigned e_writable : 1; /* file is writable */
+ unsigned e_disabled : 1; /* e_fd has been disabled */
+ unsigned e_cooked : 1; /* e_data was modified */
+ unsigned e_free_syms : 1; /* e_symtab is malloc'ed */
+ unsigned e_unmap_data : 1; /* e_data is mmap'ed */
+ unsigned e_memory : 1; /* created by elf_memory() */
+ /* magic number for debugging */
+ long e_magic;
+};
+
+#define ELF_MAGIC 0x012b649e
+
+#define INIT_ELF {\
+ /* e_size */ 0,\
+ /* e_dsize */ 0,\
+ /* e_kind */ ELF_K_NONE,\
+ /* e_data */ NULL,\
+ /* e_rawdata */ NULL,\
+ /* e_idlen */ 0,\
+ /* e_fd */ -1,\
+ /* e_count */ 1,\
+ /* e_parent */ NULL,\
+ /* e_next */ 0,\
+ /* e_base */ 0,\
+ /* e_link */ NULL,\
+ /* e_arhdr */ NULL,\
+ /* e_off */ 0,\
+ /* e_members */ NULL,\
+ /* e_symtab */ NULL,\
+ /* e_symlen */ 0,\
+ /* e_strtab */ NULL,\
+ /* e_strlen */ 0,\
+ /* e_class */ ELFCLASSNONE,\
+ /* e_encoding */ ELFDATANONE,\
+ /* e_version */ EV_NONE,\
+ /* e_ehdr */ NULL,\
+ /* e_phdr */ NULL,\
+ /* e_phnum */ 0,\
+ /* e_scn_1 */ NULL,\
+ /* e_scn_n */ NULL,\
+ /* e_elf_flags */ 0,\
+ /* e_ehdr_flags */ 0,\
+ /* e_phdr_flags */ 0,\
+ /* e_readable */ 0,\
+ /* e_writable */ 0,\
+ /* e_disabled */ 0,\
+ /* e_cooked */ 0,\
+ /* e_free_syms */ 0,\
+ /* e_unmap_data */ 0,\
+ /* e_memory */ 0,\
+ /* e_magic */ ELF_MAGIC\
+}
+
+/*
+ * Section descriptor
+ */
+struct Elf_Scn {
+ Elf_Scn* s_link; /* pointer to next Elf_Scn */
+ Elf* s_elf; /* pointer to elf descriptor */
+ size_t s_index; /* number of this section */
+ unsigned s_scn_flags; /* section flags (ELF_F_*) */
+ unsigned s_shdr_flags; /* shdr flags (ELF_F_*) */
+ Scn_Data* s_data_1; /* first data buffer */
+ Scn_Data* s_data_n; /* last data buffer */
+ Scn_Data* s_rawdata; /* raw data buffer */
+ /* data copied from shdr */
+ unsigned s_type; /* section type */
+ size_t s_offset; /* section offset */
+ size_t s_size; /* section size */
+ /* misc flags */
+ unsigned s_freeme : 1; /* this Elf_Scn was malloc'ed */
+ /* section header */
+ union {
+#if __LIBELF64
+ Elf64_Shdr u_shdr64;
+#endif /* __LIBELF64 */
+ Elf32_Shdr u_shdr32;
+ } s_uhdr;
+ /* magic number for debugging */
+ long s_magic;
+};
+#define s_shdr32 s_uhdr.u_shdr32
+#define s_shdr64 s_uhdr.u_shdr64
+
+#define SCN_MAGIC 0x012c747d
+
+#define INIT_SCN {\
+ /* s_link */ NULL,\
+ /* s_elf */ NULL,\
+ /* s_index */ 0,\
+ /* s_scn_flags */ 0,\
+ /* s_shdr_flags */ 0,\
+ /* s_data_1 */ NULL,\
+ /* s_data_n */ NULL,\
+ /* s_rawdata */ NULL,\
+ /* s_type */ SHT_NULL,\
+ /* s_offset */ 0,\
+ /* s_size */ 0,\
+ /* s_freeme */ 0,\
+ /* s_uhdr */ {{0,}},\
+ /* s_magic */ SCN_MAGIC\
+}
+
+/*
+ * Data descriptor
+ */
+struct Scn_Data {
+ Elf_Data sd_data; /* must be first! */
+ Scn_Data* sd_link; /* pointer to next Scn_Data */
+ Elf_Scn* sd_scn; /* pointer to section */
+ char* sd_memdata; /* memory image of section */
+ unsigned sd_data_flags; /* data flags (ELF_F_*) */
+ /* misc flags */
+ unsigned sd_freeme : 1; /* this Scn_Data was malloc'ed */
+ unsigned sd_free_data : 1; /* sd_memdata is malloc'ed */
+ /* magic number for debugging */
+ long sd_magic;
+};
+
+#define DATA_MAGIC 0x01072639
+
+#define INIT_DATA {\
+ {\
+ /* d_buf */ NULL,\
+ /* d_type */ ELF_T_BYTE,\
+ /* d_size */ 0,\
+ /* d_off */ 0,\
+ /* d_align */ 0,\
+ /* d_version */ EV_NONE\
+ },\
+ /* sd_link */ NULL,\
+ /* sd_scn */ NULL,\
+ /* sd_memdata */ NULL,\
+ /* sd_data_flags */ 0,\
+ /* sd_freeme */ 0,\
+ /* sd_free_data */ 0,\
+ /* sd_magic */ DATA_MAGIC\
+}
+
+/*
+ * Private status variables
+ */
+extern unsigned _elf_version;
+extern int _elf_errno;
+extern int _elf_fill;
+extern int _elf_sanity_checks;
+#define SANITY_CHECK_STRPTR (1u << 0)
+
+/*
+ * Private functions
+ */
+extern void *_elf_read __P((Elf*, void*, size_t, size_t));
+extern void *_elf_mmap __P((Elf*));
+extern int _elf_cook __P((Elf*));
+extern char *_elf_getehdr __P((Elf*, unsigned));
+extern char *_elf_getphdr __P((Elf*, unsigned));
+extern Elf_Data *_elf_xlatetom __P((const Elf*, Elf_Data*, const Elf_Data*));
+extern Elf_Type _elf_scn_type __P((unsigned));
+extern size_t _elf32_xltsize __P((const Elf_Data *__src, unsigned __dv, unsigned __encode, int __tof));
+extern size_t _elf64_xltsize __P((const Elf_Data *__src, unsigned __dv, unsigned __encode, int __tof));
+extern int _elf_update_shnum(Elf *__elf, size_t __shnum);
+extern Elf_Scn *_elf_first_scn(Elf *__elf);
+
+/*
+ * Special translators
+ */
+extern size_t _elf_verdef_32L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verdef_32L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verdef_32M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verdef_32M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verdef_64L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verdef_64L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verdef_64M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verdef_64M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_32L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_32L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_32M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_32M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_64L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_64L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_64M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_64M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+
+/*
+ * Private data
+ */
+extern const Elf_Scn _elf_scn_init;
+extern const Scn_Data _elf_data_init;
+extern const size_t _elf_fmsize[2][EV_CURRENT - EV_NONE][ELF_T_NUM][2];
+
+/*
+ * Access macros for _elf_fmsize[]
+ */
+#define _fmsize(c,v,t,w) \
+ (_elf_fmsize[(c)-ELFCLASS32][(v)-EV_NONE-1][(t)-ELF_T_BYTE][(w)])
+#define _fsize(c,v,t) _fmsize((c),(v),(t),1)
+#define _msize(c,v,t) _fmsize((c),(v),(t),0)
+
+/*
+ * Various checks
+ */
+#define valid_class(c) ((c) >= ELFCLASS32 && (c) <= ELFCLASS64)
+#define valid_encoding(e) ((e) >= ELFDATA2LSB && (e) <= ELFDATA2MSB)
+#define valid_version(v) ((v) > EV_NONE && (v) <= EV_CURRENT)
+#define valid_type(t) ((unsigned)(t) < ELF_T_NUM)
+
+/*
+ * Error codes
+ */
+enum {
+#define __err__(a,b) a,
+#include <errors.h> /* include constants from errors.h */
+#undef __err__
+ERROR_NUM
+};
+
+#define seterr(err) (_elf_errno = (err))
+
+/*
+ * Sizes of data types (external representation)
+ * These definitions should be in <elf.h>, but...
+ */
+#ifndef ELF32_FSZ_ADDR
+# define ELF32_FSZ_ADDR 4
+# define ELF32_FSZ_HALF 2
+# define ELF32_FSZ_OFF 4
+# define ELF32_FSZ_SWORD 4
+# define ELF32_FSZ_WORD 4
+#endif /* ELF32_FSZ_ADDR */
+#ifndef ELF64_FSZ_ADDR
+# define ELF64_FSZ_ADDR 8
+# define ELF64_FSZ_HALF 2
+# define ELF64_FSZ_OFF 8
+# define ELF64_FSZ_SWORD 4
+# define ELF64_FSZ_SXWORD 8
+# define ELF64_FSZ_WORD 4
+# define ELF64_FSZ_XWORD 8
+#endif /* ELF64_FSZ_ADDR */
+
+/*
+ * More missing pieces, in no particular order
+ */
+#ifndef SHT_SYMTAB_SHNDX
+#define SHT_SYMTAB_SHNDX 18
+#endif /* SHT_SYMTAB_SHNDX */
+
+#ifndef SHN_XINDEX
+#define SHN_XINDEX 0xffff
+#endif /* SHN_XINDEX */
+
+#ifndef PN_XNUM
+#define PN_XNUM 0xffff
+#endif /* PN_XNUM */
+
+/*
+ * Debugging
+ */
+#if ENABLE_DEBUG
+extern void __elf_assert __P((const char*, unsigned, const char*));
+# if (__STDC__ + 0)
+# define elf_assert(x) do{if(!(x))__elf_assert(__FILE__,__LINE__,#x);}while(0)
+# else /* __STDC__ */
+# define elf_assert(x) do{if(!(x))__elf_assert(__FILE__,__LINE__,"x");}while(0)
+# endif /* __STDC__ */
+#else /* ENABLE_DEBUG */
+# define elf_assert(x) do{}while(0)
+#endif /* ENABLE_DEBUG */
+
+/*
+ * Return values for certain functions
+ */
+#define LIBELF_SUCCESS 1
+#define LIBELF_FAILURE 0
+
+#endif /* _PRIVATE_H */
diff --git a/lib/rand.c b/lib/rand.c
new file mode 100644
index 0000000..9cad126
--- /dev/null
+++ b/lib/rand.c
@@ -0,0 +1,43 @@
+/*
+rand.c - implementation of the elf_rand(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: rand.c,v 1.7 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+size_t
+elf_rand(Elf *elf, size_t offset) {
+ if (!elf) {
+ return 0;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (elf->e_kind != ELF_K_AR) {
+ seterr(ERROR_NOTARCHIVE);
+ }
+ else if (offset <= 0 || offset > elf->e_size) {
+ seterr(ERROR_BADOFF);
+ }
+ else {
+ elf->e_off = offset;
+ return offset;
+ }
+ return 0;
+}
diff --git a/lib/rawdata.c b/lib/rawdata.c
new file mode 100644
index 0000000..5d9a9f3
--- /dev/null
+++ b/lib/rawdata.c
@@ -0,0 +1,89 @@
+/*
+rawdata.c - implementation of the elf_rawdata(3) function.
+Copyright (C) 1995 - 2000 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: rawdata.c,v 1.10 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+Elf_Data*
+elf_rawdata(Elf_Scn *scn, Elf_Data *data) {
+ Scn_Data *sd;
+ Elf *elf;
+
+ if (!scn) {
+ return NULL;
+ }
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ elf = scn->s_elf;
+ elf_assert(elf);
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (!elf->e_readable) {
+ return NULL;
+ }
+ else if (scn->s_index == SHN_UNDEF || scn->s_type == SHT_NULL) {
+ seterr(ERROR_NULLSCN);
+ }
+ else if (data) {
+ return NULL;
+ }
+ else if ((sd = scn->s_rawdata)) {
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ elf_assert(sd->sd_scn == scn);
+ return &sd->sd_data;
+ }
+ else if (scn->s_offset < 0 || scn->s_offset > elf->e_size) {
+ seterr(ERROR_OUTSIDE);
+ }
+ else if (scn->s_type != SHT_NOBITS
+ && scn->s_offset + scn->s_size > elf->e_size) {
+ seterr(ERROR_TRUNC_SCN);
+ }
+ else if (!(sd = (Scn_Data*)malloc(sizeof(*sd)))) {
+ seterr(ERROR_MEM_SCNDATA);
+ }
+ else {
+ *sd = _elf_data_init;
+ sd->sd_scn = scn;
+ sd->sd_freeme = 1;
+ sd->sd_data.d_size = scn->s_size;
+ sd->sd_data.d_version = _elf_version;
+ if (scn->s_type != SHT_NOBITS && scn->s_size) {
+ if (!(sd->sd_memdata = (char*)malloc(scn->s_size))) {
+ seterr(ERROR_IO_2BIG);
+ free(sd);
+ return NULL;
+ }
+ else if (elf->e_rawdata) {
+ memcpy(sd->sd_memdata, elf->e_rawdata + scn->s_offset, scn->s_size);
+ }
+ else if (!_elf_read(elf, sd->sd_memdata, scn->s_offset, scn->s_size)) {
+ free(sd->sd_memdata);
+ free(sd);
+ return NULL;
+ }
+ sd->sd_data.d_buf = sd->sd_memdata;
+ sd->sd_free_data = 1;
+ }
+ scn->s_rawdata = sd;
+ return &sd->sd_data;
+ }
+ return NULL;
+}
diff --git a/lib/rawfile.c b/lib/rawfile.c
new file mode 100644
index 0000000..43335c4
--- /dev/null
+++ b/lib/rawfile.c
@@ -0,0 +1,54 @@
+/*
+ * rawfile.c - implementation of the elf_rawfile(3) function.
+ * Copyright (C) 1995 - 2009 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: rawfile.c,v 1.8 2009/05/22 17:07:46 michael Exp $";
+#endif /* lint */
+
+char*
+elf_rawfile(Elf *elf, size_t *ptr) {
+ size_t tmp;
+
+ if (!ptr) {
+ ptr = &tmp;
+ }
+ *ptr = 0;
+ if (!elf) {
+ return NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (!elf->e_readable) {
+ return NULL;
+ }
+ else if (elf->e_size) {
+ if (!elf->e_rawdata) {
+ elf_assert(elf->e_data);
+ if (!elf->e_cooked) {
+ elf->e_rawdata = elf->e_data;
+ }
+ else if (!(elf->e_rawdata = _elf_read(elf, NULL, 0, elf->e_size))) {
+ return NULL;
+ }
+ }
+ *ptr = elf->e_size;
+ }
+ return elf->e_rawdata;
+}
diff --git a/lib/strptr.c b/lib/strptr.c
new file mode 100644
index 0000000..30e217e
--- /dev/null
+++ b/lib/strptr.c
@@ -0,0 +1,150 @@
+/*
+ * strptr.c - implementation of the elf_strptr(3) function.
+ * Copyright (C) 1995 - 2007 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: strptr.c,v 1.12 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+char*
+elf_strptr(Elf *elf, size_t section, size_t offset) {
+ Elf_Data *data;
+ Elf_Scn *scn;
+ size_t n;
+ char *s;
+
+ if (!elf) {
+ return NULL;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (!(scn = elf_getscn(elf, section))) {
+ return NULL;
+ }
+ if (scn->s_index == SHN_UNDEF) {
+ seterr(ERROR_NOSTRTAB);
+ return NULL;
+ }
+ /*
+ * checking the section header is more appropriate
+ */
+ if (elf->e_class == ELFCLASS32) {
+ if (scn->s_shdr32.sh_type != SHT_STRTAB) {
+ seterr(ERROR_NOSTRTAB);
+ return NULL;
+ }
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ if (scn->s_shdr64.sh_type != SHT_STRTAB) {
+ seterr(ERROR_NOSTRTAB);
+ return NULL;
+ }
+ }
+#endif /* __LIBELF64 */
+ else if (valid_class(elf->e_class)) {
+ seterr(ERROR_UNIMPLEMENTED);
+ return NULL;
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ return NULL;
+ }
+ /*
+ * Find matching buffer
+ */
+ n = 0;
+ data = NULL;
+ if (elf->e_elf_flags & ELF_F_LAYOUT) {
+ /*
+ * Programmer is responsible for d_off
+ * Note: buffers may be in any order!
+ */
+ while ((data = elf_getdata(scn, data))) {
+ n = data->d_off;
+ if (offset >= n && offset - n < data->d_size) {
+ /*
+ * Found it
+ */
+ break;
+ }
+ }
+ }
+ else {
+ /*
+ * Calculate offsets myself
+ */
+ while ((data = elf_getdata(scn, data))) {
+ if (data->d_align > 1) {
+ n += data->d_align - 1;
+ n -= n % data->d_align;
+ }
+ if (offset < n) {
+ /*
+ * Invalid offset: points into a hole
+ */
+ seterr(ERROR_BADSTROFF);
+ return NULL;
+ }
+ if (offset - n < data->d_size) {
+ /*
+ * Found it
+ */
+ break;
+ }
+ n += data->d_size;
+ }
+ }
+ if (data == NULL) {
+ /*
+ * Not found
+ */
+ seterr(ERROR_BADSTROFF);
+ return NULL;
+ }
+ if (data->d_buf == NULL) {
+ /*
+ * Buffer is NULL (usually the programmers' fault)
+ */
+ seterr(ERROR_NULLBUF);
+ return NULL;
+ }
+ offset -= n;
+ s = (char*)data->d_buf;
+ if (!(_elf_sanity_checks & SANITY_CHECK_STRPTR)) {
+ return s + offset;
+ }
+ /*
+ * Perform extra sanity check
+ */
+ for (n = offset; n < data->d_size; n++) {
+ if (s[n] == '\0') {
+ /*
+ * Return properly NUL terminated string
+ */
+ return s + offset;
+ }
+ }
+ /*
+ * String is not NUL terminated
+ * Return error to avoid SEGV in application
+ */
+ seterr(ERROR_UNTERM);
+ return NULL;
+}
diff --git a/lib/swap64.c b/lib/swap64.c
new file mode 100644
index 0000000..397bd5b
--- /dev/null
+++ b/lib/swap64.c
@@ -0,0 +1,81 @@
+/*
+swap64.c - 64-bit byte swapping functions.
+Copyright (C) 1995 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+#include <byteswap.h>
+
+#if __LIBELF64
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: swap64.c,v 1.6 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+__libelf_u64_t
+_elf_load_u64L(const unsigned char *from) {
+ return ((__libelf_u64_t)__load_u32L(from + 4) << 32)
+ | (__libelf_u64_t)__load_u32L(from);
+}
+
+__libelf_u64_t
+_elf_load_u64M(const unsigned char *from) {
+ return ((__libelf_u64_t)__load_u32M(from) << 32)
+ | (__libelf_u64_t)__load_u32M(from + 4);
+}
+
+__libelf_i64_t
+_elf_load_i64L(const unsigned char *from) {
+ return ((__libelf_i64_t)__load_i32L(from + 4) << 32)
+ | (__libelf_u64_t)__load_u32L(from);
+}
+
+__libelf_i64_t
+_elf_load_i64M(const unsigned char *from) {
+ return ((__libelf_i64_t)__load_i32M(from) << 32)
+ | (__libelf_u64_t)__load_u32M(from + 4);
+}
+
+void
+_elf_store_u64L(unsigned char *to, __libelf_u64_t v) {
+ __store_u32L(to, (__libelf_u32_t)v);
+ v >>= 32;
+ __store_u32L(to + 4, (__libelf_u32_t)v);
+}
+
+void
+_elf_store_u64M(unsigned char *to, __libelf_u64_t v) {
+ __store_u32M(to + 4, (__libelf_u32_t)v);
+ v >>= 32;
+ __store_u32M(to, (__libelf_u32_t)v);
+}
+
+void
+_elf_store_i64L(unsigned char *to, __libelf_u64_t v) {
+ __store_u32L(to, (__libelf_u32_t)v);
+ v >>= 32;
+ __store_i32L(to + 4, (__libelf_u32_t)v);
+}
+
+void
+_elf_store_i64M(unsigned char *to, __libelf_u64_t v) {
+ __store_u32M(to + 4, (__libelf_u32_t)v);
+ v >>= 32;
+ __store_i32M(to, (__libelf_u32_t)v);
+}
+
+#endif /* __LIBELF64 */
diff --git a/lib/sys_elf.h.in b/lib/sys_elf.h.in
new file mode 100644
index 0000000..b71a20d
--- /dev/null
+++ b/lib/sys_elf.h.in
@@ -0,0 +1,130 @@
+/*
+sys_elf.h.in - configure template for private "switch" file.
+Copyright (C) 1998 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+/* @(#) $Id: sys_elf.h.in,v 1.13 2008/05/23 08:57:07 michael Exp $ */
+
+/*
+ * DO NOT USE THIS IN APPLICATIONS - #include <libelf.h> INSTEAD!
+ */
+
+/* Define to `<elf.h>' or `<sys/elf.h>' if one of them is present */
+#undef __LIBELF_HEADER_ELF_H
+
+/* Define if Elf32_Dyn is declared in <link.h> */
+#undef __LIBELF_NEED_LINK_H
+
+/* Define if Elf32_Dyn is declared in <sys/link.h> */
+#undef __LIBELF_NEED_SYS_LINK_H
+
+/* Define if you want 64-bit support (and your system supports it) */
+#undef __LIBELF64
+
+/* Define if you want 64-bit support, and are running IRIX */
+#undef __LIBELF64_IRIX
+
+/* Define if you want 64-bit support, and are running Linux */
+#undef __LIBELF64_LINUX
+
+/* Define if you want symbol versioning (and your system supports it) */
+#undef __LIBELF_SYMBOL_VERSIONS
+
+/* Define to a 64-bit signed integer type if one exists */
+#undef __libelf_i64_t
+
+/* Define to a 64-bit unsigned integer type if one exists */
+#undef __libelf_u64_t
+
+/* Define to a 32-bit signed integer type if one exists */
+#undef __libelf_i32_t
+
+/* Define to a 32-bit unsigned integer type if one exists */
+#undef __libelf_u32_t
+
+/* Define to a 16-bit signed integer type if one exists */
+#undef __libelf_i16_t
+
+/* Define to a 16-bit unsigned integer type if one exists */
+#undef __libelf_u16_t
+
+/*
+ * Ok, now get the correct instance of elf.h...
+ */
+#ifdef __LIBELF_HEADER_ELF_H
+# include __LIBELF_HEADER_ELF_H
+#else /* __LIBELF_HEADER_ELF_H */
+# if __LIBELF_INTERNAL__
+# include <elf_repl.h>
+# else /* __LIBELF_INTERNAL__ */
+# include <libelf/elf_repl.h>
+# endif /* __LIBELF_INTERNAL__ */
+#endif /* __LIBELF_HEADER_ELF_H */
+
+/*
+ * On some systems, <elf.h> is severely broken. Try to fix it.
+ */
+#ifdef __LIBELF_HEADER_ELF_H
+
+# ifndef ELF32_FSZ_ADDR
+# define ELF32_FSZ_ADDR 4
+# define ELF32_FSZ_HALF 2
+# define ELF32_FSZ_OFF 4
+# define ELF32_FSZ_SWORD 4
+# define ELF32_FSZ_WORD 4
+# endif /* ELF32_FSZ_ADDR */
+
+# ifndef STN_UNDEF
+# define STN_UNDEF 0
+# endif /* STN_UNDEF */
+
+# if __LIBELF64
+
+# ifndef ELF64_FSZ_ADDR
+# define ELF64_FSZ_ADDR 8
+# define ELF64_FSZ_HALF 2
+# define ELF64_FSZ_OFF 8
+# define ELF64_FSZ_SWORD 4
+# define ELF64_FSZ_WORD 4
+# define ELF64_FSZ_SXWORD 8
+# define ELF64_FSZ_XWORD 8
+# endif /* ELF64_FSZ_ADDR */
+
+# ifndef ELF64_ST_BIND
+# define ELF64_ST_BIND(i) ((i)>>4)
+# define ELF64_ST_TYPE(i) ((i)&0xf)
+# define ELF64_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
+# endif /* ELF64_ST_BIND */
+
+# ifndef ELF64_R_SYM
+# define ELF64_R_SYM(i) ((Elf64_Xword)(i)>>32)
+# define ELF64_R_TYPE(i) ((i)&0xffffffffL)
+# define ELF64_R_INFO(s,t) (((Elf64_Xword)(s)<<32)+((t)&0xffffffffL))
+# endif /* ELF64_R_SYM */
+
+# if __LIBELF64_LINUX
+typedef __libelf_u64_t Elf64_Addr;
+typedef __libelf_u16_t Elf64_Half;
+typedef __libelf_u64_t Elf64_Off;
+typedef __libelf_i32_t Elf64_Sword;
+typedef __libelf_u32_t Elf64_Word;
+typedef __libelf_i64_t Elf64_Sxword;
+typedef __libelf_u64_t Elf64_Xword;
+# endif /* __LIBELF64_LINUX */
+
+# endif /* __LIBELF64 */
+#endif /* __LIBELF_HEADER_ELF_H */
diff --git a/lib/sys_elf.h.w32 b/lib/sys_elf.h.w32
new file mode 100644
index 0000000..0f93c55
--- /dev/null
+++ b/lib/sys_elf.h.w32
@@ -0,0 +1,130 @@
+/*
+ * lib/sys_elf.h.w32 - internal configuration file for W32 port
+ * Copyright (C) 2004 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * @(#) $Id: sys_elf.h.w32,v 1.2 2006/09/07 15:55:42 michael Exp $
+ */
+
+/*
+ * DO NOT USE THIS IN APPLICATIONS - #include <libelf.h> INSTEAD!
+ */
+
+/* Define to `<elf.h>' or `<sys/elf.h>' if one of them is present */
+#undef __LIBELF_HEADER_ELF_H
+
+/* Define if Elf32_Dyn is declared in <link.h> */
+#undef __LIBELF_NEED_LINK_H
+
+/* Define if Elf32_Dyn is declared in <sys/link.h> */
+#undef __LIBELF_NEED_SYS_LINK_H
+
+/* Define if you want 64-bit support (and your system supports it) */
+#define __LIBELF64 1
+
+/* Define if you want 64-bit support, and are running IRIX */
+#undef __LIBELF64_IRIX
+
+/* Define if you want 64-bit support, and are running Linux */
+#undef __LIBELF64_LINUX
+
+/* Define if you want symbol versioning (and your system supports it) */
+#define __LIBELF_SYMBOL_VERSIONS 1
+
+/* Define to a 64-bit signed integer type if one exists */
+#define __libelf_i64_t __int64
+
+/* Define to a 64-bit unsigned integer type if one exists */
+#define __libelf_u64_t unsigned __int64
+
+/* Define to a 32-bit signed integer type if one exists */
+#define __libelf_i32_t int
+
+/* Define to a 32-bit unsigned integer type if one exists */
+#define __libelf_u32_t unsigned int
+
+/* Define to a 16-bit signed integer type if one exists */
+#define __libelf_i16_t short int
+
+/* Define to a 16-bit unsigned integer type if one exists */
+#define __libelf_u16_t unsigned short int
+
+/*
+ * Ok, now get the correct instance of elf.h...
+ */
+#ifdef __LIBELF_HEADER_ELF_H
+# include __LIBELF_HEADER_ELF_H
+#else /* __LIBELF_HEADER_ELF_H */
+# if __LIBELF_INTERNAL__
+# include <elf_repl.h>
+# else /* __LIBELF_INTERNAL__ */
+# include <libelf/elf_repl.h>
+# endif /* __LIBELF_INTERNAL__ */
+#endif /* __LIBELF_HEADER_ELF_H */
+
+/*
+ * On some systems, <elf.h> is severely broken. Try to fix it.
+ */
+#ifdef __LIBELF_HEADER_ELF_H
+
+# ifndef ELF32_FSZ_ADDR
+# define ELF32_FSZ_ADDR 4
+# define ELF32_FSZ_HALF 2
+# define ELF32_FSZ_OFF 4
+# define ELF32_FSZ_SWORD 4
+# define ELF32_FSZ_WORD 4
+# endif /* ELF32_FSZ_ADDR */
+
+# ifndef STN_UNDEF
+# define STN_UNDEF 0
+# endif /* STN_UNDEF */
+
+# if __LIBELF64
+
+# ifndef ELF64_FSZ_ADDR
+# define ELF64_FSZ_ADDR 8
+# define ELF64_FSZ_HALF 2
+# define ELF64_FSZ_OFF 8
+# define ELF64_FSZ_SWORD 4
+# define ELF64_FSZ_WORD 4
+# define ELF64_FSZ_SXWORD 8
+# define ELF64_FSZ_XWORD 8
+# endif /* ELF64_FSZ_ADDR */
+
+# ifndef ELF64_ST_BIND
+# define ELF64_ST_BIND(i) ((i)>>4)
+# define ELF64_ST_TYPE(i) ((i)&0xf)
+# define ELF64_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
+# endif /* ELF64_ST_BIND */
+
+# ifndef ELF64_R_SYM
+# define ELF64_R_SYM(i) ((Elf64_Xword)(i)>>32)
+# define ELF64_R_TYPE(i) ((i)&0xffffffffL)
+# define ELF64_R_INFO(s,t) (((Elf64_Xword)(s)<<32)+((t)&0xffffffffL))
+# endif /* ELF64_R_SYM */
+
+# if __LIBELF64_LINUX
+typedef __libelf_u64_t Elf64_Addr;
+typedef __libelf_u16_t Elf64_Half;
+typedef __libelf_u64_t Elf64_Off;
+typedef __libelf_i32_t Elf64_Sword;
+typedef __libelf_u32_t Elf64_Word;
+typedef __libelf_i64_t Elf64_Sxword;
+typedef __libelf_u64_t Elf64_Xword;
+# endif /* __LIBELF64_LINUX */
+
+# endif /* __LIBELF64 */
+#endif /* __LIBELF_HEADER_ELF_H */
diff --git a/lib/update.c b/lib/update.c
new file mode 100644
index 0000000..085ddea
--- /dev/null
+++ b/lib/update.c
@@ -0,0 +1,1021 @@
+/*
+ * update.c - implementation of the elf_update(3) function.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: update.c,v 1.34 2009/05/22 17:08:09 michael Exp $";
+#endif /* lint */
+
+#include <errno.h>
+
+#if HAVE_MMAP
+#include <sys/mman.h>
+#endif /* HAVE_MMAP */
+
+static const unsigned short __encoding = ELFDATA2LSB + (ELFDATA2MSB << 8);
+#define native_encoding (*(unsigned char*)&__encoding)
+
+#define rewrite(var,val,f) \
+ do{if((var)!=(val)){(var)=(val);(f)|=ELF_F_DIRTY;}}while(0)
+
+#define align(var,val) \
+ do{if((val)>1){(var)+=(val)-1;(var)-=(var)%(val);}}while(0)
+
+#undef max
+#define max(a,b) ((a)>(b)?(a):(b))
+
+static off_t
+scn_data_layout(Elf_Scn *scn, unsigned v, unsigned type, size_t *algn, unsigned *flag) {
+ Elf *elf = scn->s_elf;
+ Elf_Data *data;
+ int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0;
+ size_t scn_align = 1;
+ size_t len = 0;
+ Scn_Data *sd;
+ size_t fsize;
+
+ if (!(sd = scn->s_data_1)) {
+ /* no data in section */
+ *algn = scn_align;
+ return (off_t)len;
+ }
+ /* load data from file, if any */
+ if (!(data = elf_getdata(scn, NULL))) {
+ return (off_t)-1;
+ }
+ elf_assert(data == &sd->sd_data);
+ for (; sd; sd = sd->sd_link) {
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ elf_assert(sd->sd_scn == scn);
+
+ if (!valid_version(sd->sd_data.d_version)) {
+ return (off_t)-1;
+ }
+
+ fsize = sd->sd_data.d_size;
+ if (fsize && type != SHT_NOBITS && valid_type(sd->sd_data.d_type)) {
+ if (elf->e_class == ELFCLASS32) {
+ fsize = _elf32_xltsize(&sd->sd_data, v, ELFDATA2LSB, 1);
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ fsize = _elf64_xltsize(&sd->sd_data, v, ELFDATA2LSB, 1);
+ }
+#endif /* __LIBELF64 */
+ else {
+ elf_assert(valid_class(elf->e_class));
+ seterr(ERROR_UNIMPLEMENTED);
+ return (off_t)-1;
+ }
+ if (fsize == (size_t)-1) {
+ return (off_t)-1;
+ }
+ }
+
+ if (layout) {
+ align(len, sd->sd_data.d_align);
+ scn_align = max(scn_align, sd->sd_data.d_align);
+ rewrite(sd->sd_data.d_off, (off_t)len, sd->sd_data_flags);
+ len += fsize;
+ }
+ else {
+ len = max(len, sd->sd_data.d_off + fsize);
+ }
+
+ *flag |= sd->sd_data_flags;
+ }
+ *algn = scn_align;
+ return (off_t)len;
+}
+
+static size_t
+scn_entsize(const Elf *elf, unsigned version, unsigned stype) {
+ Elf_Type type;
+
+ switch ((type = _elf_scn_type(stype))) {
+ case ELF_T_BYTE:
+ return 0;
+ case ELF_T_VDEF:
+ case ELF_T_VNEED:
+ return 0; /* What else can I do? Thank you, Sun! */
+ default:
+ return _fsize(elf->e_class, version, type);
+ }
+}
+
+static off_t
+_elf32_layout(Elf *elf, unsigned *flag) {
+ int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0;
+ int allow_overlap = (elf->e_elf_flags & ELF_F_LAYOUT_OVERLAP) != 0;
+ Elf32_Ehdr *ehdr = (Elf32_Ehdr*)elf->e_ehdr;
+ size_t off = 0;
+ unsigned version;
+ unsigned encoding;
+ size_t align_addr;
+ size_t entsize;
+ unsigned phnum;
+ unsigned shnum;
+ Elf_Scn *scn;
+
+ *flag = elf->e_elf_flags | elf->e_phdr_flags;
+
+ if ((version = ehdr->e_version) == EV_NONE) {
+ version = EV_CURRENT;
+ }
+ if (!valid_version(version)) {
+ seterr(ERROR_UNKNOWN_VERSION);
+ return -1;
+ }
+ if ((encoding = ehdr->e_ident[EI_DATA]) == ELFDATANONE) {
+ encoding = native_encoding;
+ }
+ if (!valid_encoding(encoding)) {
+ seterr(ERROR_UNKNOWN_ENCODING);
+ return -1;
+ }
+ entsize = _fsize(ELFCLASS32, version, ELF_T_EHDR);
+ elf_assert(entsize);
+ rewrite(ehdr->e_ehsize, entsize, elf->e_ehdr_flags);
+ off = entsize;
+
+ align_addr = _fsize(ELFCLASS32, version, ELF_T_ADDR);
+ elf_assert(align_addr);
+
+ if ((phnum = elf->e_phnum)) {
+ entsize = _fsize(ELFCLASS32, version, ELF_T_PHDR);
+ elf_assert(entsize);
+ if (layout) {
+ align(off, align_addr);
+ rewrite(ehdr->e_phoff, off, elf->e_ehdr_flags);
+ off += phnum * entsize;
+ }
+ else {
+ off = max(off, ehdr->e_phoff + phnum * entsize);
+ }
+ }
+ else {
+ entsize = 0;
+ if (layout) {
+ rewrite(ehdr->e_phoff, 0, elf->e_ehdr_flags);
+ }
+ }
+ if (phnum >= PN_XNUM) {
+ Elf_Scn *scn = elf->e_scn_1;
+ Elf32_Shdr *shdr = &scn->s_shdr32;
+
+ elf_assert(scn);
+ elf_assert(scn->s_index == 0);
+ rewrite(shdr->sh_info, phnum, scn->s_shdr_flags);
+ *flag |= scn->s_shdr_flags;
+ phnum = PN_XNUM;
+ }
+ rewrite(ehdr->e_phnum, phnum, elf->e_ehdr_flags);
+ rewrite(ehdr->e_phentsize, entsize, elf->e_ehdr_flags);
+
+ for (scn = elf->e_scn_1, shnum = 0; scn; scn = scn->s_link, ++shnum) {
+ Elf32_Shdr *shdr = &scn->s_shdr32;
+ size_t scn_align = 1;
+ off_t len;
+
+ elf_assert(scn->s_index == shnum);
+
+ *flag |= scn->s_scn_flags;
+
+ if (scn->s_index == SHN_UNDEF) {
+ rewrite(shdr->sh_entsize, 0, scn->s_shdr_flags);
+ if (layout) {
+ rewrite(shdr->sh_offset, 0, scn->s_shdr_flags);
+ rewrite(shdr->sh_size, 0, scn->s_shdr_flags);
+ rewrite(shdr->sh_addralign, 0, scn->s_shdr_flags);
+ }
+ *flag |= scn->s_shdr_flags;
+ continue;
+ }
+ if (shdr->sh_type == SHT_NULL) {
+ *flag |= scn->s_shdr_flags;
+ continue;
+ }
+
+ len = scn_data_layout(scn, version, shdr->sh_type, &scn_align, flag);
+ if (len == -1) {
+ return -1;
+ }
+
+ /*
+ * Never override the program's choice.
+ */
+ if (shdr->sh_entsize == 0) {
+ entsize = scn_entsize(elf, version, shdr->sh_type);
+ if (entsize > 1) {
+ rewrite(shdr->sh_entsize, entsize, scn->s_shdr_flags);
+ }
+ }
+
+ if (layout) {
+ align(off, scn_align);
+ rewrite(shdr->sh_offset, off, scn->s_shdr_flags);
+ rewrite(shdr->sh_size, (size_t)len, scn->s_shdr_flags);
+ rewrite(shdr->sh_addralign, scn_align, scn->s_shdr_flags);
+
+ if (shdr->sh_type != SHT_NOBITS) {
+ off += (size_t)len;
+ }
+ }
+ else if ((size_t)len > shdr->sh_size) {
+ seterr(ERROR_SCN2SMALL);
+ return -1;
+ }
+ else {
+ Elf_Scn *scn2;
+ size_t end1, end2;
+
+ end1 = shdr->sh_offset;
+ if (shdr->sh_type != SHT_NOBITS) {
+ end1 += shdr->sh_size;
+ }
+ if (!allow_overlap && shdr->sh_offset < off) {
+ /*
+ * check for overlapping sections
+ */
+ for (scn2 = elf->e_scn_1; scn2; scn2 = scn2->s_link) {
+ if (scn2 == scn) {
+ break;
+ }
+ end2 = scn2->s_shdr32.sh_offset;
+ if (scn2->s_shdr32.sh_type != SHT_NOBITS) {
+ end2 += scn2->s_shdr32.sh_size;
+ }
+ if (end1 > scn2->s_shdr32.sh_offset
+ && end2 > shdr->sh_offset) {
+ seterr(ERROR_SCN_OVERLAP);
+ return -1;
+ }
+ }
+ }
+ if (off < end1) {
+ off = end1;
+ }
+ }
+ *flag |= scn->s_shdr_flags;
+ }
+
+ if (shnum) {
+ entsize = _fsize(ELFCLASS32, version, ELF_T_SHDR);
+ elf_assert(entsize);
+ if (layout) {
+ align(off, align_addr);
+ rewrite(ehdr->e_shoff, off, elf->e_ehdr_flags);
+ off += shnum * entsize;
+ }
+ else {
+ off = max(off, ehdr->e_shoff + shnum * entsize);
+ }
+ }
+ else {
+ entsize = 0;
+ if (layout) {
+ rewrite(ehdr->e_shoff, 0, elf->e_ehdr_flags);
+ }
+ }
+ if (shnum >= SHN_LORESERVE) {
+ Elf_Scn *scn = elf->e_scn_1;
+ Elf32_Shdr *shdr = &scn->s_shdr32;
+
+ elf_assert(scn->s_index == 0);
+ rewrite(shdr->sh_size, shnum, scn->s_shdr_flags);
+ *flag |= scn->s_shdr_flags;
+ shnum = 0;
+ }
+ rewrite(ehdr->e_shnum, shnum, elf->e_ehdr_flags);
+ rewrite(ehdr->e_shentsize, entsize, elf->e_ehdr_flags);
+
+ rewrite(ehdr->e_ident[EI_MAG0], ELFMAG0, elf->e_ehdr_flags);
+ rewrite(ehdr->e_ident[EI_MAG1], ELFMAG1, elf->e_ehdr_flags);
+ rewrite(ehdr->e_ident[EI_MAG2], ELFMAG2, elf->e_ehdr_flags);
+ rewrite(ehdr->e_ident[EI_MAG3], ELFMAG3, elf->e_ehdr_flags);
+ rewrite(ehdr->e_ident[EI_CLASS], ELFCLASS32, elf->e_ehdr_flags);
+ rewrite(ehdr->e_ident[EI_DATA], encoding, elf->e_ehdr_flags);
+ rewrite(ehdr->e_ident[EI_VERSION], version, elf->e_ehdr_flags);
+ rewrite(ehdr->e_version, version, elf->e_ehdr_flags);
+
+ *flag |= elf->e_ehdr_flags;
+
+ return off;
+}
+
+#if __LIBELF64
+
+static off_t
+_elf64_layout(Elf *elf, unsigned *flag) {
+ int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0;
+ int allow_overlap = (elf->e_elf_flags & ELF_F_LAYOUT_OVERLAP) != 0;
+ Elf64_Ehdr *ehdr = (Elf64_Ehdr*)elf->e_ehdr;
+ size_t off = 0;
+ unsigned version;
+ unsigned encoding;
+ size_t align_addr;
+ size_t entsize;
+ unsigned phnum;
+ unsigned shnum;
+ Elf_Scn *scn;
+
+ *flag = elf->e_elf_flags | elf->e_phdr_flags;
+
+ if ((version = ehdr->e_version) == EV_NONE) {
+ version = EV_CURRENT;
+ }
+ if (!valid_version(version)) {
+ seterr(ERROR_UNKNOWN_VERSION);
+ return -1;
+ }
+ if ((encoding = ehdr->e_ident[EI_DATA]) == ELFDATANONE) {
+ encoding = native_encoding;
+ }
+ if (!valid_encoding(encoding)) {
+ seterr(ERROR_UNKNOWN_ENCODING);
+ return -1;
+ }
+ entsize = _fsize(ELFCLASS64, version, ELF_T_EHDR);
+ elf_assert(entsize);
+ rewrite(ehdr->e_ehsize, entsize, elf->e_ehdr_flags);
+ off = entsize;
+
+ align_addr = _fsize(ELFCLASS64, version, ELF_T_ADDR);
+ elf_assert(align_addr);
+
+ if ((phnum = elf->e_phnum)) {
+ entsize = _fsize(ELFCLASS64, version, ELF_T_PHDR);
+ elf_assert(entsize);
+ if (layout) {
+ align(off, align_addr);
+ rewrite(ehdr->e_phoff, off, elf->e_ehdr_flags);
+ off += phnum * entsize;
+ }
+ else {
+ off = max(off, ehdr->e_phoff + phnum * entsize);
+ }
+ }
+ else {
+ entsize = 0;
+ if (layout) {
+ rewrite(ehdr->e_phoff, 0, elf->e_ehdr_flags);
+ }
+ }
+ if (phnum >= PN_XNUM) {
+ Elf_Scn *scn = elf->e_scn_1;
+ Elf32_Shdr *shdr = &scn->s_shdr32;
+
+ /* modify first section header, too! */
+ elf_assert(scn);
+ elf_assert(scn->s_index == 0);
+ rewrite(shdr->sh_info, phnum, scn->s_shdr_flags);
+ *flag |= scn->s_shdr_flags;
+ phnum = PN_XNUM;
+ }
+ rewrite(ehdr->e_phnum, phnum, elf->e_ehdr_flags);
+ rewrite(ehdr->e_phentsize, entsize, elf->e_ehdr_flags);
+
+ for (scn = elf->e_scn_1, shnum = 0; scn; scn = scn->s_link, ++shnum) {
+ Elf64_Shdr *shdr = &scn->s_shdr64;
+ size_t scn_align = 1;
+ off_t len;
+
+ elf_assert(scn->s_index == shnum);
+
+ *flag |= scn->s_scn_flags;
+
+ if (scn->s_index == SHN_UNDEF) {
+ rewrite(shdr->sh_entsize, 0, scn->s_shdr_flags);
+ if (layout) {
+ rewrite(shdr->sh_offset, 0, scn->s_shdr_flags);
+ rewrite(shdr->sh_size, 0, scn->s_shdr_flags);
+ rewrite(shdr->sh_addralign, 0, scn->s_shdr_flags);
+ }
+ *flag |= scn->s_shdr_flags;
+ continue;
+ }
+ if (shdr->sh_type == SHT_NULL) {
+ *flag |= scn->s_shdr_flags;
+ continue;
+ }
+
+ len = scn_data_layout(scn, version, shdr->sh_type, &scn_align, flag);
+ if (len == -1) {
+ return -1;
+ }
+
+ /*
+ * Never override the program's choice.
+ */
+ if (shdr->sh_entsize == 0) {
+ entsize = scn_entsize(elf, version, shdr->sh_type);
+ if (entsize > 1) {
+ rewrite(shdr->sh_entsize, entsize, scn->s_shdr_flags);
+ }
+ }
+
+ if (layout) {
+ align(off, scn_align);
+ rewrite(shdr->sh_offset, off, scn->s_shdr_flags);
+ rewrite(shdr->sh_size, (size_t)len, scn->s_shdr_flags);
+ rewrite(shdr->sh_addralign, scn_align, scn->s_shdr_flags);
+
+ if (shdr->sh_type != SHT_NOBITS) {
+ off += (size_t)len;
+ }
+ }
+ else if ((size_t)len > shdr->sh_size) {
+ seterr(ERROR_SCN2SMALL);
+ return -1;
+ }
+ else {
+ Elf_Scn *scn2;
+ size_t end1, end2;
+
+ end1 = shdr->sh_offset;
+ if (shdr->sh_type != SHT_NOBITS) {
+ end1 += shdr->sh_size;
+ }
+ if (!allow_overlap && shdr->sh_offset < off) {
+ /*
+ * check for overlapping sections
+ */
+ for (scn2 = elf->e_scn_1; scn2; scn2 = scn2->s_link) {
+ if (scn2 == scn) {
+ break;
+ }
+ end2 = scn2->s_shdr64.sh_offset;
+ if (scn2->s_shdr64.sh_type != SHT_NOBITS) {
+ end2 += scn2->s_shdr64.sh_size;
+ }
+ if (end1 > scn2->s_shdr64.sh_offset
+ && end2 > shdr->sh_offset) {
+ seterr(ERROR_SCN_OVERLAP);
+ return -1;
+ }
+ }
+ }
+ if (off < end1) {
+ off = end1;
+ }
+ }
+ *flag |= scn->s_shdr_flags;
+ }
+
+ if (shnum) {
+ entsize = _fsize(ELFCLASS64, version, ELF_T_SHDR);
+ elf_assert(entsize);
+ if (layout) {
+ align(off, align_addr);
+ rewrite(ehdr->e_shoff, off, elf->e_ehdr_flags);
+ off += shnum * entsize;
+ }
+ else {
+ off = max(off, ehdr->e_shoff + shnum * entsize);
+ }
+ }
+ else {
+ entsize = 0;
+ if (layout) {
+ rewrite(ehdr->e_shoff, 0, elf->e_ehdr_flags);
+ }
+ }
+ if (shnum >= SHN_LORESERVE) {
+ Elf_Scn *scn = elf->e_scn_1;
+ Elf64_Shdr *shdr = &scn->s_shdr64;
+
+ elf_assert(scn->s_index == 0);
+ rewrite(shdr->sh_size, shnum, scn->s_shdr_flags);
+ *flag |= scn->s_shdr_flags;
+ shnum = 0;
+ }
+ rewrite(ehdr->e_shnum, shnum, elf->e_ehdr_flags);
+ rewrite(ehdr->e_shentsize, entsize, elf->e_ehdr_flags);
+
+ rewrite(ehdr->e_ident[EI_MAG0], ELFMAG0, elf->e_ehdr_flags);
+ rewrite(ehdr->e_ident[EI_MAG1], ELFMAG1, elf->e_ehdr_flags);
+ rewrite(ehdr->e_ident[EI_MAG2], ELFMAG2, elf->e_ehdr_flags);
+ rewrite(ehdr->e_ident[EI_MAG3], ELFMAG3, elf->e_ehdr_flags);
+ rewrite(ehdr->e_ident[EI_CLASS], ELFCLASS64, elf->e_ehdr_flags);
+ rewrite(ehdr->e_ident[EI_DATA], encoding, elf->e_ehdr_flags);
+ rewrite(ehdr->e_ident[EI_VERSION], version, elf->e_ehdr_flags);
+ rewrite(ehdr->e_version, version, elf->e_ehdr_flags);
+
+ *flag |= elf->e_ehdr_flags;
+
+ return off;
+}
+
+#endif /* __LIBELF64 */
+
+#define ptrinside(p,a,l) ((p)>=(a)&&(p)<(a)+(l))
+#define newptr(p,o,n) ((p)=((p)-(o))+(n))
+
+static int
+_elf_update_pointers(Elf *elf, char *outbuf, size_t len) {
+ Elf_Scn *scn;
+ Scn_Data *sd;
+ char *data, *rawdata;
+
+ elf_assert(elf);
+ elf_assert(elf->e_data);
+ elf_assert(!elf->e_parent);
+ elf_assert(!elf->e_unmap_data);
+ elf_assert(elf->e_kind == ELF_K_ELF);
+ elf_assert(len >= EI_NIDENT);
+
+ /* resize memory images */
+ if (len <= elf->e_dsize) {
+ /* don't shorten the memory image */
+ data = elf->e_data;
+ }
+ else if ((data = (char*)realloc(elf->e_data, len))) {
+ elf->e_dsize = len;
+ }
+ else {
+ seterr(ERROR_IO_2BIG);
+ return -1;
+ }
+ if (elf->e_rawdata == elf->e_data) {
+ /* update frozen raw image */
+ memcpy(data, outbuf, len);
+ elf->e_data = elf->e_rawdata = data;
+ /* cooked data is stored outside the raw image */
+ return 0;
+ }
+ if (elf->e_rawdata) {
+ /* update raw image */
+ if (!(rawdata = (char*)realloc(elf->e_rawdata, len))) {
+ seterr(ERROR_IO_2BIG);
+ return -1;
+ }
+ memcpy(rawdata, outbuf, len);
+ elf->e_rawdata = rawdata;
+ }
+ if (data == elf->e_data) {
+ /* nothing more to do */
+ return 0;
+ }
+ /* adjust internal pointers */
+ for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ elf_assert(scn->s_elf == elf);
+ if ((sd = scn->s_data_1)) {
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ elf_assert(sd->sd_scn == scn);
+ if (sd->sd_memdata && !sd->sd_free_data) {
+ elf_assert(ptrinside(sd->sd_memdata, elf->e_data, elf->e_dsize));
+ if (sd->sd_data.d_buf == sd->sd_memdata) {
+ newptr(sd->sd_memdata, elf->e_data, data);
+ sd->sd_data.d_buf = sd->sd_memdata;
+ }
+ else {
+ newptr(sd->sd_memdata, elf->e_data, data);
+ }
+ }
+ }
+ if ((sd = scn->s_rawdata)) {
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ elf_assert(sd->sd_scn == scn);
+ if (sd->sd_memdata && sd->sd_free_data) {
+ size_t off, len;
+
+ if (elf->e_class == ELFCLASS32) {
+ off = scn->s_shdr32.sh_offset;
+ len = scn->s_shdr32.sh_size;
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ off = scn->s_shdr64.sh_offset;
+ len = scn->s_shdr64.sh_size;
+ }
+#endif /* __LIBELF64 */
+ else {
+ seterr(ERROR_UNIMPLEMENTED);
+ return -1;
+ }
+ if (!(rawdata = (char*)realloc(sd->sd_memdata, len))) {
+ seterr(ERROR_IO_2BIG);
+ return -1;
+ }
+ memcpy(rawdata, outbuf + off, len);
+ if (sd->sd_data.d_buf == sd->sd_memdata) {
+ sd->sd_data.d_buf = rawdata;
+ }
+ sd->sd_memdata = rawdata;
+ }
+ }
+ }
+ elf->e_data = data;
+ return 0;
+}
+
+#undef ptrinside
+#undef newptr
+
+static off_t
+_elf32_write(Elf *elf, char *outbuf, size_t len) {
+ Elf32_Ehdr *ehdr;
+ Elf32_Shdr *shdr;
+ Elf_Scn *scn;
+ Scn_Data *sd;
+ Elf_Data src;
+ Elf_Data dst;
+ unsigned encode;
+
+ elf_assert(len);
+ elf_assert(elf->e_ehdr);
+ ehdr = (Elf32_Ehdr*)elf->e_ehdr;
+ encode = ehdr->e_ident[EI_DATA];
+
+ src.d_buf = ehdr;
+ src.d_type = ELF_T_EHDR;
+ src.d_size = _msize(ELFCLASS32, _elf_version, ELF_T_EHDR);
+ src.d_version = _elf_version;
+ dst.d_buf = outbuf;
+ dst.d_size = ehdr->e_ehsize;
+ dst.d_version = ehdr->e_version;
+ if (!elf32_xlatetof(&dst, &src, encode)) {
+ return -1;
+ }
+
+ if (elf->e_phnum) {
+ src.d_buf = elf->e_phdr;
+ src.d_type = ELF_T_PHDR;
+ src.d_size = elf->e_phnum * _msize(ELFCLASS32, _elf_version, ELF_T_PHDR);
+ src.d_version = _elf_version;
+ dst.d_buf = outbuf + ehdr->e_phoff;
+ dst.d_size = elf->e_phnum * ehdr->e_phentsize;
+ dst.d_version = ehdr->e_version;
+ if (!elf32_xlatetof(&dst, &src, encode)) {
+ return -1;
+ }
+ }
+
+ for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ elf_assert(scn->s_elf == elf);
+
+ src.d_buf = &scn->s_uhdr;
+ src.d_type = ELF_T_SHDR;
+ src.d_size = _msize(ELFCLASS32, EV_CURRENT, ELF_T_SHDR);
+ src.d_version = EV_CURRENT;
+ dst.d_buf = outbuf + ehdr->e_shoff + scn->s_index * ehdr->e_shentsize;
+ dst.d_size = ehdr->e_shentsize;
+ dst.d_version = ehdr->e_version;
+ if (!elf32_xlatetof(&dst, &src, encode)) {
+ return -1;
+ }
+
+ if (scn->s_index == SHN_UNDEF) {
+ continue;
+ }
+ shdr = &scn->s_shdr32;
+ if (shdr->sh_type == SHT_NULL || shdr->sh_type == SHT_NOBITS) {
+ continue;
+ }
+ /* XXX: this is probably no longer necessary */
+ if (scn->s_data_1 && !elf_getdata(scn, NULL)) {
+ return -1;
+ }
+ for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ elf_assert(sd->sd_scn == scn);
+ src = sd->sd_data;
+ if (!src.d_size) {
+ continue;
+ }
+ if (!src.d_buf) {
+ seterr(ERROR_NULLBUF);
+ return -1;
+ }
+ dst.d_buf = outbuf + shdr->sh_offset + src.d_off;
+ dst.d_size = src.d_size;
+ dst.d_version = ehdr->e_version;
+ if (valid_type(src.d_type)) {
+ size_t tmp;
+
+ tmp = _elf32_xltsize(&src, dst.d_version, ELFDATA2LSB, 1);
+ if (tmp == (size_t)-1) {
+ return -1;
+ }
+ dst.d_size = tmp;
+ }
+ else {
+ src.d_type = ELF_T_BYTE;
+ }
+ if (!elf32_xlatetof(&dst, &src, encode)) {
+ return -1;
+ }
+ }
+ }
+
+ /* cleanup */
+ if (elf->e_readable && _elf_update_pointers(elf, outbuf, len)) {
+ return -1;
+ }
+ /* NOTE: ehdr is no longer valid! */
+ ehdr = (Elf32_Ehdr*)elf->e_ehdr; elf_assert(ehdr);
+ elf->e_encoding = ehdr->e_ident[EI_DATA];
+ elf->e_version = ehdr->e_ident[EI_VERSION];
+ elf->e_elf_flags &= ~ELF_F_DIRTY;
+ elf->e_ehdr_flags &= ~ELF_F_DIRTY;
+ elf->e_phdr_flags &= ~ELF_F_DIRTY;
+ for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+ scn->s_scn_flags &= ~ELF_F_DIRTY;
+ scn->s_shdr_flags &= ~ELF_F_DIRTY;
+ for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
+ sd->sd_data_flags &= ~ELF_F_DIRTY;
+ }
+ if (elf->e_readable) {
+ shdr = &scn->s_shdr32;
+ scn->s_type = shdr->sh_type;
+ scn->s_size = shdr->sh_size;
+ scn->s_offset = shdr->sh_offset;
+ }
+ }
+ elf->e_size = len;
+ return len;
+}
+
+#if __LIBELF64
+
+static off_t
+_elf64_write(Elf *elf, char *outbuf, size_t len) {
+ Elf64_Ehdr *ehdr;
+ Elf64_Shdr *shdr;
+ Elf_Scn *scn;
+ Scn_Data *sd;
+ Elf_Data src;
+ Elf_Data dst;
+ unsigned encode;
+
+ elf_assert(len);
+ elf_assert(elf->e_ehdr);
+ ehdr = (Elf64_Ehdr*)elf->e_ehdr;
+ encode = ehdr->e_ident[EI_DATA];
+
+ src.d_buf = ehdr;
+ src.d_type = ELF_T_EHDR;
+ src.d_size = _msize(ELFCLASS64, _elf_version, ELF_T_EHDR);
+ src.d_version = _elf_version;
+ dst.d_buf = outbuf;
+ dst.d_size = ehdr->e_ehsize;
+ dst.d_version = ehdr->e_version;
+ if (!elf64_xlatetof(&dst, &src, encode)) {
+ return -1;
+ }
+
+ if (elf->e_phnum) {
+ src.d_buf = elf->e_phdr;
+ src.d_type = ELF_T_PHDR;
+ src.d_size = elf->e_phnum * _msize(ELFCLASS64, _elf_version, ELF_T_PHDR);
+ src.d_version = _elf_version;
+ dst.d_buf = outbuf + ehdr->e_phoff;
+ dst.d_size = elf->e_phnum * ehdr->e_phentsize;
+ dst.d_version = ehdr->e_version;
+ if (!elf64_xlatetof(&dst, &src, encode)) {
+ return -1;
+ }
+ }
+
+ for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ elf_assert(scn->s_elf == elf);
+
+ src.d_buf = &scn->s_uhdr;
+ src.d_type = ELF_T_SHDR;
+ src.d_size = _msize(ELFCLASS64, EV_CURRENT, ELF_T_SHDR);
+ src.d_version = EV_CURRENT;
+ dst.d_buf = outbuf + ehdr->e_shoff + scn->s_index * ehdr->e_shentsize;
+ dst.d_size = ehdr->e_shentsize;
+ dst.d_version = ehdr->e_version;
+ if (!elf64_xlatetof(&dst, &src, encode)) {
+ return -1;
+ }
+
+ if (scn->s_index == SHN_UNDEF) {
+ continue;
+ }
+ shdr = &scn->s_shdr64;
+ if (shdr->sh_type == SHT_NULL || shdr->sh_type == SHT_NOBITS) {
+ continue;
+ }
+ /* XXX: this is probably no longer necessary */
+ if (scn->s_data_1 && !elf_getdata(scn, NULL)) {
+ return -1;
+ }
+ for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ elf_assert(sd->sd_scn == scn);
+ src = sd->sd_data;
+ if (!src.d_size) {
+ continue;
+ }
+ if (!src.d_buf) {
+ seterr(ERROR_NULLBUF);
+ return -1;
+ }
+ dst.d_buf = outbuf + shdr->sh_offset + src.d_off;
+ dst.d_size = src.d_size;
+ dst.d_version = ehdr->e_version;
+ if (valid_type(src.d_type)) {
+ size_t tmp;
+
+ tmp = _elf64_xltsize(&src, dst.d_version, ELFDATA2LSB, 1);
+ if (tmp == (size_t)-1) {
+ return -1;
+ }
+ dst.d_size = tmp;
+ }
+ else {
+ src.d_type = ELF_T_BYTE;
+ }
+ if (!elf64_xlatetof(&dst, &src, encode)) {
+ return -1;
+ }
+ }
+ }
+
+ /* cleanup */
+ if (elf->e_readable && _elf_update_pointers(elf, outbuf, len)) {
+ return -1;
+ }
+ /* NOTE: ehdr is no longer valid! */
+ ehdr = (Elf64_Ehdr*)elf->e_ehdr; elf_assert(ehdr);
+ elf->e_encoding = ehdr->e_ident[EI_DATA];
+ elf->e_version = ehdr->e_ident[EI_VERSION];
+ elf->e_elf_flags &= ~ELF_F_DIRTY;
+ elf->e_ehdr_flags &= ~ELF_F_DIRTY;
+ elf->e_phdr_flags &= ~ELF_F_DIRTY;
+ for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+ scn->s_scn_flags &= ~ELF_F_DIRTY;
+ scn->s_shdr_flags &= ~ELF_F_DIRTY;
+ for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
+ sd->sd_data_flags &= ~ELF_F_DIRTY;
+ }
+ if (elf->e_readable) {
+ shdr = &scn->s_shdr64;
+ scn->s_type = shdr->sh_type;
+ scn->s_size = shdr->sh_size;
+ scn->s_offset = shdr->sh_offset;
+ }
+ }
+ elf->e_size = len;
+ return len;
+}
+
+#endif /* __LIBELF64 */
+
+static int
+xwrite(int fd, char *buffer, size_t len) {
+ size_t done = 0;
+ size_t n;
+
+ while (done < len) {
+ n = write(fd, buffer + done, len - done);
+ if (n == 0) {
+ /* file system full */
+ return -1;
+ }
+ else if (n != (size_t)-1) {
+ /* some bytes written, continue */
+ done += n;
+ }
+ else if (errno != EAGAIN && errno != EINTR) {
+ /* real error */
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static off_t
+_elf_output(Elf *elf, int fd, size_t len, off_t (*_elf_write)(Elf*, char*, size_t)) {
+ char *buf;
+ off_t err;
+
+ elf_assert(len);
+#if HAVE_FTRUNCATE
+ ftruncate(fd, 0);
+#endif /* HAVE_FTRUNCATE */
+#if HAVE_MMAP
+ /*
+ * Make sure the file is (at least) len bytes long
+ */
+#if HAVE_FTRUNCATE
+ lseek(fd, (off_t)len, SEEK_SET);
+ if (ftruncate(fd, len)) {
+#else /* HAVE_FTRUNCATE */
+ {
+#endif /* HAVE_FTRUNCATE */
+ if (lseek(fd, (off_t)len - 1, SEEK_SET) != (off_t)len - 1) {
+ seterr(ERROR_IO_SEEK);
+ return -1;
+ }
+ if (xwrite(fd, "", 1)) {
+ seterr(ERROR_IO_WRITE);
+ return -1;
+ }
+ }
+ buf = (void*)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (buf != (char*)-1) {
+ if ((char)_elf_fill && !(elf->e_elf_flags & ELF_F_LAYOUT)) {
+ memset(buf, _elf_fill, len);
+ }
+ err = _elf_write(elf, buf, len);
+ munmap(buf, len);
+ return err;
+ }
+#endif /* HAVE_MMAP */
+ if (!(buf = (char*)malloc(len))) {
+ seterr(ERROR_MEM_OUTBUF);
+ return -1;
+ }
+ memset(buf, _elf_fill, len);
+ err = _elf_write(elf, buf, len);
+ if (err != -1 && (size_t)err == len) {
+ if (lseek(fd, (off_t)0, SEEK_SET)) {
+ seterr(ERROR_IO_SEEK);
+ err = -1;
+ }
+ else if (xwrite(fd, buf, len)) {
+ seterr(ERROR_IO_WRITE);
+ err = -1;
+ }
+ }
+ free(buf);
+ return err;
+}
+
+off_t
+elf_update(Elf *elf, Elf_Cmd cmd) {
+ unsigned flag;
+ off_t len;
+
+ if (!elf) {
+ return -1;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (cmd == ELF_C_WRITE) {
+ if (!elf->e_writable) {
+ seterr(ERROR_RDONLY);
+ return -1;
+ }
+ if (elf->e_disabled) {
+ seterr(ERROR_FDDISABLED);
+ return -1;
+ }
+ }
+ else if (cmd != ELF_C_NULL) {
+ seterr(ERROR_INVALID_CMD);
+ return -1;
+ }
+
+ if (!elf->e_ehdr) {
+ seterr(ERROR_NOEHDR);
+ }
+ else if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ }
+ else if (elf->e_class == ELFCLASS32) {
+ len = _elf32_layout(elf, &flag);
+ if (len != -1 && cmd == ELF_C_WRITE && (flag & ELF_F_DIRTY)) {
+ len = _elf_output(elf, elf->e_fd, (size_t)len, _elf32_write);
+ }
+ return len;
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ len = _elf64_layout(elf, &flag);
+ if (len != -1 && cmd == ELF_C_WRITE && (flag & ELF_F_DIRTY)) {
+ len = _elf_output(elf, elf->e_fd, (size_t)len, _elf64_write);
+ }
+ return len;
+ }
+#endif /* __LIBELF64 */
+ else if (valid_class(elf->e_class)) {
+ seterr(ERROR_UNIMPLEMENTED);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ return -1;
+}
diff --git a/lib/verdef.h b/lib/verdef.h
new file mode 100644
index 0000000..e17f682
--- /dev/null
+++ b/lib/verdef.h
@@ -0,0 +1,241 @@
+/*
+ * verdef.h - copy versioning information.
+ * Copyright (C) 2001 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef lint
+static const char verdef_h_rcsid[] = "@(#) $Id: verdef.h,v 1.13 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+#if VER_DEF_CURRENT != 1
+#error libelf currently does not support VER_DEF_CURRENT != 1
+#endif /* VER_DEF_CURRENT != 1 */
+
+#if TOFILE
+
+static void
+__store_verdaux(verdaux_ftype *dst, const verdaux_mtype *src, unsigned enc) {
+ if (enc == ELFDATA2LSB) {
+ __store_u32L(dst->vda_name, src->vda_name);
+ __store_u32L(dst->vda_next, src->vda_next);
+ }
+ else {
+ __store_u32M(dst->vda_name, src->vda_name);
+ __store_u32M(dst->vda_next, src->vda_next);
+ }
+}
+
+static void
+__store_verdef(verdef_ftype *dst, const verdef_mtype *src, unsigned enc) {
+ if (enc == ELFDATA2LSB) {
+ __store_u16L(dst->vd_version, src->vd_version);
+ __store_u16L(dst->vd_flags, src->vd_flags);
+ __store_u16L(dst->vd_ndx, src->vd_ndx);
+ __store_u16L(dst->vd_cnt, src->vd_cnt);
+ __store_u32L(dst->vd_hash, src->vd_hash);
+ __store_u32L(dst->vd_aux, src->vd_aux);
+ __store_u32L(dst->vd_next, src->vd_next);
+ }
+ else {
+ __store_u16M(dst->vd_version, src->vd_version);
+ __store_u16M(dst->vd_flags, src->vd_flags);
+ __store_u16M(dst->vd_ndx, src->vd_ndx);
+ __store_u16M(dst->vd_cnt, src->vd_cnt);
+ __store_u32M(dst->vd_hash, src->vd_hash);
+ __store_u32M(dst->vd_aux, src->vd_aux);
+ __store_u32M(dst->vd_next, src->vd_next);
+ }
+}
+
+typedef verdaux_mtype verdaux_stype;
+typedef verdaux_ftype verdaux_dtype;
+typedef verdef_mtype verdef_stype;
+typedef verdef_ftype verdef_dtype;
+typedef align_mtype verdef_atype;
+
+#define copy_verdaux_srctotmp(d, s, e) (*(d) = *(s))
+#define copy_verdaux_tmptodst(d, s, e) __store_verdaux((d), (s), (e))
+#define copy_verdef_srctotmp(d, s, e) (*(d) = *(s))
+#define copy_verdef_tmptodst(d, s, e) __store_verdef((d), (s), (e))
+
+#define translator_suffix _tof
+
+#else /* TOFILE */
+
+static void
+__load_verdaux(verdaux_mtype *dst, const verdaux_ftype *src, unsigned enc) {
+ if (enc == ELFDATA2LSB) {
+ dst->vda_name = __load_u32L(src->vda_name);
+ dst->vda_next = __load_u32L(src->vda_next);
+ }
+ else {
+ dst->vda_name = __load_u32M(src->vda_name);
+ dst->vda_next = __load_u32M(src->vda_next);
+ }
+}
+
+static void
+__load_verdef(verdef_mtype *dst, const verdef_ftype *src, unsigned enc) {
+ if (enc == ELFDATA2LSB) {
+ dst->vd_version = __load_u16L(src->vd_version);
+ dst->vd_flags = __load_u16L(src->vd_flags);
+ dst->vd_ndx = __load_u16L(src->vd_ndx);
+ dst->vd_cnt = __load_u16L(src->vd_cnt);
+ dst->vd_hash = __load_u32L(src->vd_hash);
+ dst->vd_aux = __load_u32L(src->vd_aux);
+ dst->vd_next = __load_u32L(src->vd_next);
+ }
+ else {
+ dst->vd_version = __load_u16M(src->vd_version);
+ dst->vd_flags = __load_u16M(src->vd_flags);
+ dst->vd_ndx = __load_u16M(src->vd_ndx);
+ dst->vd_cnt = __load_u16M(src->vd_cnt);
+ dst->vd_hash = __load_u32M(src->vd_hash);
+ dst->vd_aux = __load_u32M(src->vd_aux);
+ dst->vd_next = __load_u32M(src->vd_next);
+ }
+}
+
+typedef verdaux_ftype verdaux_stype;
+typedef verdaux_mtype verdaux_dtype;
+typedef verdef_ftype verdef_stype;
+typedef verdef_mtype verdef_dtype;
+typedef align_ftype verdef_atype;
+
+#define copy_verdaux_srctotmp(d, s, e) __load_verdaux((d), (s), (e))
+#define copy_verdaux_tmptodst(d, s, e) (*(d) = *(s))
+#define copy_verdef_srctotmp(d, s, e) __load_verdef((d), (s), (e))
+#define copy_verdef_tmptodst(d, s, e) (*(d) = *(s))
+
+#define translator_suffix _tom
+
+#endif /* TOFILE */
+
+#define cat3(a,b,c) a##b##c
+#define xlt3(p,e,s) cat3(p,e,s)
+#define xltprefix(x) xlt3(x,_,class_suffix)
+#define translator(x,e) xlt3(xltprefix(_elf_##x),e,translator_suffix)
+
+static size_t
+xlt_verdef(unsigned char *dst, const unsigned char *src, size_t n, unsigned enc) {
+ size_t off;
+
+ if (sizeof(verdef_stype) != sizeof(verdef_dtype)
+ || sizeof(verdaux_stype) != sizeof(verdaux_dtype)) {
+ /* never happens for ELF v1 and Verneed v1 */
+ seterr(ERROR_UNIMPLEMENTED);
+ return (size_t)-1;
+ }
+ /* size translation shortcut */
+ if (dst == NULL) {
+ return n;
+ }
+ if (src == NULL) {
+ seterr(ERROR_NULLBUF);
+ return (size_t)-1;
+ }
+ off = 0;
+ while (off + sizeof(verdef_stype) <= n) {
+ const verdef_stype *svd;
+ verdef_dtype *dvd;
+ verdef_mtype vd;
+ size_t acount;
+ size_t aoff;
+
+ /*
+ * check for proper alignment
+ */
+ if (off % sizeof(verdef_atype)) {
+ seterr(ERROR_VERDEF_FORMAT);
+ return (size_t)-1;
+ }
+ /*
+ * copy and check src
+ */
+ svd = (verdef_stype*)(src + off);
+ dvd = (verdef_dtype*)(dst + off);
+ copy_verdef_srctotmp(&vd, svd, enc);
+ if (vd.vd_version < 1
+ || vd.vd_version > VER_DEF_CURRENT) {
+ seterr(ERROR_VERDEF_VERSION);
+ return (size_t)-1;
+ }
+ if (vd.vd_cnt < 1
+ || vd.vd_aux == 0) {
+ seterr(ERROR_VERDEF_FORMAT);
+ return (size_t)-1;
+ }
+ copy_verdef_tmptodst(dvd, &vd, enc);
+ /*
+ * copy aux array
+ */
+ aoff = off + vd.vd_aux;
+ for (acount = 0; acount < vd.vd_cnt; acount++) {
+ const verdaux_stype *svda;
+ verdaux_dtype *dvda;
+ verdaux_mtype vda;
+
+ /*
+ * are we still inside the buffer limits?
+ */
+ if (aoff + sizeof(verdaux_stype) > n) {
+ break;
+ }
+ /*
+ * check for proper alignment
+ */
+ if (aoff % sizeof(verdef_atype)) {
+ seterr(ERROR_VERDEF_FORMAT);
+ return (size_t)-1;
+ }
+ /*
+ * copy and check src
+ */
+ svda = (verdaux_stype*)(src + aoff);
+ dvda = (verdaux_dtype*)(dst + aoff);
+ copy_verdaux_srctotmp(&vda, svda, enc);
+ copy_verdaux_tmptodst(dvda, &vda, enc);
+ /*
+ * advance to next verdaux
+ */
+ if (vda.vda_next == 0) {
+ /* end of list */
+ break;
+ }
+ aoff += vda.vda_next;
+ }
+ /*
+ * advance to next verdef
+ */
+ if (vd.vd_next == 0) {
+ /* end of list */
+ break;
+ }
+ off += vd.vd_next;
+ }
+ return n;
+}
+
+size_t
+translator(verdef,L11)(unsigned char *dst, const unsigned char *src, size_t n) {
+ return xlt_verdef(dst, src, n, ELFDATA2LSB);
+}
+
+size_t
+translator(verdef,M11)(unsigned char *dst, const unsigned char *src, size_t n) {
+ return xlt_verdef(dst, src, n, ELFDATA2MSB);
+}
diff --git a/lib/verdef_32_tof.c b/lib/verdef_32_tof.c
new file mode 100644
index 0000000..efca6ee
--- /dev/null
+++ b/lib/verdef_32_tof.c
@@ -0,0 +1,53 @@
+/*
+verdef_32_tof.c - copy 32-bit versioning information.
+Copyright (C) 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+#include <ext_types.h>
+#include <byteswap.h>
+
+#if __LIBELF_SYMBOL_VERSIONS
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: verdef_32_tof.c,v 1.5 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+typedef Elf32_Verdaux verdaux_mtype;
+typedef Elf32_Verdef verdef_mtype;
+typedef Elf32_Vernaux vernaux_mtype;
+typedef Elf32_Verneed verneed_mtype;
+typedef Elf32_Word align_mtype;
+
+typedef __ext_Elf32_Verdaux verdaux_ftype;
+typedef __ext_Elf32_Verdef verdef_ftype;
+typedef __ext_Elf32_Vernaux vernaux_ftype;
+typedef __ext_Elf32_Verneed verneed_ftype;
+typedef __ext_Elf32_Word align_ftype;
+
+#define class_suffix 32
+
+#undef TOFILE
+#define TOFILE 1
+
+/*
+ * Include shared code
+ */
+#include "verdef.h"
+#include "verneed.h"
+
+#endif /* __LIBELF_SYMBOL_VERSIONS */
diff --git a/lib/verdef_32_tom.c b/lib/verdef_32_tom.c
new file mode 100644
index 0000000..f0efd0f
--- /dev/null
+++ b/lib/verdef_32_tom.c
@@ -0,0 +1,53 @@
+/*
+verdef_32_tom.c - copy 32-bit versioning information.
+Copyright (C) 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+#include <ext_types.h>
+#include <byteswap.h>
+
+#if __LIBELF_SYMBOL_VERSIONS
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: verdef_32_tom.c,v 1.5 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+typedef Elf32_Verdaux verdaux_mtype;
+typedef Elf32_Verdef verdef_mtype;
+typedef Elf32_Vernaux vernaux_mtype;
+typedef Elf32_Verneed verneed_mtype;
+typedef Elf32_Word align_mtype;
+
+typedef __ext_Elf32_Verdaux verdaux_ftype;
+typedef __ext_Elf32_Verdef verdef_ftype;
+typedef __ext_Elf32_Vernaux vernaux_ftype;
+typedef __ext_Elf32_Verneed verneed_ftype;
+typedef __ext_Elf32_Word align_ftype;
+
+#define class_suffix 32
+
+#undef TOFILE
+#define TOFILE 0
+
+/*
+ * Include shared code
+ */
+#include "verdef.h"
+#include "verneed.h"
+
+#endif /* __LIBELF_SYMBOL_VERSIONS */
diff --git a/lib/verdef_64_tof.c b/lib/verdef_64_tof.c
new file mode 100644
index 0000000..16b903e
--- /dev/null
+++ b/lib/verdef_64_tof.c
@@ -0,0 +1,53 @@
+/*
+verdef_64_tof.c - copy 64-bit versioning information.
+Copyright (C) 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+#include <ext_types.h>
+#include <byteswap.h>
+
+#if __LIBELF64 && __LIBELF_SYMBOL_VERSIONS
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: verdef_64_tof.c,v 1.5 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+typedef Elf64_Verdaux verdaux_mtype;
+typedef Elf64_Verdef verdef_mtype;
+typedef Elf64_Vernaux vernaux_mtype;
+typedef Elf64_Verneed verneed_mtype;
+typedef Elf64_Word align_mtype;
+
+typedef __ext_Elf64_Verdaux verdaux_ftype;
+typedef __ext_Elf64_Verdef verdef_ftype;
+typedef __ext_Elf64_Vernaux vernaux_ftype;
+typedef __ext_Elf64_Verneed verneed_ftype;
+typedef __ext_Elf64_Word align_ftype;
+
+#define class_suffix 64
+
+#undef TOFILE
+#define TOFILE 1
+
+/*
+ * Include shared code
+ */
+#include "verdef.h"
+#include "verneed.h"
+
+#endif /* __LIBELF64 && __LIBELF_SYMBOL_VERSIONS */
diff --git a/lib/verdef_64_tom.c b/lib/verdef_64_tom.c
new file mode 100644
index 0000000..183524e
--- /dev/null
+++ b/lib/verdef_64_tom.c
@@ -0,0 +1,53 @@
+/*
+verdef_64_tom.c - copy 64-bit versioning information.
+Copyright (C) 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+#include <ext_types.h>
+#include <byteswap.h>
+
+#if __LIBELF64 && __LIBELF_SYMBOL_VERSIONS
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: verdef_64_tom.c,v 1.5 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+typedef Elf64_Verdaux verdaux_mtype;
+typedef Elf64_Verdef verdef_mtype;
+typedef Elf64_Vernaux vernaux_mtype;
+typedef Elf64_Verneed verneed_mtype;
+typedef Elf64_Word align_mtype;
+
+typedef __ext_Elf64_Verdaux verdaux_ftype;
+typedef __ext_Elf64_Verdef verdef_ftype;
+typedef __ext_Elf64_Vernaux vernaux_ftype;
+typedef __ext_Elf64_Verneed verneed_ftype;
+typedef __ext_Elf64_Word align_ftype;
+
+#define class_suffix 64
+
+#undef TOFILE
+#define TOFILE 0
+
+/*
+ * Include shared code
+ */
+#include "verdef.h"
+#include "verneed.h"
+
+#endif /* __LIBELF64 && __LIBELF_SYMBOL_VERSIONS */
diff --git a/lib/verneed.h b/lib/verneed.h
new file mode 100644
index 0000000..54f0f06
--- /dev/null
+++ b/lib/verneed.h
@@ -0,0 +1,245 @@
+/*
+ * verneed.h - copy versioning information.
+ * Copyright (C) 2001 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef lint
+static const char verneed_h_rcsid[] = "@(#) $Id: verneed.h,v 1.13 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+#if VER_NEED_CURRENT != 1
+#error libelf currently does not support VER_NEED_CURRENT != 1
+#endif /* VER_NEED_CURRENT != 1 */
+
+#if TOFILE
+
+static void
+__store_vernaux(vernaux_ftype *dst, const vernaux_mtype *src, unsigned enc) {
+ if (enc == ELFDATA2LSB) {
+ __store_u32L(dst->vna_hash, src->vna_hash);
+ __store_u16L(dst->vna_flags, src->vna_flags);
+ __store_u16L(dst->vna_other, src->vna_other);
+ __store_u32L(dst->vna_name, src->vna_name);
+ __store_u32L(dst->vna_next, src->vna_next);
+ }
+ else {
+ __store_u32M(dst->vna_hash, src->vna_hash);
+ __store_u16M(dst->vna_flags, src->vna_flags);
+ __store_u16M(dst->vna_other, src->vna_other);
+ __store_u32M(dst->vna_name, src->vna_name);
+ __store_u32M(dst->vna_next, src->vna_next);
+ }
+}
+
+static void
+__store_verneed(verneed_ftype *dst, const verneed_mtype *src, unsigned enc) {
+ if (enc == ELFDATA2LSB) {
+ __store_u16L(dst->vn_version, src->vn_version);
+ __store_u16L(dst->vn_cnt, src->vn_cnt);
+ __store_u32L(dst->vn_file, src->vn_file);
+ __store_u32L(dst->vn_aux, src->vn_aux);
+ __store_u32L(dst->vn_next, src->vn_next);
+ }
+ else {
+ __store_u16M(dst->vn_version, src->vn_version);
+ __store_u16M(dst->vn_cnt, src->vn_cnt);
+ __store_u32M(dst->vn_file, src->vn_file);
+ __store_u32M(dst->vn_aux, src->vn_aux);
+ __store_u32M(dst->vn_next, src->vn_next);
+ }
+}
+
+typedef vernaux_mtype vernaux_stype;
+typedef vernaux_ftype vernaux_dtype;
+typedef verneed_mtype verneed_stype;
+typedef verneed_ftype verneed_dtype;
+typedef align_mtype verneed_atype;
+
+#define copy_vernaux_srctotmp(d, s, e) (*(d) = *(s))
+#define copy_vernaux_tmptodst(d, s, e) __store_vernaux((d), (s), (e))
+#define copy_verneed_srctotmp(d, s, e) (*(d) = *(s))
+#define copy_verneed_tmptodst(d, s, e) __store_verneed((d), (s), (e))
+
+#define translator_suffix _tof
+
+#else /* TOFILE */
+
+static void
+__load_vernaux(vernaux_mtype *dst, const vernaux_ftype *src, unsigned enc) {
+ if (enc == ELFDATA2LSB) {
+ dst->vna_hash = __load_u32L(src->vna_hash);
+ dst->vna_flags = __load_u16L(src->vna_flags);
+ dst->vna_other = __load_u16L(src->vna_other);
+ dst->vna_name = __load_u32L(src->vna_name);
+ dst->vna_next = __load_u32L(src->vna_next);
+ }
+ else {
+ dst->vna_hash = __load_u32M(src->vna_hash);
+ dst->vna_flags = __load_u16M(src->vna_flags);
+ dst->vna_other = __load_u16M(src->vna_other);
+ dst->vna_name = __load_u32M(src->vna_name);
+ dst->vna_next = __load_u32M(src->vna_next);
+ }
+}
+
+static void
+__load_verneed(verneed_mtype *dst, const verneed_ftype *src, unsigned enc) {
+ if (enc == ELFDATA2LSB) {
+ dst->vn_version = __load_u16L(src->vn_version);
+ dst->vn_cnt = __load_u16L(src->vn_cnt);
+ dst->vn_file = __load_u32L(src->vn_file);
+ dst->vn_aux = __load_u32L(src->vn_aux);
+ dst->vn_next = __load_u32L(src->vn_next);
+ }
+ else {
+ dst->vn_version = __load_u16M(src->vn_version);
+ dst->vn_cnt = __load_u16M(src->vn_cnt);
+ dst->vn_file = __load_u32M(src->vn_file);
+ dst->vn_aux = __load_u32M(src->vn_aux);
+ dst->vn_next = __load_u32M(src->vn_next);
+ }
+}
+
+typedef vernaux_ftype vernaux_stype;
+typedef vernaux_mtype vernaux_dtype;
+typedef verneed_ftype verneed_stype;
+typedef verneed_mtype verneed_dtype;
+typedef align_ftype verneed_atype;
+
+#define copy_vernaux_srctotmp(d, s, e) __load_vernaux((d), (s), (e))
+#define copy_vernaux_tmptodst(d, s, e) (*(d) = *(s))
+#define copy_verneed_srctotmp(d, s, e) __load_verneed((d), (s), (e))
+#define copy_verneed_tmptodst(d, s, e) (*(d) = *(s))
+
+#define translator_suffix _tom
+
+#endif /* TOFILE */
+
+#define cat3(a,b,c) a##b##c
+#define xlt3(p,e,s) cat3(p,e,s)
+#define xltprefix(x) xlt3(x,_,class_suffix)
+#define translator(x,e) xlt3(xltprefix(_elf_##x),e,translator_suffix)
+
+static size_t
+xlt_verneed(unsigned char *dst, const unsigned char *src, size_t n, unsigned enc) {
+ size_t off;
+
+ if (sizeof(verneed_stype) != sizeof(verneed_dtype)
+ || sizeof(vernaux_stype) != sizeof(vernaux_dtype)) {
+ /* never happens for ELF v1 and Verneed v1 */
+ seterr(ERROR_UNIMPLEMENTED);
+ return (size_t)-1;
+ }
+ /* size translation shortcut */
+ if (dst == NULL) {
+ return n;
+ }
+ if (src == NULL) {
+ seterr(ERROR_NULLBUF);
+ return (size_t)-1;
+ }
+ off = 0;
+ while (off + sizeof(verneed_stype) <= n) {
+ const verneed_stype *svn;
+ verneed_dtype *dvn;
+ verneed_mtype vn;
+ size_t acount;
+ size_t aoff;
+
+ /*
+ * check for proper alignment
+ */
+ if (off % sizeof(verneed_atype)) {
+ seterr(ERROR_VERNEED_FORMAT);
+ return (size_t)-1;
+ }
+ /*
+ * copy and check src
+ */
+ svn = (verneed_stype*)(src + off);
+ dvn = (verneed_dtype*)(dst + off);
+ copy_verneed_srctotmp(&vn, svn, enc);
+ if (vn.vn_version < 1
+ || vn.vn_version > VER_NEED_CURRENT) {
+ seterr(ERROR_VERNEED_VERSION);
+ return (size_t)-1;
+ }
+ if (vn.vn_cnt < 1
+ || vn.vn_aux == 0) {
+ seterr(ERROR_VERNEED_FORMAT);
+ return (size_t)-1;
+ }
+ copy_verneed_tmptodst(dvn, &vn, enc);
+ /*
+ * copy aux array
+ */
+ aoff = off + vn.vn_aux;
+ for (acount = 0; acount < vn.vn_cnt; acount++) {
+ const vernaux_stype *svna;
+ vernaux_dtype *dvna;
+ vernaux_mtype vna;
+
+ /*
+ * are we still inside the buffer limits?
+ */
+ if (aoff + sizeof(vernaux_stype) > n) {
+ break;
+ }
+ /*
+ * check for proper alignment
+ */
+ if (aoff % sizeof(verneed_atype)) {
+ seterr(ERROR_VERNEED_FORMAT);
+ return (size_t)-1;
+ }
+ /*
+ * copy and check src
+ */
+ svna = (vernaux_stype*)(src + aoff);
+ dvna = (vernaux_dtype*)(dst + aoff);
+ copy_vernaux_srctotmp(&vna, svna, enc);
+ copy_vernaux_tmptodst(dvna, &vna, enc);
+ /*
+ * advance to next vernaux
+ */
+ if (vna.vna_next == 0) {
+ /* end of list */
+ break;
+ }
+ aoff += vna.vna_next;
+ }
+ /*
+ * advance to next verneed
+ */
+ if (vn.vn_next == 0) {
+ /* end of list */
+ break;
+ }
+ off += vn.vn_next;
+ }
+ return n;
+}
+
+size_t
+translator(verneed,L11)(unsigned char *dst, const unsigned char *src, size_t n) {
+ return xlt_verneed(dst, src, n, ELFDATA2LSB);
+}
+
+size_t
+translator(verneed,M11)(unsigned char *dst, const unsigned char *src, size_t n) {
+ return xlt_verneed(dst, src, n, ELFDATA2MSB);
+}
diff --git a/lib/version.c b/lib/version.c
new file mode 100644
index 0000000..7a901d3
--- /dev/null
+++ b/lib/version.c
@@ -0,0 +1,44 @@
+/*
+ * version.c - implementation of the elf_version(3) function.
+ * Copyright (C) 1995 - 1998, 2007 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: version.c,v 1.8 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+unsigned
+elf_version(unsigned ver) {
+ const char *s;
+ unsigned tmp;
+
+ if ((s = getenv("LIBELF_SANITY_CHECKS"))) {
+ _elf_sanity_checks = (int)strtol(s, (char**)NULL, 0);
+ }
+ if (ver == EV_NONE) {
+ return EV_CURRENT;
+ }
+ if (!valid_version(ver)) {
+ seterr(ERROR_UNKNOWN_VERSION);
+ return EV_NONE;
+ }
+ tmp = _elf_version == EV_NONE ? EV_CURRENT : _elf_version;
+ _elf_version = ver;
+ return tmp;
+}
diff --git a/lib/x.elfext.c b/lib/x.elfext.c
new file mode 100644
index 0000000..cbd3539
--- /dev/null
+++ b/lib/x.elfext.c
@@ -0,0 +1,190 @@
+/*
+ * x.elfext.c -- handle ELF format extensions
+ * Copyright (C) 2002 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: x.elfext.c,v 1.5 2009/07/07 17:57:43 michael Exp $";
+#endif /* lint */
+
+int
+elf_getphdrnum(Elf *elf, size_t *resultp) {
+ if (!elf) {
+ return -1;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ return -1;
+ }
+ if (!elf->e_ehdr && !_elf_cook(elf)) {
+ return -1;
+ }
+ if (resultp) {
+ *resultp = elf->e_phnum;
+ }
+ return 0;
+}
+
+int
+elf_getshdrnum(Elf *elf, size_t *resultp) {
+ size_t num = 0;
+ Elf_Scn *scn;
+
+ if (!elf) {
+ return -1;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ return -1;
+ }
+ if (!elf->e_ehdr && !_elf_cook(elf)) {
+ return -1;
+ }
+ if ((scn = elf->e_scn_n)) {
+ num = scn->s_index + 1;
+ }
+ if (resultp) {
+ *resultp = num;
+ }
+ return 0;
+}
+
+int
+elf_getshdrstrndx(Elf *elf, size_t *resultp) {
+ size_t num = 0;
+ size_t dummy;
+ Elf_Scn *scn;
+
+ if (!elf) {
+ return -1;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (resultp == NULL) {
+ resultp = &dummy; /* handle NULL pointer gracefully */
+ }
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ return -1;
+ }
+ if (!elf->e_ehdr && !_elf_cook(elf)) {
+ return -1;
+ }
+ if (elf->e_class == ELFCLASS32) {
+ num = ((Elf32_Ehdr*)elf->e_ehdr)->e_shstrndx;
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ num = ((Elf64_Ehdr*)elf->e_ehdr)->e_shstrndx;
+ }
+#endif /* __LIBELF64 */
+ else {
+ if (valid_class(elf->e_class)) {
+ seterr(ERROR_UNIMPLEMENTED);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ return -1;
+ }
+ if (num != SHN_XINDEX) {
+ *resultp = num;
+ return 0;
+ }
+ /*
+ * look at first section header
+ */
+ if (!(scn = elf->e_scn_1)) {
+ seterr(ERROR_NOSUCHSCN);
+ return -1;
+ }
+ elf_assert(scn->s_magic == SCN_MAGIC);
+#if __LIBELF64
+ if (elf->e_class == ELFCLASS64) {
+ *resultp = scn->s_shdr64.sh_link;
+ return 0;
+ }
+#endif /* __LIBELF64 */
+ *resultp = scn->s_shdr32.sh_link;
+ return 0;
+}
+
+int
+elf_getphnum(Elf *elf, size_t *resultp) {
+ return elf_getphdrnum(elf, resultp) ? LIBELF_FAILURE : LIBELF_SUCCESS;
+}
+
+int
+elf_getshnum(Elf *elf, size_t *resultp) {
+ return elf_getshdrnum(elf, resultp) ? LIBELF_FAILURE : LIBELF_SUCCESS;
+}
+
+int
+elf_getshstrndx(Elf *elf, size_t *resultp) {
+ return elf_getshdrstrndx(elf, resultp) ? LIBELF_FAILURE : LIBELF_SUCCESS;
+}
+
+int
+elfx_update_shstrndx(Elf *elf, size_t value) {
+ size_t extvalue = 0;
+ Elf_Scn *scn;
+
+ if (!elf) {
+ return LIBELF_FAILURE;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (value >= SHN_LORESERVE) {
+ extvalue = value;
+ value = SHN_XINDEX;
+ }
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ return LIBELF_FAILURE;
+ }
+ if (!elf->e_ehdr && !_elf_cook(elf)) {
+ return LIBELF_FAILURE;
+ }
+ if (!(scn = _elf_first_scn(elf))) {
+ return LIBELF_FAILURE;
+ }
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ if (elf->e_class == ELFCLASS32) {
+ ((Elf32_Ehdr*)elf->e_ehdr)->e_shstrndx = value;
+ scn->s_shdr32.sh_link = extvalue;
+ }
+#if __LIBELF64
+ else if (elf->e_class == ELFCLASS64) {
+ ((Elf64_Ehdr*)elf->e_ehdr)->e_shstrndx = value;
+ scn->s_shdr64.sh_link = extvalue;
+ }
+#endif /* __LIBELF64 */
+ else {
+ if (valid_class(elf->e_class)) {
+ seterr(ERROR_UNIMPLEMENTED);
+ }
+ else {
+ seterr(ERROR_UNKNOWN_CLASS);
+ }
+ return LIBELF_FAILURE;
+ }
+ elf->e_ehdr_flags |= ELF_F_DIRTY;
+ scn->s_shdr_flags |= ELF_F_DIRTY;
+ return LIBELF_SUCCESS;
+}
diff --git a/lib/x.movscn.c b/lib/x.movscn.c
new file mode 100644
index 0000000..4f3d9d2
--- /dev/null
+++ b/lib/x.movscn.c
@@ -0,0 +1,112 @@
+/*
+x.movscn.c - implementation of the elfx_movscn(3) function.
+Copyright (C) 1995 - 2001, 2003 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: x.movscn.c,v 1.14 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+size_t
+elfx_movscn(Elf *elf, Elf_Scn *scn, Elf_Scn *after) {
+ Elf_Scn *prev;
+ Elf_Scn *tmp;
+ int off;
+
+ if (!elf || !scn || !after) {
+ return SHN_UNDEF;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ return SHN_UNDEF;
+ }
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ elf_assert(after->s_magic == SCN_MAGIC);
+ if (scn->s_elf != elf || after->s_elf != elf) {
+ seterr(ERROR_ELFSCNMISMATCH);
+ return SHN_UNDEF;
+ }
+ elf_assert(elf->e_scn_1);
+ if (scn == elf->e_scn_1) {
+ seterr(ERROR_NULLSCN);
+ return SHN_UNDEF;
+ }
+ if (scn == after || scn == after->s_link) {
+ /* nothing to do */
+ return scn->s_index;
+ }
+
+ /*
+ * Find previous section.
+ */
+ prev = NULL;
+ for (tmp = elf->e_scn_1; tmp->s_link; tmp = tmp->s_link) {
+ if (tmp->s_link == scn) {
+ prev = tmp;
+ break;
+ }
+ }
+ elf_assert(prev != NULL);
+
+ /*
+ * Update section indices
+ */
+ off = 0;
+ for (tmp = elf->e_scn_1; tmp; tmp = tmp->s_link) {
+ if (off) {
+ tmp->s_index += off;
+ }
+ if (tmp == after) {
+ off++;
+ }
+ else if (tmp == scn) {
+ off--;
+ }
+ }
+ elf_assert(off == 0);
+
+ /*
+ * Move section.
+ */
+ prev->s_link = scn->s_link;
+ scn->s_link = after->s_link;
+ after->s_link = scn;
+ scn->s_index = after->s_index + 1;
+ if (elf->e_scn_n == scn) {
+ elf->e_scn_n = prev;
+ }
+ else if (elf->e_scn_n == after) {
+ elf->e_scn_n = scn;
+ }
+
+#if ENABLE_DEBUG
+ /*
+ * Check section indices
+ */
+ tmp = elf->e_scn_1;
+ elf_assert(tmp->s_index == 0);
+ while (tmp->s_link) {
+ elf_assert(tmp->s_link->s_index == tmp->s_index + 1);
+ tmp = tmp->s_link;
+ }
+#endif /* ENABLE_DEBUG */
+
+ return scn->s_index;
+}
diff --git a/lib/x.remscn.c b/lib/x.remscn.c
new file mode 100644
index 0000000..d04816e
--- /dev/null
+++ b/lib/x.remscn.c
@@ -0,0 +1,119 @@
+/*
+x.remscn.c - implementation of the elfx_remscn(3) function.
+Copyright (C) 1995 - 2001, 2003 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: x.remscn.c,v 1.15 2008/05/23 08:15:35 michael Exp $";
+#endif /* lint */
+
+size_t
+elfx_remscn(Elf *elf, Elf_Scn *scn) {
+ Elf_Scn *pscn;
+ Scn_Data *sd;
+ Scn_Data *tmp;
+ size_t index;
+
+ if (!elf || !scn) {
+ return SHN_UNDEF;
+ }
+ elf_assert(elf->e_magic == ELF_MAGIC);
+ if (elf->e_kind != ELF_K_ELF) {
+ seterr(ERROR_NOTELF);
+ return SHN_UNDEF;
+ }
+ elf_assert(scn->s_magic == SCN_MAGIC);
+ elf_assert(elf->e_ehdr);
+ if (scn->s_elf != elf) {
+ seterr(ERROR_ELFSCNMISMATCH);
+ return SHN_UNDEF;
+ }
+ elf_assert(elf->e_scn_1);
+ if (scn == elf->e_scn_1) {
+ seterr(ERROR_NULLSCN);
+ return SHN_UNDEF;
+ }
+
+ /*
+ * Find previous section.
+ */
+ for (pscn = elf->e_scn_1; pscn->s_link; pscn = pscn->s_link) {
+ if (pscn->s_link == scn) {
+ break;
+ }
+ }
+ if (pscn->s_link != scn) {
+ seterr(ERROR_ELFSCNMISMATCH);
+ return SHN_UNDEF;
+ }
+
+ /*
+ * Unlink section.
+ */
+ if (elf->e_scn_n == scn) {
+ elf->e_scn_n = pscn;
+ }
+ pscn->s_link = scn->s_link;
+ index = scn->s_index;
+
+ /*
+ * Free section descriptor and data.
+ */
+ for (sd = scn->s_data_1; sd; sd = tmp) {
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ elf_assert(sd->sd_scn == scn);
+ tmp = sd->sd_link;
+ if (sd->sd_free_data && sd->sd_memdata) {
+ free(sd->sd_memdata);
+ }
+ if (sd->sd_freeme) {
+ free(sd);
+ }
+ }
+ if ((sd = scn->s_rawdata)) {
+ elf_assert(sd->sd_magic == DATA_MAGIC);
+ elf_assert(sd->sd_scn == scn);
+ if (sd->sd_free_data && sd->sd_memdata) {
+ free(sd->sd_memdata);
+ }
+ if (sd->sd_freeme) {
+ free(sd);
+ }
+ }
+ if (scn->s_freeme) {
+ elf_assert(scn->s_index > 0);
+ free(scn);
+ }
+
+ /*
+ * Adjust section indices.
+ */
+ for (scn = pscn->s_link; scn; scn = scn->s_link) {
+ elf_assert(scn->s_index > index);
+ scn->s_index--;
+ }
+
+ /*
+ * Adjust section count in ELF header
+ */
+ if (_elf_update_shnum(elf, elf->e_scn_n->s_index + 1)) {
+ return SHN_UNDEF;
+ }
+ return index;
+}