aboutsummaryrefslogtreecommitdiff
path: root/test/libelf/tset
diff options
context:
space:
mode:
authorKai Wang <kaiw@FreeBSD.org>2014-01-15 08:43:20 +0000
committerKai Wang <kaiw@FreeBSD.org>2014-01-15 08:43:20 +0000
commit5265ace0e440a23fb522c516f4ee20f43eaed2b3 (patch)
tree13068447bb61372f7540b168e913b8eb88ef7578 /test/libelf/tset
Notes
Diffstat (limited to 'test/libelf/tset')
-rw-r--r--test/libelf/tset/Makefile58
-rw-r--r--test/libelf/tset/Makefile.tset36
-rw-r--r--test/libelf/tset/abi/Makefile7
-rw-r--r--test/libelf/tset/abi/abi.m4296
-rwxr-xr-xtest/libelf/tset/bin/elf-hash39
-rwxr-xr-xtest/libelf/tset/bin/elfc1615
-rw-r--r--test/libelf/tset/common/Makefile36
-rw-r--r--test/libelf/tset/common/check_elf.yaml16
-rw-r--r--test/libelf/tset/common/ehdr.yaml23
-rw-r--r--test/libelf/tset/common/ehdr_template.m4371
-rw-r--r--test/libelf/tset/common/elf_flag.m4184
-rw-r--r--test/libelf/tset/common/elfts-compare-files.c125
-rw-r--r--test/libelf/tset/common/elfts-copy-file.c107
-rw-r--r--test/libelf/tset/common/elfts-initversion.c48
-rw-r--r--test/libelf/tset/common/elfts-openfile.c80
-rw-r--r--test/libelf/tset/common/elfts.h118
-rw-r--r--test/libelf/tset/common/fsize.yaml16
-rw-r--r--test/libelf/tset/common/gelf_ehdr_template.h167
-rw-r--r--test/libelf/tset/common/getclass.yaml16
-rw-r--r--test/libelf/tset/common/getshdr.m4171
-rw-r--r--test/libelf/tset/common/newehdr.yaml7
-rw-r--r--test/libelf/tset/common/newehdr_template.m4243
-rw-r--r--test/libelf/tset/common/newscn.yaml27
-rw-r--r--test/libelf/tset/common/newscn2.yaml28
-rw-r--r--test/libelf/tset/common/phdr.yaml38
-rw-r--r--test/libelf/tset/common/phdr_template.c418
-rw-r--r--test/libelf/tset/common/rdwr.yaml27
-rw-r--r--test/libelf/tset/common/rdwr1.yaml27
-rw-r--r--test/libelf/tset/common/rdwr2.yaml28
-rw-r--r--test/libelf/tset/common/shdr.yaml42
-rw-r--r--test/libelf/tset/common/u1.yaml29
-rw-r--r--test/libelf/tset/common/versioning.yaml55
-rw-r--r--test/libelf/tset/common/xlate.yaml23
-rw-r--r--test/libelf/tset/common/xlate_template.c1825
-rw-r--r--test/libelf/tset/common/xlate_template.m41436
-rw-r--r--test/libelf/tset/common/xscn-1.yaml23
-rw-r--r--test/libelf/tset/common/xscn-2.yaml22
-rw-r--r--test/libelf/tset/common/xscn-3.yaml26
-rw-r--r--test/libelf/tset/common/zerosection.yaml27
-rw-r--r--test/libelf/tset/elf32_getehdr/Makefile8
-rw-r--r--test/libelf/tset/elf32_getehdr/ehdr.m441
-rw-r--r--test/libelf/tset/elf32_getphdr/Makefile9
-rw-r--r--test/libelf/tset/elf32_getphdr/phdr.m441
-rw-r--r--test/libelf/tset/elf32_getshdr/Makefile8
-rw-r--r--test/libelf/tset/elf32_getshdr/shdr.m454
-rw-r--r--test/libelf/tset/elf32_newehdr/Makefile9
-rw-r--r--test/libelf/tset/elf32_newehdr/ehdr.m445
-rw-r--r--test/libelf/tset/elf32_xlatetof/Makefile7
-rw-r--r--test/libelf/tset/elf32_xlatetof/xlate.m451
-rw-r--r--test/libelf/tset/elf32_xlatetom/Makefile7
-rw-r--r--test/libelf/tset/elf32_xlatetom/xlate.m452
-rw-r--r--test/libelf/tset/elf64_getehdr/Makefile8
-rw-r--r--test/libelf/tset/elf64_getehdr/ehdr.m441
-rw-r--r--test/libelf/tset/elf64_getphdr/Makefile9
-rw-r--r--test/libelf/tset/elf64_getphdr/phdr.m441
-rw-r--r--test/libelf/tset/elf64_getshdr/Makefile8
-rw-r--r--test/libelf/tset/elf64_getshdr/shdr.m454
-rw-r--r--test/libelf/tset/elf64_newehdr/Makefile9
-rw-r--r--test/libelf/tset/elf64_newehdr/ehdr.m445
-rw-r--r--test/libelf/tset/elf64_xlatetof/Makefile7
-rw-r--r--test/libelf/tset/elf64_xlatetof/xlate.m451
-rw-r--r--test/libelf/tset/elf64_xlatetom/Makefile7
-rw-r--r--test/libelf/tset/elf64_xlatetom/xlate.m452
-rw-r--r--test/libelf/tset/elf_begin/Makefile23
-rw-r--r--test/libelf/tset/elf_begin/begin.m4636
-rw-r--r--test/libelf/tset/elf_cntl/Makefile16
-rw-r--r--test/libelf/tset/elf_cntl/cntl.m4217
-rw-r--r--test/libelf/tset/elf_end/Makefile7
-rw-r--r--test/libelf/tset/elf_end/end.m4100
-rw-r--r--test/libelf/tset/elf_errmsg/Makefile7
-rw-r--r--test/libelf/tset/elf_errmsg/errmsg.m4153
-rw-r--r--test/libelf/tset/elf_errno/Makefile7
-rw-r--r--test/libelf/tset/elf_errno/errno.m4185
-rw-r--r--test/libelf/tset/elf_fill/Makefile7
-rw-r--r--test/libelf/tset/elf_fill/fill.m4558
-rw-r--r--test/libelf/tset/elf_flagarhdr/Makefile16
-rw-r--r--test/libelf/tset/elf_flagarhdr/flagarhdr.m498
-rw-r--r--test/libelf/tset/elf_flagdata/Makefile7
-rw-r--r--test/libelf/tset/elf_flagdata/data.m4110
-rw-r--r--test/libelf/tset/elf_flagehdr/Makefile8
-rw-r--r--test/libelf/tset/elf_flagehdr/ehdr.m4115
-rw-r--r--test/libelf/tset/elf_flagelf/Makefile17
-rw-r--r--test/libelf/tset/elf_flagelf/elf.m4133
-rw-r--r--test/libelf/tset/elf_flagphdr/Makefile8
-rw-r--r--test/libelf/tset/elf_flagphdr/phdr.m4117
-rw-r--r--test/libelf/tset/elf_flagscn/Makefile7
-rw-r--r--test/libelf/tset/elf_flagscn/scn.m491
-rw-r--r--test/libelf/tset/elf_flagshdr/Makefile7
-rw-r--r--test/libelf/tset/elf_flagshdr/shdr.m491
-rw-r--r--test/libelf/tset/elf_fsize/Makefile8
-rw-r--r--test/libelf/tset/elf_fsize/fsize.m4273
-rw-r--r--test/libelf/tset/elf_getarhdr/Makefile29
-rw-r--r--test/libelf/tset/elf_getarhdr/getarhdr.m4471
-rw-r--r--test/libelf/tset/elf_getarsym/Makefile40
-rw-r--r--test/libelf/tset/elf_getarsym/getarsym.m4363
-rw-r--r--test/libelf/tset/elf_getbase/Makefile7
-rw-r--r--test/libelf/tset/elf_getbase/getbase.m4100
-rw-r--r--test/libelf/tset/elf_getdata/Makefile8
-rw-r--r--test/libelf/tset/elf_getdata/getdata.m4203
-rw-r--r--test/libelf/tset/elf_getident/Makefile7
-rw-r--r--test/libelf/tset/elf_getident/getident.m4168
-rw-r--r--test/libelf/tset/elf_getscn/Makefile8
-rw-r--r--test/libelf/tset/elf_getscn/getscn.m4313
-rw-r--r--test/libelf/tset/elf_getshnum/Makefile8
-rw-r--r--test/libelf/tset/elf_getshnum/getshnum.m4177
-rw-r--r--test/libelf/tset/elf_getshstrndx/Makefile8
-rw-r--r--test/libelf/tset/elf_getshstrndx/getshstrndx.m4180
-rw-r--r--test/libelf/tset/elf_hash/Makefile7
-rw-r--r--test/libelf/tset/elf_hash/hash.m4101
-rw-r--r--test/libelf/tset/elf_kind/Makefile7
-rw-r--r--test/libelf/tset/elf_kind/kind.m4122
-rw-r--r--test/libelf/tset/elf_memory/Makefile7
-rw-r--r--test/libelf/tset/elf_memory/memory.m4240
-rw-r--r--test/libelf/tset/elf_ndxscn/Makefile8
-rw-r--r--test/libelf/tset/elf_ndxscn/ndxscn.m4119
-rw-r--r--test/libelf/tset/elf_newscn/Makefile8
-rw-r--r--test/libelf/tset/elf_newscn/newscn.m4290
-rw-r--r--test/libelf/tset/elf_next/Makefile36
-rw-r--r--test/libelf/tset/elf_next/next.m4151
-rw-r--r--test/libelf/tset/elf_nextscn/Makefile8
-rw-r--r--test/libelf/tset/elf_nextscn/nextscn.m4378
-rw-r--r--test/libelf/tset/elf_rawfile/Makefile7
-rw-r--r--test/libelf/tset/elf_rawfile/rawfile.m4154
-rw-r--r--test/libelf/tset/elf_strptr/Makefile8
-rw-r--r--test/libelf/tset/elf_strptr/strptr.m4363
-rw-r--r--test/libelf/tset/elf_update/Makefile8
-rw-r--r--test/libelf/tset/elf_update/update.m42308
-rw-r--r--test/libelf/tset/elf_version/Makefile7
-rw-r--r--test/libelf/tset/elf_version/version.m4185
-rw-r--r--test/libelf/tset/gelf_getclass/Makefile8
-rw-r--r--test/libelf/tset/gelf_getclass/getclass.m487
-rw-r--r--test/libelf/tset/gelf_getehdr/Makefile8
-rw-r--r--test/libelf/tset/gelf_getehdr/ehdr.m4282
-rw-r--r--test/libelf/tset/gelf_newehdr/Makefile8
-rw-r--r--test/libelf/tset/gelf_newehdr/ehdr.m4470
-rw-r--r--test/libelf/tset/gelf_xlate/Makefile8
-rw-r--r--test/libelf/tset/gelf_xlate/xlate.m41356
137 files changed, 20405 insertions, 0 deletions
diff --git a/test/libelf/tset/Makefile b/test/libelf/tset/Makefile
new file mode 100644
index 0000000000000..707a3ab82137b
--- /dev/null
+++ b/test/libelf/tset/Makefile
@@ -0,0 +1,58 @@
+#
+# $Id: Makefile 1638 2011-07-10 15:43:19Z jkoshy $
+#
+
+SUBDIR+= common # must be first
+
+SUBDIR+= abi
+SUBDIR+= elf_begin
+SUBDIR+= elf_cntl
+SUBDIR+= elf_end
+SUBDIR+= elf_errmsg
+SUBDIR+= elf_errno
+SUBDIR+= elf_fill
+SUBDIR+= elf_flagarhdr
+SUBDIR+= elf_flagdata
+SUBDIR+= elf_flagehdr
+SUBDIR+= elf_flagelf
+SUBDIR+= elf_flagphdr
+SUBDIR+= elf_flagscn
+SUBDIR+= elf_flagshdr
+SUBDIR+= elf_fsize
+SUBDIR+= elf_getarhdr
+SUBDIR+= elf_getarsym
+SUBDIR+= elf_getbase
+SUBDIR+= elf_getdata
+SUBDIR+= elf_getident
+SUBDIR+= elf_getscn
+SUBDIR+= elf_getshnum
+SUBDIR+= elf_getshstrndx
+SUBDIR+= elf_hash
+SUBDIR+= elf_kind
+SUBDIR+= elf_memory
+SUBDIR+= elf_ndxscn
+SUBDIR+= elf_next
+SUBDIR+= elf_newscn
+SUBDIR+= elf_nextscn
+SUBDIR+= elf_rawfile
+SUBDIR+= elf_strptr
+SUBDIR+= elf_update
+SUBDIR+= elf_version
+SUBDIR+= elf32_getehdr
+SUBDIR+= elf32_getphdr
+SUBDIR+= elf32_getshdr
+SUBDIR+= elf32_newehdr
+SUBDIR+= elf32_xlatetof
+SUBDIR+= elf32_xlatetom
+SUBDIR+= elf64_getehdr
+SUBDIR+= elf64_getphdr
+SUBDIR+= elf64_getshdr
+SUBDIR+= elf64_newehdr
+SUBDIR+= elf64_xlatetof
+SUBDIR+= elf64_xlatetom
+SUBDIR+= gelf_getclass
+SUBDIR+= gelf_getehdr
+SUBDIR+= gelf_newehdr
+SUBDIR+= gelf_xlate
+
+.include <bsd.subdir.mk>
diff --git a/test/libelf/tset/Makefile.tset b/test/libelf/tset/Makefile.tset
new file mode 100644
index 0000000000000..45ae4d68d065e
--- /dev/null
+++ b/test/libelf/tset/Makefile.tset
@@ -0,0 +1,36 @@
+# $Id: Makefile.tset 2077 2011-10-27 03:59:40Z jkoshy $
+
+# All the test cases in this test suite need -lelf.
+DPADD+= ${LIBELF}
+LDADD+= -lelf
+
+GENERATE_TEST_SCAFFOLDING= yes
+
+# Add a file name to TS_YAML if all four variants of the generated ELF
+# object are needed.
+.if defined(TS_YAML)
+.for yaml in ${TS_YAML}
+.for sufx in lsb32 lsb64 msb32 msb64
+TS_DATA+= ${yaml}.${sufx}
+.endfor
+.endfor
+.endif
+
+# Copy ELF binaries used by test cases to the build directory so that
+# the test binaries have access to them.
+_TS_YAMLOBJ?= ${TS_DATA:M*.msb32} ${TS_DATA:M*.lsb32} ${TS_DATA:M*.msb64} \
+ ${TS_DATA:M*.lsb64}
+.for f in ${_TS_YAMLOBJ}
+.if exists(${TS_OBJROOT}/common/${f})
+_YO= ${TS_OBJROOT}/common/${f}
+.elif exists(${TS_ROOT}/common/obj/${f})
+_YO= ${TS_ROOT}/common/obj/${f}
+.else
+_YO= /nonexistent
+.endif
+${f}: ${_YO}
+ @cp ${.ALLSRC} ${.TARGET}
+.endfor
+
+# Test cases do not supply manual pages.
+NOMAN= noman
diff --git a/test/libelf/tset/abi/Makefile b/test/libelf/tset/abi/Makefile
new file mode 100644
index 0000000000000..7a94fdf6c7705
--- /dev/null
+++ b/test/libelf/tset/abi/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 2077 2011-10-27 03:59:40Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= abi.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/abi/abi.m4 b/test/libelf/tset/abi/abi.m4
new file mode 100644
index 0000000000000..4d946cb3f6c67
--- /dev/null
+++ b/test/libelf/tset/abi/abi.m4
@@ -0,0 +1,296 @@
+/*-
+ * Copyright (c) 2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: abi.m4 2077 2011-10-27 03:59:40Z jkoshy $
+ */
+
+/*
+ * Tests for ABI values.
+ *
+ * See: http://www.sco.com/developers/gabi/latest/ch4.eheader.html
+ */
+
+#include <libelf.h>
+
+#include "tet_api.h"
+
+include(`elfts.m4')
+
+undefine(`FN')
+define(`FN',`
+void
+tcCheck$1(void)
+{
+ int result;
+ const size_t nconst = sizeof($2) / sizeof ($2[0]);
+ size_t n;
+
+ TP_ANNOUNCE("Check " $3 " values");
+
+ result = TET_FAIL;
+
+ for (n = 0; n < nconst; n++)
+ if ($2[n].symbol != $2[n].value)
+ goto done;
+
+ result = TET_PASS;
+
+done:
+ tet_result(result);
+}
+')
+
+struct _sym {
+ size_t symbol;
+ size_t value;
+};
+
+/*
+ * Check ELFOSABI_* values.
+ */
+struct _sym elf_osabi[] = {
+ { ELFOSABI_NONE, 0},
+ { ELFOSABI_SYSV, 0},
+ { ELFOSABI_HPUX, 1},
+ { ELFOSABI_NETBSD, 2},
+ { ELFOSABI_GNU, 3},
+ { ELFOSABI_HURD, 4},
+ { ELFOSABI_86OPEN, 5},
+ { ELFOSABI_SOLARIS, 6},
+ { ELFOSABI_AIX, 7},
+ { ELFOSABI_IRIX, 8},
+ { ELFOSABI_FREEBSD, 9},
+ { ELFOSABI_TRU64, 10},
+ { ELFOSABI_MODESTO, 11},
+ { ELFOSABI_OPENBSD, 12},
+ { ELFOSABI_OPENVMS, 13},
+ { ELFOSABI_NSK, 14},
+ { ELFOSABI_AROS, 15},
+ { ELFOSABI_FENIXOS, 16}
+};
+
+FN(OsAbi, elf_osabi, "ELF_OSABI")
+
+/*
+ * Check EM_* values.
+ */
+struct _sym elf_em[] = {
+ { EM_NONE, 0 },
+ { EM_M32, 1 },
+ { EM_SPARC, 2 },
+ { EM_386, 3 },
+ { EM_68K, 4 },
+ { EM_88K, 5 },
+ { EM_860, 7 },
+ { EM_MIPS, 8 },
+ { EM_S370, 9 },
+ { EM_MIPS_RS3_LE, 10 },
+ { EM_PARISC, 15 },
+ { EM_VPP500, 17 },
+ { EM_SPARC32PLUS, 18 },
+ { EM_960, 19 },
+ { EM_PPC, 20 },
+ { EM_PPC64, 21 },
+ { EM_S390, 22 },
+ { EM_SPU, 23 },
+ { EM_V800, 36 },
+ { EM_FR20, 37 },
+ { EM_RH32, 38 },
+ { EM_RCE, 39 },
+ { EM_ARM, 40 },
+ { EM_ALPHA, 41 },
+ { EM_SH, 42 },
+ { EM_SPARCV9, 43 },
+ { EM_TRICORE, 44 },
+ { EM_ARC, 45 },
+ { EM_H8_300, 46 },
+ { EM_H8_300H, 47 },
+ { EM_H8S, 48 },
+ { EM_H8_500, 49 },
+ { EM_IA_64, 50 },
+ { EM_MIPS_X, 51 },
+ { EM_COLDFIRE, 52 },
+ { EM_68HC12, 53 },
+ { EM_MMA, 54 },
+ { EM_PCP, 55 },
+ { EM_NCPU, 56 },
+ { EM_NDR1, 57 },
+ { EM_STARCORE, 58 },
+ { EM_ME16, 59 },
+ { EM_ST100, 60 },
+ { EM_TINYJ, 61 },
+ { EM_X86_64, 62 },
+ { EM_PDSP, 63 },
+ { EM_PDP10, 64 },
+ { EM_PDP11, 65 },
+ { EM_FX66, 66 },
+ { EM_ST9PLUS, 67 },
+ { EM_ST7, 68 },
+ { EM_68HC16, 69 },
+ { EM_68HC11, 70 },
+ { EM_68HC08, 71 },
+ { EM_68HC05, 72 },
+ { EM_SVX, 73 },
+ { EM_ST19, 74 },
+ { EM_VAX, 75 },
+ { EM_CRIS, 76 },
+ { EM_JAVELIN, 77 },
+ { EM_FIREPATH, 78 },
+ { EM_ZSP, 79 },
+ { EM_MMIX, 80 },
+ { EM_HUANY, 81 },
+ { EM_PRISM, 82 },
+ { EM_AVR, 83 },
+ { EM_FR30, 84 },
+ { EM_D10V, 85 },
+ { EM_D30V, 86 },
+ { EM_V850, 87 },
+ { EM_M32R, 88 },
+ { EM_MN10300, 89 },
+ { EM_MN10200, 90 },
+ { EM_PJ, 91 },
+ { EM_OPENRISC, 92 },
+ { EM_ARC_COMPACT, 93 },
+ { EM_XTENSA, 94 },
+ { EM_VIDEOCORE, 95 },
+ { EM_TMM_GPP, 96 },
+ { EM_NS32K, 97 },
+ { EM_TPC, 98 },
+ { EM_SNP1K, 99 },
+ { EM_ST200, 100 },
+ { EM_IP2K, 101 },
+ { EM_MAX, 102 },
+ { EM_CR, 103 },
+ { EM_F2MC16, 104 },
+ { EM_MSP430, 105 },
+ { EM_BLACKFIN, 106 },
+ { EM_SE_C33, 107 },
+ { EM_SEP, 108 },
+ { EM_ARCA, 109 },
+ { EM_UNICORE, 110 },
+ { EM_EXCESS, 111 },
+ { EM_DXP, 112 },
+ { EM_ALTERA_NIOS2, 113 },
+ { EM_CRX, 114 },
+ { EM_XGATE, 115 },
+ { EM_C166, 116 },
+ { EM_M16C, 117 },
+ { EM_DSPIC30F, 118 },
+ { EM_CE, 119 },
+ { EM_M32C, 120 },
+ { EM_TSK3000, 131 },
+ { EM_RS08, 132 },
+ { EM_SHARC, 133 },
+ { EM_ECOG2, 134 },
+ { EM_SCORE7, 135 },
+ { EM_DSP24, 136 },
+ { EM_VIDEOCORE3, 137 },
+ { EM_LATTICEMICO32, 138 },
+ { EM_SE_C17, 139 },
+ { EM_TI_C6000, 140 },
+ { EM_TI_C2000, 141 },
+ { EM_TI_C5500, 142 },
+ { EM_MMDSP_PLUS, 160 },
+ { EM_CYPRESS_M8C, 161 },
+ { EM_R32C, 162 },
+ { EM_TRIMEDIA, 163 },
+ { EM_QDSP6, 164 },
+ { EM_8051, 165 },
+ { EM_STXP7X, 166 },
+ { EM_NDS32, 167 },
+ { EM_ECOG1, 168 },
+ { EM_ECOG1X, 168 },
+ { EM_MAXQ30, 169 },
+ { EM_XIMO16, 170 },
+ { EM_MANIK, 171 },
+ { EM_CRAYNV2, 172 },
+ { EM_RX, 173 },
+ { EM_METAG, 174 },
+ { EM_MCST_ELBRUS, 175 },
+ { EM_ECOG16, 176 },
+ { EM_CR16, 177 },
+ { EM_ETPU, 178 },
+ { EM_SLE9X, 179 },
+ { EM_AVR32, 185 },
+ { EM_STM8, 186 },
+ { EM_TILE64, 187 },
+ { EM_TILEPRO, 188 },
+ { EM_MICROBLAZE, 189 },
+ { EM_CUDA, 190 },
+ { EM_TILEGX, 191 },
+ { EM_CLOUDSHIELD, 192 },
+ { EM_COREA_1ST, 193 },
+ { EM_COREA_2ND, 194 },
+ { EM_ARC_COMPACT2, 195 },
+ { EM_OPEN8, 196 },
+ { EM_RL78, 197 },
+ { EM_VIDEOCORE5, 198 },
+ { EM_78KOR, 199 },
+};
+
+FN(ElfMachine, elf_em, "EM_*")
+
+/*
+ * Check ET_* values.
+ */
+struct _sym elf_type[] = {
+ { ET_NONE, 0 },
+ { ET_REL, 1 },
+ { ET_EXEC, 2 },
+ { ET_DYN, 3 },
+ { ET_CORE, 4 }
+};
+
+FN(ElfType, elf_type, "ET_*")
+
+/*
+ * Check values for miscellaneous ABI symbols.
+ */
+struct _sym elf_misc[] = {
+ { EV_NONE, 0 },
+ { EV_CURRENT, 1 },
+ { EI_MAG0, 0 },
+ { EI_MAG1, 1 },
+ { EI_MAG2, 2 },
+ { EI_MAG3, 3 },
+ { EI_CLASS, 4 },
+ { EI_DATA, 5 },
+ { EI_VERSION, 6 },
+ { EI_OSABI, 7 },
+ { EI_ABIVERSION, 8 },
+ { EI_NIDENT, 16 },
+ { ELFMAG0, 0x7F },
+ { ELFMAG1, 'E' },
+ { ELFMAG2, 'L' },
+ { ELFMAG3, 'F' },
+ { ELFCLASSNONE, 0 },
+ { ELFCLASS32, 1 },
+ { ELFCLASS64, 2 },
+ { ELFDATANONE, 0 },
+ { ELFDATA2LSB, 1 },
+ { ELFDATA2MSB, 2 },
+};
+
+FN(ElfMisc, elf_misc, "miscellaneous symbol");
diff --git a/test/libelf/tset/bin/elf-hash b/test/libelf/tset/bin/elf-hash
new file mode 100755
index 0000000000000..ca9277354b288
--- /dev/null
+++ b/test/libelf/tset/bin/elf-hash
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+#
+# $Id: elf-hash 2054 2011-10-26 12:12:06Z jkoshy $
+
+import sys, os
+
+def elf_hash(s):
+ """A python implementation of elf_hash(3)."""
+ h = 0L
+ for c in s:
+ h = (h << 4) + ord(c)
+ t = (h & 0xF0000000L)
+ if t != 0:
+ h = h ^ (t >> 24)
+ h = h & ~t
+ return h
+
+
+if __name__ == '__main__':
+ from optparse import OptionParser
+
+ usage = "usage: %prog [options] files...\n" + \
+ " print ELF hash values for strings or file contents"
+
+ p = OptionParser(usage=usage)
+ p.add_option("-s", "--string", dest="hash_strings",
+ action="append", metavar="STRING",
+ help="compute hash for STRING")
+
+ options, args = p.parse_args()
+ if not options.hash_strings and not args:
+ p.print_help()
+ sys.exit(1)
+
+ if options.hash_strings:
+ for s in options.hash_strings:
+ print "\"%s\" 0x%x" % (s, elf_hash(s))
+ for f in args:
+ print "[%s] 0x%x" % (f, elf_hash(open(f,'r').read()))
diff --git a/test/libelf/tset/bin/elfc b/test/libelf/tset/bin/elfc
new file mode 100755
index 0000000000000..99fa859f5a68f
--- /dev/null
+++ b/test/libelf/tset/bin/elfc
@@ -0,0 +1,1615 @@
+#!/usr/bin/env python
+#
+# This script converts a textual (YAML) description of an ELF file to
+# an equivalent 'binary' file.
+#
+# The YAML description may have the following top-level keys:
+#
+# 'elf_fillchar': char
+# Sets the fill character to 'char'.
+# 'ehdr': EHDR-DESCRIPTOR
+# Defines an ELF Ehdr structure.
+# 'phdrtab': list-of(PHDR-DESCRIPTOR)
+# Defines the contents of the ELF Program Header table.
+# Each `Phdr' descriptor represents one ELF Phdr entry.
+# 'sections': list-of(SECTION-DESCRIPTOR)
+# Defines the content of each section in the file. Each
+# `SECTION-DESCRIPTOR' contains information for the
+# section `header' and the actual data for the section.
+#
+# The script will compute reasonable defaults for any fields
+# left unspecified in the YAML description.
+#
+# Descriptors EHDR-DESCRIPTOR and PHDR-DESCRIPTOR may be specified
+# as a YAML key-value set. The key names correspond to the
+# field names of the corresponding ELF structures, e.g., 'e_machine'
+# and 'e_ident' for the Ehdr and 'p_type' and 'p_paddr' for
+# a Phdr entry.
+#
+# Descriptor SECTION-DESCRIPTOR contains the fields in an ELF
+# Shdr structure and an additional member 'sh_data', whose
+# value is the data for the section.
+#
+# Example:
+#
+# <snip>
+# ehdr: !Ehdr
+# e_ident: !Ident
+# ei_class: ELFCLASS32
+# ei_data: ELFDATA2MSB
+# e_machine: EM_PPC
+# phdrtab:
+# - !Phdr
+# ph_type: PHT_NULL
+# ... other program header fields ...
+# - !Phdr
+# ... etc. ...
+# sections:
+# - !Section
+# sh_name: .dynsym
+# ... other section header fields ...
+# sh_data: # ... list of data ...
+# - !Dyn
+# d_tag: 0xdeadcode
+# - !Dyn
+# d_tag: 0xcafebabe
+# - !Section
+# sh_name: .shstrtab
+# sh_type: SHT_STRTAB
+# sh_data:
+# - string1
+# - string2
+# </snip>
+#
+# :: Handling of strings ::
+#
+# Fields like 'sh_name' (in a section header) are defined to contain
+# an integer index into a specified string table (in this case a
+# section with name '.shstrtab'). Other ELF data structures use a
+# similar convention; names in a '.dynamic' section as stored as
+# indices into a '.dynstr' section. In the YAML descriptor, such
+# fields may be specified as indices, which are used as-is, or as text
+# strings which are converted to the appropriate string index.
+# For convenience in creating ELF objects with a large number of
+# sections, a section index may be manually specified using a
+# 'sh_index' pseudo field.
+#
+# $Id: elfc 1718 2011-08-12 07:30:43Z jkoshy $
+
+version = "%prog 1.0"
+usage = "usage: %prog [options] [input-file]"
+description = """Create an ELF binary from a textual description in """ + \
+ """'input-file' (or stdin)"""
+
+import optparse, re, struct, sys, types, yaml
+
+class ElfError(Exception):
+ """An exception signalled during conversion."""
+
+ def __init__(self, node=None, msg=None):
+ """Initialize an exception object.
+
+ Arguments:
+ node -- a YAML parse tree node.
+ msg -- human readable message associated with this
+ exception.
+ """
+ if node:
+ self.ee_start = node.start_mark.line + 1
+ self.ee_end = node.end_mark.line + 1
+ else:
+ self.ee_start = self.ee_end = -1
+ self.ee_msg = msg
+
+ def __str__(self):
+ """Form a printable representation of an exception."""
+
+ if self.ee_start != -1:
+ if self.ee_start == self.ee_end:
+ return "Error: line %d: %s" % (self.ee_start,
+ self.ee_msg)
+ else:
+ return "Error: lines %d--%d: %s" % \
+ (self.ee_start, self.ee_end,
+ self.ee_msg)
+ else:
+ return "Error: %s" % self.ee_msg
+
+
+#
+# Mappings used by the 'encode()' function
+#
+
+elf_cap_tag = {
+ 'CA_SUNW_NULL': 0, 'CA_SUNW_HW_1': 1, 'CA_SUNW_SF_1': 2
+}
+
+elf_d_flags = {
+ 'DF_ORIGIN': 0x0001, 'DF_SYMBOLIC': 0x0002, 'DF_TEXTREL': 0x0004,
+ 'DF_BIND_NOW': 0x0006, 'DF_STATIC_TLS': 0x0010
+}
+
+elf_d_tag = {
+ # from <sys/elf_common.h>
+ 'DT_NULL': 0, 'DT_NEEDED': 1, 'DT_PLTRELSZ': 2, 'DT_PLTGOT': 3,
+ 'DT_HASH': 4, 'DT_STRTAB': 5, 'DT_SYMTAB': 6, 'DT_RELA': 7,
+ 'DT_RELASZ': 8, 'DT_RELAENT': 9, 'DT_STRSZ': 10, 'DT_SYMENT': 11,
+ 'DT_INIT': 12, 'DT_FINI': 13, 'DT_SONAME': 14, 'DT_RPATH': 15,
+ 'DT_SYMBOLIC': 16, 'DT_REL': 17, 'DT_RELSZ': 18, 'DT_RELENT': 19,
+ 'DT_PLTREL': 20, 'DT_DEBUG': 21, 'DT_TEXTREL': 22, 'DT_JMPREL': 23,
+ 'DT_BIND_NOW': 24, 'DT_INIT_ARRAY': 25,'DT_FINI_ARRAY': 26,
+ 'DT_INIT_ARRAYSZ': 27, 'DT_FINI_ARRAYSZ': 28, 'DT_RUNPATH': 29,
+ 'DT_FLAGS': 30, 'DT_ENCODING': 32, 'DT_PREINIT_ARRAY': 32,
+ 'DT_PREINIT_ARRAYSZ': 33, 'DT_LOOS': 0x6000000d, 'DT_HIOS': 0x6ffff000,
+ 'DT_LOPROC': 0x70000000, 'DT_HIPROC': 0x7fffffff,
+ 'DT_SUNW_AUXILIARY': 0x6000000D, 'DT_SUNW_RTLDINF': 0x6000000E,
+ 'DT_SUNW_FILTER': 0x6000000F, 'DT_SUNW_CAP': 0x60000010,
+ # from "usr.bin/elfdump/elfdump.c"
+ 'DT_GNU_PRELINKED': 0x6ffffdf5, 'DT_GNU_CONFLICTSZ': 0x6ffffdf6,
+ 'DT_GNU_LIBLISTSZ': 0x6ffffdf7, 'DT_SUNW_CHECKSUM': 0x6ffffdf78,
+ 'DT_PLTPADSZ': 0x6ffffdf79, 'DT_MOVEENT': 0x6ffffdfa,
+ 'DT_MOVESZ': 0x6ffffdfb, 'DT_FEATURE': 0x6ffffdfc,
+ 'DT_FEATURE': 0x6ffffdfd, 'DT_POSFLAG_1': 0x6ffffdfe,
+ 'DT_SYMINENT': 0x6ffffdff, 'DT_VALRNGHI': 0x6ffffdff, # dup
+ 'DT_ADDRRNGLO': 0x6ffffe00, 'DT_GNU_CONFLICT': 0x6ffffef8,
+ 'DT_GNU_LIBLIST': 0x6ffffef9, 'DT_SUNW_CONFIG': 0x6ffffefa,
+ 'DT_SUNW_DEPAUDIT': 0x6ffffefb, 'DT_SUNW_AUDIT': 0x6ffffefc,
+ 'DT_SUNW_PLTPAD': 0x6ffffefd, 'DT_SUNW_MOVETAB': 0x6ffffefe,
+ 'DT_SYMINFO': 0x6ffffeff, 'DT_ADDRRNGHI': 0x6ffffeff, # dup
+ 'DT_VERSYM': 0x6ffffff0, 'DT_GNU_VERSYM': 0x6ffffff0, # dup
+ 'DT_RELACOUNT': 0x6ffffff9, 'DT_RELCOUNT': 0x6ffffffa,
+ 'DT_FLAGS_1': 0x6ffffffb, 'DT_VERDEF': 0x6ffffffc,
+ 'DT_VERDEFNUM': 0x6ffffffd, 'DT_VERNEED': 0x6ffffffe,
+ 'DT_VERNEEDNUM': 0x6fffffff,
+ 'DT_IA_64_PLT_RESERVE': 0x70000000, 'DT_SUNW_AUXILIARY': 0x7ffffffd,
+ 'DT_SUNW_USED': 0x7ffffffe, 'DT_SUNW_FILTER': 0x7fffffff
+}
+
+elf_dyn_fields = [ 'd_tag', 'd_val', 'd_ptr' ]
+
+elf_ehdr_flags = { # no known flags
+}
+
+elf_ehdr_type = { # e_type
+ 'ET_NONE': 0, 'ET_REL': 1, 'ET_EXEC': 2, 'ET_DYN': 3, 'ET_CORE': 4
+}
+
+elf_ehdr_machine = { # e_machine
+ 'EM_NONE': 0, 'EM_M32': 1, 'EM_SPARC': 2, 'EM_386': 3, 'EM_68K': 4,
+ 'EM_88K': 5, 'EM_486': 6, 'EM_860': 7, 'EM_MIPS': 8, 'EM_S370': 9,
+ 'EM_MIPS_RS3_LE': 10, 'EM_MIPS_RS4_BE': 10, 'EM_PARISC': 15,
+ 'EM_VPP500': 17, 'EM_SPARC32PLUS': 18, 'EM_960': 19, 'EM_PPC': 20,
+ 'EM_PPC64': 21, 'EM_S390': 22, 'EM_V800': 36, 'EM_FR20': 37,
+ 'EM_RH32': 38, 'EM_RCE': 39, 'EM_ARM': 40, 'EM_ALPHA_STD': 41,
+ 'EM_SH': 42, 'EM_SPARCV9': 43, 'EM_TRICORE': 44, 'EM_ARC': 45,
+ 'EM_H8_300': 46, 'EM_H8_300H': 47, 'EM_H8S': 48, 'EM_H8_500': 49,
+ 'EM_IA_64': 50, 'EM_MIPS_X': 51, 'EM_COLDFIRE': 52,
+ 'EM_68HC12': 53, 'EM_MMA': 54, 'EM_PCP': 55, 'EM_NCPU': 56,
+ 'EM_NDR1': 57, 'EM_STARCORE': 58, 'EM_ME16': 59, 'EM_ST100': 60,
+ 'EM_TINYJ': 61, 'EM_X86_64': 62, 'EM_ALPHA': 0x9026
+}
+
+elf_ei_version = { # e_version
+ 'EV_NONE': 0, 'EV_CURRENT': 1
+}
+
+elf_ei_class = {
+ 'ELFCLASSNONE': 0, 'ELFCLASS32': 1, 'ELFCLASS64': 2
+}
+
+elf_ei_data = {
+ 'ELFDATANONE': 0, 'ELFDATA2LSB': 1, 'ELFDATA2MSB': 2
+}
+
+elf_ei_osabi = {
+ # Official values.
+ 'ELFOSABI_NONE': 0,
+ 'ELFOSABI_HPUX': 1,
+ 'ELFOSABI_NETBSD': 2,
+ 'ELFOSABI_GNU': 3,
+ 'ELFOSABI_HURD': 4,
+ 'ELFOSABI_86OPEN': 5,
+ 'ELFOSABI_SOLARIS': 6,
+ 'ELFOSABI_AIX': 7,
+ 'ELFOSABI_IRIX': 8,
+ 'ELFOSABI_FREEBSD': 9,
+ 'ELFOSABI_TRU64': 10,
+ 'ELFOSABI_MODESTO': 11,
+ 'ELFOSABI_OPENBSD': 12,
+ 'ELFOSABI_OPENVMS': 13,
+ 'ELFOSABI_NSK': 14,
+ 'ELFOSABI_ARM': 97,
+ 'ELFOSABI_STANDALONE': 255,
+ # Aliases.
+ 'ELFOSABI_SYSV': 0,
+ 'ELFOSABI_LINUX': 3,
+ 'ELFOSABI_MONTEREY': 7
+}
+
+elf_ph_fields = [ 'p_align', 'p_filesz', 'p_flags', 'p_memsz', 'p_offset',
+ 'p_paddr', 'p_type', 'p_vaddr' ]
+
+elf_ph_flags = {
+ 'PF_X': 0x1, 'PF_W': 0x2, 'PF_R': 0x4
+}
+
+elf_ph_type = {
+ 'PT_NULL': 0, 'PT_LOAD': 1, 'PT_DYNAMIC': 2, 'PT_INTERP': 3,
+ 'PT_NOTE': 4, 'PT_SHLIB': 5, 'PT_PHDR': 6, 'PT_TLS': 7,
+ 'PT_LOOS': 0x60000000, 'PT_HIOS': 0x6FFFFFFF,
+ 'PT_SUNW_UNWIND': 0x6464E550, 'PT_GNU_EHFRAME': 0x6464E550, # dup
+ 'PT_SUNWBSS': 0x6FFFFFFA, 'PT_SUNWSTACK': 0x6FFFFFFB,
+ 'PT_SUNWDTRACE': 0x6FFFFFFC, 'PT_SUNWCAP': 0x6FFFFFFD,
+ 'PT_LOPROC': 0x70000000, 'PT_HIPROC': 0x7FFFFFFF
+}
+
+elf_sh_type = {
+ 'SHT_NULL': 0, 'SHT_PROGBITS': 1, 'SHT_SYMTAB': 2, 'SHT_STRTAB': 3,
+ 'SHT_RELA': 4, 'SHT_HASH': 5, 'SHT_DYNAMIC': 6, 'SHT_NOTE': 7,
+ 'SHT_NOBITS': 8, 'SHT_REL': 9, 'SHT_SHLIB': 10, 'SHT_DYNSYM': 11,
+ 'SHT_INIT_ARRAY': 14, 'SHT_FINI_ARRAY': 15, 'SHT_PREINIT_ARRAY': 16,
+ 'SHT_GROUP': 17, 'SHT_SYMTAB_SHNDX': 18, 'SHT_LOOS': 0x60000000,
+ 'SHT_HIOS': 0x6fffffff, 'SHT_LOPROC': 0x70000000,
+ 'SHT_HIPROC': 0x7fffffff, 'SHT_LOUSER': 0x80000000,
+ 'SHT_HIUSER': 0xffffffff,
+ # OS specific types
+ 'SHT_SUNW_dof': 0x6FFFFFF4, 'SHT_SUNW_cap': 0x6FFFFFF5,
+ 'SHT_SUNW_SIGNATURE': 0x6FFFFFF6,
+ 'SHT_SUNW_ANNOTATE': 0x6FFFFFF7, 'SHT_GNU_LIBLIST': 0x6ffffff7, # dup
+ 'SHT_SUNW_DEBUGSTR': 0x6FFFFFF8, 'SHT_SUNW_DEBUG': 0x6FFFFFF9,
+ 'SHT_SUNW_move': 0x6FFFFFFA, 'SHT_SUNW_COMDAT': 0x6FFFFFFB,
+ 'SHT_SUNW_syminfo': 0x6FFFFFFC,
+ 'SHT_GNU_verdef': 0x6ffffffd, 'SHT_SUNW_verdef': 0x6ffffffd, # dup
+ 'SHT_GNU_verneed': 0x6ffffffe, 'SHT_SUNW_verneed': 0x6ffffffe, # dup
+ 'SHT_GNU_versym': 0x6fffffff, 'SHT_SUNW_versym': 0x6fffffff, # dup
+ # Processor specific types
+ 'SHT_IA_64_EXT': 0x70000000, 'SHT_IA_64_UNWIND': 0x70000001
+}
+
+elf_sh_flags = {
+ 'SHF_WRITE': 0x1, 'SHF_ALLOC': 0x2, 'SHF_EXECINSTR': 0x4,
+ 'SHF_MERGE': 0x10, 'SHF_STRINGS': 0x20, 'SHF_INFO_LINK': 0x40,
+ 'SHF_LINK_ORDER': 0x80, 'SHF_OS_NONCONFORMING': 0x100,
+ 'SHF_GROUP': 0x200, 'SHF_TLS': 0x400, 'SHF_MASKOS': 0x0ff00000,
+ 'SHF_MASKPROC': 0xf0000000
+}
+
+elf_st_bindings = {
+ 'STB_LOCAL': 0, 'STB_GLOBAL': 1, 'STB_WEAK': 2
+}
+
+elf_st_flags = {
+ 'SHF_WRITE': 1, 'SHF_ALLOC': 2, 'SHF_EXECINSTR': 4
+}
+
+elf_st_types = {
+ 'STT_NOTYPE': 0, 'STT_OBJECT': 1, 'STT_FUNC': 2, 'STT_SECTION': 3,
+ 'STT_FILE': 3
+}
+
+elf_syminfo_flags = {
+ 'SYMINFO_FLG_DIRECT': 1,
+ 'SYMINFO_FLG_PASSTHRU': 2, 'SYMINFO_FLG_FILTER': 2, # dup
+ 'SYMINFO_FLG_COPY': 4, 'SYMINFO_FLG_LAZYLOAD': 8,
+ 'SYMINFO_FLG_DIRECTBIND': 0x10, 'SYMINFO_FLG_NOEXTDIRECT': 0x20,
+ 'SYMINFO_FLG_AUXILIARY': 0x40
+}
+
+elf_syminfo_boundto_types = {
+ 'SYMINFO_BT_SELF': 0xFFFF, 'SYMINFO_BT_PARENT': 0xFFFE,
+ 'SYMINFO_BT_NONE': 0xFFFD, 'SYMINFO_BT_EXTERN': 0xFFFC
+}
+
+# Defaults
+
+defaults = {
+ # ElfDyn structures
+ 'd_tag': 'DT_NULL',
+ 'd_un': '0',
+
+ # fields in an ELf Executable Header
+ 'e_ehsize': None,
+ 'e_entry': '0',
+ 'e_flags': [ '0' ],
+ 'e_ident': None,
+ 'e_machine': 'EM_NONE',
+ 'e_phentsize': None,
+ 'e_phnum': None,
+ 'e_phoff': None,
+ 'e_shentsize': None,
+ 'e_shnum': None,
+ 'e_shoff': None,
+ 'e_shstrndx': None,
+ 'e_type': 'ET_NONE',
+ 'e_version': 'EV_CURRENT',
+ # e_ident bytes
+ 'ei_class': 'ELFCLASS32',
+ 'ei_data': 'ELFDATA2LSB',
+ 'ei_version': 'EV_CURRENT',
+ 'ei_osabi': 'ELFOSABI_NONE',
+ 'ei_abiversion': '0',
+ # File-wide defaults
+ 'elf_fillchar': '0',
+ # Elf Notes
+ 'n_namesz': None,
+ 'n_descsz': None,
+ 'n_type': '0',
+ 'n_data': [ "", "" ],
+ # Phdr
+ 'p_align': '1',
+ 'p_filesz': '0',
+ 'p_memsz': '0',
+ 'p_flags': [ '0' ],
+ 'p_offset': '0',
+ 'p_paddr': '0',
+ 'p_type': 'PT_NULL',
+ 'p_vaddr': '0',
+ # Shdr
+ 'sh_addr': '0',
+ 'sh_addralign': None,
+ 'sh_data': [],
+ 'sh_entsize': '0',
+ 'sh_flags': [ '0' ],
+ 'sh_info': '0',
+ 'sh_index': None,
+ 'sh_link': '0',
+ 'sh_name': '0',
+ 'sh_offset': None,
+ 'sh_size': None,
+ 'sh_type': 'SHT_NULL',
+ # Verdaux
+ 'vda_name': 0,
+ 'vda_next': 0,
+ # Verdef
+ 'vd_version': 1,
+ 'vd_flags': 0,
+ 'vd_ndx': 0,
+ 'vd_cnt': 0,
+ 'vd_hash': 0,
+ 'vd_aux': 0,
+ 'vd_next': 0,
+ # Vernaux
+ 'vna_hash': 0,
+ 'vna_flags': 0,
+ 'vna_other': 0,
+ 'vna_name': 0,
+ 'vna_next': 0,
+ # Verneed
+ 'vn_version': 1,
+ 'vn_cnt': 0,
+ 'vn_file': 0,
+ 'vn_aux': 0,
+ 'vn_next': 0
+}
+
+#
+# Module wide constants.
+#
+
+ELFCLASS32 = elf_ei_class['ELFCLASS32']
+ELFDATA2LSB = elf_ei_data['ELFDATA2LSB']
+SHT_NOBITS = elf_sh_type['SHT_NOBITS']
+SHT_NULL = elf_sh_type['SHT_NULL']
+SHT_STRTAB = elf_sh_type['SHT_STRTAB']
+SHN_LORESERVE= 0xFF00
+SHN_XINDEX = 0xFFFF
+#
+# Helper functions.
+#
+
+def get(d, key, default):
+ """Retrieve the value of 'key' from YAML dictionary 'd'.
+
+ The return value is guaranteed to be not 'None'.
+ """
+ v = d.get(key, default)
+ if v is None:
+ v = default
+ return v
+
+def encode(d, key, default, mapping):
+ """Return the numeric value of d[key] in map 'mapping'."""
+
+ v = get(d, key, default)
+ try:
+ return mapping[v]
+ except KeyError:
+ return int(v)
+
+def encode_flags(flags, m):
+ """Convert 'flags' to a single numeric value using mapping 'm'."""
+ try:
+ v = long(flags)
+ return v
+ except:
+ pass
+ v = 0L
+ for f in flags:
+ try:
+ t = long(m[f])
+ except KeyError:
+ t = long(f)
+ v |= t
+ return v
+
+def check_dict(d, l, node=None):
+ """Check a dictionary for unknown keys."""
+ unknown = []
+ for k in d.keys():
+ if k not in l:
+ unknown.append(k)
+ if len(unknown) > 0:
+ raise ElfError(node, "{%s} Unknown key(s) %s" % \
+ (node.tag, unknown))
+
+#
+# Helper classes.
+#
+
+class ElfStrTab:
+ """A ELF string table.
+
+ This class manages strings in an ELF string table section.
+ """
+
+ def __init__(self, strs=None):
+ """Initialize a string table from a list of strings."""
+ self.offset = 1 # reserve space for initial null byte
+ self.htab = {}
+ if type(strs) == types.StringType: # one string
+ self.add(strs)
+ elif type(strs) == types.ListType: # list of strings
+ for s in strs:
+ self.add(s)
+
+ def add(self, str):
+ """Add a string to the string table.
+
+ Returns the offset of the string in the ELF section."""
+ try:
+ return self.lookup(str)
+ except KeyError:
+ self.htab[str] = offset = self.offset
+ self.offset += len(str) + 1 # Keep space for a NUL.
+ return offset
+
+ def bits(self):
+ """Return the contents of an ELF string table."""
+
+ l = self.htab.items()
+ l.sort(lambda x, y: cmp(x[1],y[1])) # Order by string offset.
+ ls = [""] # initial NUL
+ for (ss,oo) in l:
+ ls.append(ss)
+ return "\000".join(ls) + "\000" # Add trailing NULs
+
+ def lookup(self, str):
+ """Return the ELF string table offset for string 'str'."""
+
+ return self.htab[str]
+
+
+class ElfType:
+ """A base type for ELF type descriptors.
+
+ Derived classes are expected to provide the following attributes:
+
+ 'fields' -- a list of 4-typles (name, fn, lsz, msz).
+
+ 'name' is the name of a field in the ELF structure.
+
+ 'fn' is a convertor function, one of the functions
+ 'do_(long,encode,flags)' below.
+
+ 'msz' and 'lsz' provide the appropriate sizes when
+ generating a binary representation of the type.
+ """
+
+ fields = None
+ def __init__(self, d, node):
+ """Initialize an ELF datatype from a YAML description.
+
+ Arguments:
+ d -- a dictionary containing name/value pairs specified
+ in the text description.
+ node -- YAML parser node for this element.
+ """
+
+ keys = map(lambda t: t[0], self.fields)
+ check_dict(d, keys, node)
+ for f in self.fields:
+ name = f[0]
+ fn = f[1]
+ try:
+ v = fn(d, name)
+ setattr(self,f[0],v)
+ except:
+ raise ElfError(node,
+ 'key: "%s" value: "%s" unrecognized.' % \
+ (name, d[name]))
+ self._n = node # Save YAML node and associated value
+ self._d = d # for error reporting.
+
+ def __getitem__(self, attrib):
+ """Allow an ELF type to be treated like a dictionary."""
+
+ return getattr(self, attrib)
+
+ def bits(self, formatchar, elfclass):
+ """Convert an ELF type to its file representation."""
+
+ format, args = self.getfields(elfclass)
+ return struct.pack(formatchar + format, *args)
+
+ def formatstring(self, elfclass):
+ """Return the format string for this type."""
+
+ if elfclass == ELFCLASS32:
+ n = 2
+ else:
+ n = 3
+ return "".join(map (lambda t: t[n], self.fields))
+
+ def content(self, elfclass):
+ """Return a tuple containing the values for an ELF type."""
+
+ a = []
+ if elfclass == ELFCLASS32:
+ n = 2
+ else:
+ n = 3
+ for t in self.fields:
+ if t[n] != "":
+ a.append(getattr(self, t[0]))
+ return tuple(a)
+
+ def getfields(self, elfclass):
+ """Describe the binary layout of the type.
+
+ Return a tuple (formatstring, *args) describing the
+ desired binary layout in the manner of the 'struct'
+ python library module.
+ """
+
+ return (self.formatstring(elfclass),
+ self.content(elfclass))
+
+ def layout(self, offset, elf):
+ """Perform any layout-time translation for an ELF type."""
+
+ return offset
+
+ def size(self, elfclass):
+ """Return the size of the type in bytes.
+
+ The size returned is independent of the alignment needs of
+ the type.
+ """
+
+ format = self.formatstring(elfclass)
+ sz = 0
+ for f in format:
+ if f == "B":
+ sz += 1
+ elif f == "H":
+ sz += 2
+ elif f == "I":
+ sz += 4
+ elif f == "Q":
+ sz += 8
+ elif f == "":
+ pass
+ else:
+ raise TypeError, "Invalid format char '%s'." % f
+ return sz
+
+
+#
+# Translation helper functions.
+#
+
+def do_string(d, n):
+ """Convert a YAML value to a Python string."""
+
+ v = get(d, n, defaults[n])
+ if v:
+ return str(v)
+ return v
+
+def do_long(d, n):
+ """Convert a YAML value to a Python 'long'."""
+
+ v = get(d, n, defaults[n])
+ if v:
+ return long(v)
+ return v
+
+def do_copy(d, n):
+ """Copy a YAML value without conversion."""
+
+ v = get(d, n, defaults[n])
+ return v
+
+def do_encode(xlate):
+ """Translate a YAML value according to mapping 'xlate'."""
+
+ return lambda d, n, xl=xlate: encode(d, n, defaults[n], xl)
+
+def do_flags(xlate):
+ """Translate a list of flags according to mapping 'xlate'."""
+
+ return lambda d, n, xl=xlate: encode_flags(get(d, n, defaults[n]), xl)
+
+#
+# Definitions of ELF types.
+#
+
+class ElfCap(ElfType):
+ """A representation of an ELF Cap structure.
+
+ YAML tag: !Cap
+ """
+
+ fields = [
+ ('c_tag', do_encode(elf_cap_tag), "I", "Q"),
+ ('c_un', do_long, "I", "Q")
+ ]
+ def __init__(self, cap, node):
+ ElfType.__init__(self, cap, node)
+
+
+class ElfDyn(ElfType):
+ """A representation of an ELF Dyn structure.
+
+ YAML tag: !Dyn
+ """
+
+ fields = [
+ ('d_tag', do_encode(elf_d_tag), "I", "Q"),
+ ('d_un', do_long, "I", "Q")
+ ]
+
+ def __init__(self, d, node):
+ ElfType.__init__(self, d, node)
+
+
+class ElfEhdrIdent(ElfType):
+ """A representation for the 'ident' field of an ELF Ehdr.
+
+ YAML tag: !Ident
+ """
+
+ fields = [
+ ('ei_class', do_encode(elf_ei_class), "B", "B"),
+ ('ei_data', do_encode(elf_ei_data), "B", "B"),
+ ('ei_version', do_encode(elf_ei_version), "B", "B"),
+ ('ei_osabi', do_encode(elf_ei_osabi), "B", "B"),
+ ('ei_abiversion', do_long, "B", "B")
+ ]
+
+ def __init__(self, ei, node):
+ ElfType.__init__(self, ei, node)
+
+ def bits(self, format, elfclass):
+ f, args = self.getfields(elfclass)
+ s = "\x7FELF"
+ s += struct.pack(f + 'xxxxxxx', *args)
+ return s
+
+
+class ElfEhdr(ElfType):
+ """A representation of an ELF Executable Header.
+
+ YAML tag: !Ehdr
+ """
+
+ fields = [
+ ('e_ident', do_copy, "", ""),
+ ('e_type', do_encode(elf_ehdr_type), "H", "H"),
+ ('e_machine', do_encode(elf_ehdr_machine), "H", "H"),
+ ('e_version', do_encode(elf_ei_version), "I", "I"),
+ ('e_entry', do_long, "I", "Q"),
+ ('e_phoff', do_long, "I", "Q"),
+ ('e_shoff', do_long, "I", "Q"),
+ ('e_flags', do_flags(elf_ehdr_flags), "I", "I"),
+ ('e_ehsize', do_long, "H", "H"),
+ ('e_phentsize', do_long, "H", "H"),
+ ('e_phnum', do_long, "H", "H"),
+ ('e_shentsize', do_long, "H", "H"),
+ ('e_shnum', do_long, "H", "H"),
+ ('e_shstrndx', do_copy, "H", "H")
+ ]
+
+ def __init__(self, eh, node):
+ """Initialize an Ehdr structure.
+
+ If an 'ident' structure was not specified as part of
+ the YAML description, initialize it explicitly.
+ """
+
+ ElfType.__init__(self, eh, node)
+ if self.e_ident is None:
+ self.e_ident = ElfEhdrIdent({}, node)
+
+ def layout(self, offset, elf):
+ """Layout an ELF Ehdr.
+
+ This method will fill in defaults and/or compute
+ values for fields that were not specified in the YAML
+ description.
+ """
+
+ elfclass = elf.elfclass()
+ if elfclass == ELFCLASS32:
+ e_ehsize = 52
+ e_phentsize = 32
+ e_shentsize = 40
+ alignment = 4
+ else: # 64 bit sizes
+ e_ehsize = 64
+ e_phentsize = 56
+ e_shentsize = 64
+ alignment = 8
+
+ if self.e_ehsize is None:
+ self.e_ehsize = e_ehsize
+
+ # Compute e_phnum if needed.
+ if self.e_phnum is None:
+ self.e_phnum = len(elf.elf_phdrtab)
+
+ # Compute a value for the e_phentsize field.
+ if self.e_phentsize is None:
+ if self.e_phnum:
+ self.e_phentsize = e_phentsize
+ else:
+ self.e_phentsize = 0
+
+ # Set the e_shentsize field.
+ if self.e_shentsize is None:
+ self.e_shentsize = e_shentsize
+
+ # The program header defaults to just after the ELF header.
+ if self.e_phoff is None:
+ if self.e_phnum > 0:
+ self.e_phoff = \
+ (self.e_ehsize + (alignment - 1)) & \
+ ~(alignment - 1)
+ else:
+ self.e_phoff = 0
+
+ # compute e_shnum
+ self.nsections = elf.elf_sections.get_shnum()
+ if self.nsections > 0:
+ if self.e_shstrndx is None:
+ self.e_shstrndx = '.shstrtab'
+ if type(self.e_shstrndx) == types.StringType:
+ self.e_shstrndx = \
+ elf.elf_sections.get_index(self.e_shstrndx)
+ elif type(self.e_shstrndx) == types.IntType or \
+ type(self.e_shstrndx) == types.LongType:
+ pass
+ else:
+ raise ElfError(self._n, "Unparseable e_shstrndx field.")
+ if self.e_shstrndx is None:
+ raise ElfError(self._n,
+ 'Cannot determine section ' + \
+ 'name string table index.')
+ else:
+ if self.e_shstrndx is None:
+ self.e_shstrndx = 0
+
+ if self.e_shnum is None:
+ self.e_shnum = self.nsections
+
+ # section data comes after the program header by default. The
+ # section header table is placed after all section data.
+
+ if self.e_phnum > 0:
+ offset = self.e_phoff + self.e_phnum * self.e_phentsize
+ else:
+ offset = self.e_ehsize
+ offset = elf.elf_sections.layout(offset, elf)
+ if self.e_shoff is None:
+ if self.nsections > 0:
+ self.e_shoff = (offset + (alignment-1)) & \
+ ~(alignment-1)
+ else:
+ self.e_shoff = 0
+
+ if self.nsections >= SHN_LORESERVE:
+ elf.elf_sections.set_extended_shnum(self.nsections)
+ self.e_shnum = 0
+ if self.e_shstrndx >= SHN_XINDEX:
+ elf.elf_sections.set_extended_shstrndx(self.e_shstrndx)
+ self.e_shstrndx = SHN_XINDEX
+
+ def bits(self, formatchar, elfclass):
+ """Return the file representation of an Elf Ehdr."""
+
+ s = self.e_ident.bits(formatchar, elfclass)
+ s += ElfType.bits(self, formatchar, elfclass)
+
+ return s
+
+
+class ElfLong:
+ """Wrapper around a python Int/Long."""
+
+ def __init__(self, v):
+ self._v = long(v)
+
+ def bits(self, formatchar, elfclass):
+ """Return the file representation for this object.
+
+ Depending on the number of bits needed to represent
+ the number, the returned bits would be either 4 or
+ 8 bytes wide.
+ """
+
+ if self._v > 0xFFFFFFFFL:
+ f = formatchar + "Q"
+ else:
+ f = formatchar + "I"
+ return struct.pack(f, self._v)
+
+
+class ElfMove(ElfType):
+ """A representation of an Elf Move type.
+
+ YAML tag: !Move
+ """
+
+ fields = [
+ ('m_value', do_long, "I", "I"),
+ ('m_info', do_long, "I", "Q"),
+ ('m_poffset', do_long, "I", "Q"),
+ ('m_repeat', do_long, "H", "H"),
+ ('m_stride', do_long, "H", "H")
+ ]
+
+ def __init__(self, move, node):
+ ElfType.__init__(self, move, node)
+
+
+class ElfNote(ElfType):
+ """A representation of an Elf Note type.
+
+ YAML tag: !Note
+
+ The data in the note is held in YAML node named 'n_data' which is
+ a pair of strings, one for the note's name field and one for the
+ description.
+
+ If the fields 'n_namesz' and 'n_descz' aren't specified, they
+ are computed from the contents of 'n_data'.
+ """
+
+ fields = [
+ ('n_namesz', do_long, "I", "I"),
+ ('n_descsz', do_long, "I", "I"),
+ ('n_type', do_long, "I", "I"),
+ ('n_data', do_copy, "", "")
+ ]
+
+ def __init__(self, note, node):
+ ElfType.__init__(self, note, node)
+ self._note = note
+
+ def layout(self, offset, elfclass):
+ if len(self.n_data) != 2:
+ raise ElfError(node, "Note data not a pair of strings.")
+
+ for nd in self.n_data:
+ if isinstance(nd, ElfType):
+ nd.layout(offset, elfclass)
+
+ if self.n_namesz is None:
+ self.n_namesz = len(self.n_data[0])
+ if self.n_descsz is None:
+ self.n_descsz = len(self.n_data[1])
+
+ def bits(self, format, elfclass):
+ b = ElfType.bits(self, format, elfclass)
+ nbits = str(self.n_data[0])
+ dbits = str(self.n_data[1])
+ return b + nbits + dbits
+
+
+class ElfPhdr(ElfType):
+ """A representation of an ELF Program Header Table entry.
+
+ YAML tag: !Phdr
+ """
+
+ fields = [ # NOTE: class-dependent field ordering
+ ('p_align', do_long),
+ ('p_filesz', do_long),
+ ('p_flags' , do_flags(elf_ph_flags), ),
+ ('p_memsz' , do_long),
+ ('p_offset', do_long),
+ ('p_paddr' , do_long),
+ ('p_type' , do_encode(elf_ph_type)),
+ ('p_vaddr' , do_long)
+ ]
+
+ def __init__(self, ph, node):
+ ElfType.__init__(self, ph, node)
+
+ def to_string(self):
+ """Helper during debugging."""
+
+ s = "Phdr(type:%(p_type)d,flags:%(p_flags)d," \
+ "offset:%(p_offset)ld,vaddr:%(p_vaddr)ld," \
+ "paddr:%(p_paddr)ld,filesz:%(p_filesz)ld," \
+ "memsz:%(p_memsz)ld)" % self
+ return s
+
+ def bits(self, formatchar, elfclass):
+ """Return the file representation of a Phdr."""
+
+ f = formatchar
+ # Phdr structures are laid out in a class-dependent way
+ if elfclass == ELFCLASS32:
+ f += "IIIIIIII"
+ s = struct.pack(f,
+ self.p_type,
+ self.p_offset,
+ self.p_vaddr,
+ self.p_paddr,
+ self.p_filesz,
+ self.p_memsz,
+ self.p_flags,
+ self.p_align)
+ else:
+ f += "IIQQQQQQ"
+ s = struct.pack(f,
+ self.p_type,
+ self.p_flags,
+ self.p_offset,
+ self.p_vaddr,
+ self.p_paddr,
+ self.p_filesz,
+ self.p_memsz,
+ self.p_align)
+ return s
+
+class ElfRel(ElfType):
+ """A representation of an ELF Rel type.
+
+ YAML tag: !Rel
+ """
+
+ fields = [
+ ('r_offset', do_long, "I", "Q"),
+ ('r_info', do_long, "I", "Q")
+ ]
+
+ def __init__(self, rel, node):
+ ElfType.__init__(self, rel, node)
+
+
+class ElfRela(ElfType):
+ """A representation of an ELF Rela type.
+
+ YAML tag: !Rela
+ """
+
+ fields = [
+ ('r_offset', do_long, "I", "Q"),
+ ('r_info', do_long, "I", "Q"),
+ ('r_addend', do_long, "I", "Q")
+ ]
+
+ def __init__(self, rela, node):
+ ElfType.__init__(self, rela, node)
+
+
+class ElfSection(ElfType):
+ """A representation of an ELF Section.
+
+ YAML tag: !Section
+
+ A section description consists of the fields that make up an ELF
+ section header entry and an additional field 'sh_data' that
+ contains the data associated with this section.
+
+ 'sh_data' may be a YAML string, or a YAML list of items that
+ comprise the content of the section.
+ """
+
+ fields = [
+ ('sh_name', do_string, "I", "I"),
+ ('sh_type', do_encode(elf_sh_type), "I", "I"),
+ ('sh_flags', do_flags(elf_sh_flags), "I", "Q"),
+ ('sh_addr', do_long, "I", "Q"),
+ ('sh_offset', do_long, "I", "Q"),
+ ('sh_size', do_long, "I", "Q"),
+ ('sh_link', do_long, "I", "I"),
+ ('sh_info', do_long, "I", "I"),
+ ('sh_addralign', do_copy, "I", "Q"),
+ ('sh_entsize', do_long, "I", "Q"),
+ ('sh_data', do_copy, "", ""),
+ ('sh_index', do_long, "", "")
+ ]
+
+ def __init__(self, shdr, node):
+ """Initialize a section descriptor."""
+
+ ElfType.__init__(self, shdr, node)
+ if type(self.sh_data) != types.ListType:
+ self.sh_data = list(self.sh_data)
+ if self.sh_addralign is None:
+ if self.sh_type == SHT_NULL or self.sh_type == SHT_NOBITS:
+ self.sh_addralign = 0
+ else:
+ self.sh_addralign = 1
+ else:
+ if (self.sh_addralign == 0 or \
+ (self.sh_addralign & (self.sh_addralign - 1)) != 0):
+ raise ElfError(node,
+ "'sh_addralign' not a power of two.")
+ self._data = None # 'cache' of translated data
+ self._strtab = None
+
+ def to_string(self):
+ """Helper function during debugging."""
+
+ return "Section(name:%(sh_name)s,type:%(sh_type)d," \
+ "flags:%(sh_flags)x,addr:%(sh_addr)d,"\
+ "offset:%(sh_offset)d,size:%(sh_size)d," \
+ "link:%(sh_link)d,info:%(sh_info)d," \
+ "addralign:%(sh_addralign)d,entsize:%(sh_entsize)d)" % \
+ self
+
+ def make_strtab(self):
+ """Create a string table from section contents."""
+
+ self._strtab = ElfStrTab(self.sh_data)
+
+ def string_to_index(self, name):
+ """Convert 'name' to an offset inside a string table.
+
+ Only valid for sections of type SHT_STRTAB."""
+
+ if self._strtab:
+ return self._strtab.lookup(name)
+ raise ElfError(None, 'Cannot translate "%s" to an index.' % name)
+
+ def bits(self, formatchar, elfclass):
+ raise AssertionError, "Section objects should use " \
+ "databits() or headerbits()"
+
+ def layout(self, offset, elf):
+ """Prepare an ELF section for output."""
+
+ if type(self.sh_name) == types.StringType:
+ # first try convert it to a long
+ try:
+ self.sh_name = long(self.sh_name)
+ except ValueError: # lookup in string table
+ try:
+ self.sh_name = \
+ elf.section_name_index(self.sh_name)
+ except KeyError:
+ raise ElfError(self._n,
+ "Section name '%s' not in string table." % \
+ self.sh_name)
+ # give a chance for the contents of a section to xlate strings
+ for d in self.sh_data:
+ if isinstance(d, ElfType):
+ d.layout(offset, elf)
+ # compute the space used by the section data
+ self._data = self.databits(elf.formatchar(), elf.elfclass())
+
+ align = self.sh_addralign
+ if align == 0:
+ align = 1
+ if self.sh_type == SHT_NULL or self.sh_type == SHT_NOBITS:
+ isnulltype = 1
+ else:
+ isnulltype = 0
+
+ offset = (offset + (align - 1)) & ~(align - 1)
+ if self.sh_size is None:
+ if isnulltype:
+ self.sh_size = 0
+ else:
+ self.sh_size = len(self._data)
+ if self.sh_offset is None:
+ if isnulltype:
+ self.sh_offset = 0
+ else:
+ self.sh_offset = offset
+ if isnulltype: # ignore bits for null types
+ return offset
+ return offset + len(self._data)
+
+ def databits(self, formatchar, elfclass):
+ """Return the contents of a section."""
+
+ if self._data:
+ return self._data
+ # special-case string table handling
+ if self.sh_type == SHT_STRTAB:
+ return self._strtab.bits()
+ # 'normal' section
+ s = ""
+ for d in self.sh_data:
+ if isinstance(d, ElfType):
+ s += d.bits(formatchar, elfclass)
+ elif isinstance(d, types.LongType):
+ s += struct.pack(formatchar + "Q", d)
+ elif isinstance(d, types.IntType):
+ s += struct.pack(formatchar + "I", d)
+ else:
+ s += str(d)
+ return s
+
+ def headerbits(self, formatchar, elfclass):
+ """Return the file representation of the section header."""
+
+ return ElfType.bits(self, formatchar, elfclass)
+
+
+class ElfSym(ElfType):
+ """A representation for an ELF Symbol type.
+
+ YAML tag: !Sym
+ """
+
+ fields = [ # NOTE: class-dependent layout.
+ ('st_info', do_long, "B", "B"),
+ ('st_name', do_string, "I", "I"),
+ ('st_other', do_long, "B", "B"),
+ ('st_shndx', do_string, "H", "H"),
+ ('st_size', do_long, "I", "Q"),
+ ('st_value', do_long, "I", "Q")
+ ]
+
+ def __init__(self, sym, node):
+ ElfType.__init__(self, sym, node)
+
+ def bits(self, format, elfclass):
+ """Return the file representation for an ELF Sym."""
+
+ if elfclass == ELFCLASS32:
+ s = struct.pack(format + "IIIBBH",
+ self.st_name,
+ self.st_value,
+ self.st_size,
+ self.st_info,
+ self.st_other,
+ self.st_shndx)
+ else:
+ s = struct.pack(format + "IBBHQQ",
+ self.st_name,
+ self.st_info,
+ self.st_other,
+ self.st_shndx,
+ self.st_value,
+ self.st_size)
+ return s
+
+ def layout(self, offset, elf):
+ """Perform layout-time conversions for an ELF Sym.
+
+ String valued fields are converted to offsets into
+ string tables.
+ """
+
+ if type(self.st_shndx) == types.StringType:
+ self.st_shndx = \
+ elf.elf_sections.get_index(self.st_shndx)
+ if self.st_shndx is None:
+ raise ElfError(self._n, "Untranslateable 'st_shndx' " + \
+ "value \"%s\"." % self.st_shndx)
+
+ if type(self.st_name) == types.StringType:
+ try:
+ strtab = \
+ elf.elf_sections[self.st_shndx]._strtab
+ except IndexError:
+ raise ElfError(self._n, "'st_shndx' out of range")
+ if strtab is None:
+ raise ElfError(self._n, "'st_shndx' not of type STRTAB.")
+
+ try:
+ self.st_name = strtab.lookup(self.st_name)
+ except KeyError:
+ raise ElfError(self._n,
+ 'unknown string "%s"' % self.st_name)
+ return offset
+
+
+class ElfSyminfo(ElfType):
+ """A representation of an ELF Syminfo type.
+
+ YAML tag: !Syminfo
+ """
+
+ fields = [
+ ('si_boundto', do_encode(elf_syminfo_boundto_types), "H", "H"),
+ ('si_flags', do_flags(elf_syminfo_flags), "H", "H")
+ ]
+
+ def __init__(self, syminfo, node):
+ ElfType.__init__(self, syminfo, node)
+
+
+class ElfVerdaux(ElfType):
+ """A representation of an ELF Verdaux type."""
+
+ fields = [
+ ('vda_name', do_long, "I", "I"),
+ ('vda_next', do_long, "I", "I")
+ ]
+
+ def __init__(self, verdaux, node):
+ ElfType.__init__(self, verdaux, node)
+
+
+class ElfVerdef(ElfType):
+ """A representation of an ELF Verdef type."""
+
+ fields = [
+ ('vd_version', do_long, "H", "H"),
+ ('vd_flags', do_long, "H", "H"),
+ ('vd_ndx', do_long, "H", "H"),
+ ('vd_cnt', do_long, "H", "H"),
+ ('vd_hash', do_long, "I", "I"),
+ ('vd_aux', do_long, "I", "I"),
+ ('vd_next', do_long, "I", "I")
+ ]
+
+ def __init__(self, verdef, node):
+ ElfType.__init__(self, verdef, node)
+
+
+class ElfVernaux(ElfType):
+ """A representation of an ELF Vernaux type."""
+
+ fields = [
+ ('vna_hash', do_long, "I", "I"),
+ ('vna_flags', do_long, "H", "H"),
+ ('vna_other', do_long, "H", "H"),
+ ('vna_name', do_long, "I", "I"),
+ ('vna_next', do_long, "I", "I")
+ ]
+
+ def __init__(self, vernaux, node):
+ ElfType.__init__(self, vernaux, node)
+
+class ElfVerneed(ElfType):
+ """A representation of an ELF Verneed type."""
+
+ fields = [
+ ('vn_version', do_long, "H", "H"),
+ ('vn_cnt', do_long, "H", "H"),
+ ('vn_file', do_long, "I", "I"),
+ ('vn_aux', do_long, "I", "I"),
+ ('vn_next', do_long, "I", "I")
+ ]
+
+ def __init__(self, verneed, node):
+ ElfType.__init__(self, verneed, node)
+
+
+#
+# Aggregates
+#
+
+class ElfPhdrTable:
+ """A representation of an ELF Program Header Table.
+
+ A program header table is a list of program header entry sections.
+ """
+
+ def __init__(self, phdr):
+ """Initialize a program header table object.
+
+ Argument 'phdr' is a list of parsed ElfPhdr objects.
+ """
+
+ self.pht_data = []
+ for ph in phdr:
+ if type(ph) == types.DictType:
+ ph = ElfPhdr(ph)
+ elif not isinstance(ph, ElfPhdr):
+ raise ElfError(ph.node,
+ "Program Header Table "
+ "contains non header data.")
+ self.pht_data.append(ph)
+
+ def bits(self, formatchar, elfclass):
+ """Return the file representation of the Phdr table."""
+
+ s = ""
+ for d in self.pht_data:
+ s += d.bits(formatchar, elfclass)
+ return s
+
+ def __len__(self):
+ """Return the number of program header table entries."""
+
+ return len(self.pht_data)
+
+ def __iter__(self):
+ """Return an iterator for traversing Phdr entries."""
+
+ return self.pht_data.__iter__()
+
+
+class ElfSectionList:
+ """A list of ELF sections."""
+
+ def __init__(self, shlist):
+ """Initialize an ELF section list.
+
+ Argument 'shlist' is a list of parser ElfSection
+ objects.
+ """
+
+ self.shl_sections = shlist
+ self.shl_sectionnames = []
+ self.shl_nentries = len(shlist)
+
+ for sh in shlist:
+ if not isinstance(sh, ElfSection):
+ raise ElfError(None,
+ """Section 'sections' contains
+ unrecognized data.""")
+ if sh.sh_index is not None:
+ if self.shl_nentries <= sh.sh_index:
+ self.shl_nentries = sh.sh_index + 1
+ self.shl_sectionnames.append((sh.sh_name, sh.sh_index))
+ if sh.sh_type == SHT_STRTAB: # a string table
+ sh.make_strtab()
+
+ def __len__(self):
+ """Return the number of ELF sections."""
+
+ return len(self.shl_sections)
+
+ def __iter__(self):
+ """Iterate through ELF sections."""
+
+ return self.shl_sections.__iter__()
+
+ def __getitem__(self, ind):
+ """Retrieve the ELF section at index 'ind'."""
+
+ try:
+ return self.shl_sections[ind]
+ except IndexError:
+ for sh in self.shl_sections:
+ if sh.sh_index == ind:
+ return sh
+ raise IndexError, "no section at index %d" % ind
+
+ def layout(self, offset, elf):
+ """Compute the layout for section."""
+
+ if len(self.shl_sections) == 0:
+ return 0
+ for sh in self.shl_sections: # layout sections
+ offset = sh.layout(offset, elf)
+ return offset
+
+ def get_index(self, name):
+ """Return the section index for section 'name', or 'None'."""
+
+ c = 0
+ for (n,i) in self.shl_sectionnames:
+ if n == name:
+ if i is None:
+ return c
+ else:
+ return i
+ c += 1
+ return None
+
+ def get_shnum(self):
+ """Retrieve the number of sections in this container."""
+
+ return self.shl_nentries
+
+ def set_extended_shnum(self, shnum):
+ """Set the extended section number."""
+
+ sh = self.shl_sections[0]
+ sh.sh_size = shnum
+
+ def set_extended_shstrndx(self, strndx):
+ """Set the extended string table index."""
+
+ sh = self.shl_sections[0]
+ sh.sh_link = strndx
+
+class Elf:
+ """A representation of an ELF object."""
+
+ def __init__(self, yamldict, ehdr, phdrtab, sections):
+ self._d = yamldict
+ self._n = None
+ self.elf_ehdr = ehdr
+ self.elf_phdrtab = phdrtab
+ self.elf_sections = sections
+ self.elf_fillchar = long(get(yamldict, 'elf_fillchar',
+ defaults['elf_fillchar']))
+ def byteorder(self):
+ """Return the byteorder for this ELF object."""
+ return self.elf_ehdr.e_ident.ei_data
+
+ def elfclass(self):
+ """Return the ELF class for this ELF object."""
+ return self.elf_ehdr.e_ident.ei_class
+
+ def formatchar(self):
+ """Return the format character corresponding to the ELF
+ byteorder."""
+
+ if self.byteorder() == ELFCLASS32:
+ return "<"
+ else:
+ return ">"
+
+ def layout(self):
+ """Compute a file layout for this ELF object and update
+ internal data structures."""
+
+ self.elf_ehdr.layout(0, self)
+
+
+ def section_name_index(self, name):
+ """Compute index of section 'name' in the section name string table."""
+
+ strndx = self.elf_ehdr.e_shstrndx
+ if strndx is None:
+ return None
+ return self.elf_sections[strndx].string_to_index(name)
+
+ def write(self, fn):
+ """Write out the file representation of an ELF object.
+
+ Argument 'fn' denotes the destination."""
+
+ of = file(fn, 'w')
+
+ formatchar = self.formatchar()
+ elfclass = self.elfclass()
+
+ # Write out the header
+ of.write(self.elf_ehdr.bits(formatchar, elfclass))
+
+ # Write out the program header table if present
+ if self.elf_phdrtab:
+ self.reposition(of, self.elf_ehdr.e_phoff)
+ for ph in self.elf_phdrtab:
+ of.write(ph.bits(formatchar, elfclass))
+ # Write out the sections
+ if self.elf_sections:
+ # First the contents of the sections
+ for sh in self.elf_sections:
+ if sh.sh_type == SHT_NULL or sh.sh_type == SHT_NOBITS:
+ continue
+ self.reposition(of, sh.sh_offset)
+ of.write(sh.databits(formatchar, elfclass))
+ # Then the header table
+ self.reposition(of, self.elf_ehdr.e_shoff)
+ for sh in self.elf_sections:
+ if sh.sh_index:
+ new_offset = sh.sh_index * self.elf_ehdr.e_shentsize + \
+ self.elf_ehdr.e_shoff
+ self.reposition(of, new_offset)
+ of.write(sh.headerbits(formatchar, elfclass))
+ of.close()
+
+ def reposition(self, f, offset):
+ """Reposition file `f' to offset `offset', filling gaps with
+ the configured fill character as needed."""
+
+ pos = f.tell()
+ if offset == pos:
+ return
+ if offset < pos or (offset > pos and self.elf_fillchar == 0):
+ f.seek(offset, 0)
+ return
+ s = ("%c" % self.elf_fillchar) * (offset - pos)
+ f.write(s)
+
+
+#
+# YAML Parser configuration and helpers.
+#
+
+yaml_tags = [
+ (u'!Cap', ElfCap),
+ (u'!Dyn', ElfDyn),
+ (u'!Ehdr', ElfEhdr),
+ (u'!Ident', ElfEhdrIdent),
+ (u'!Move', ElfMove),
+ (u'!Note', ElfNote),
+ (u'!Phdr', ElfPhdr),
+ (u'!Rel', ElfRel),
+ (u'!Rela', ElfRela),
+ (u'!Section', ElfSection),
+ (u'!Sym', ElfSym),
+ (u'!Syminfo', ElfSyminfo),
+ (u'!Verdaux', ElfVerdaux),
+ (u'!Verdef', ElfVerdef),
+ (u'!Vernaux', ElfVernaux),
+ (u'!Verneed', ElfVerneed) ]
+
+def init_parser():
+ for t in yaml_tags:
+ yaml.add_constructor(t[0], # lamdba: loader, node, class
+ lambda l, n, c=t[1]: \
+ c(l.construct_mapping(n, deep=True), n))
+
+def make_elf(yd):
+ """Convert a YAML description `yd' of an ELF file into an
+ ELF object."""
+
+ try:
+ eh = yd['ehdr']
+ except KeyError:
+ eh = ElfEhdr({}, None)
+
+ phdrtab = ElfPhdrTable(get(yd, 'phdrtab', {}))
+ sectionlist = ElfSectionList(get(yd, 'sections', {}))
+
+ return Elf(yd, eh, phdrtab, sectionlist)
+
+
+#
+# MAIN
+#
+
+if __name__ == '__main__':
+ parser = optparse.OptionParser(usage=usage, version=version,
+ description=description)
+ parser.add_option("-o", "--output", dest="output",
+ help="write output to FILE [default: %default]",
+ metavar="FILE", default="a.out")
+ parser.add_option("-N", "--no-shstrtab", dest="do_shstrtab",
+ help="do not create a string table section for "
+ "section names if missing", action="store_false",
+ metavar="BOOLEAN", default=True)
+ parser.add_option("-U", "--no-shnundef", dest="do_shnundef",
+ help="do not create a section header for index "
+ "SHN_UNDEF if missing", action="store_false",
+ metavar="BOOLEAN", default=True)
+
+ (options, args) = parser.parse_args()
+
+ if len(args) > 1:
+ parser.error("only one input-file must be specified")
+
+ try:
+ if args:
+ stream = file(args[0], 'r')
+ else:
+ stream = sys.stdin
+ except IOError, x:
+ parser.error("cannot open stream: %s" % x)
+
+ init_parser()
+
+ try:
+ elf = make_elf(yaml.load(stream))
+ elf.layout()
+ elf.write(options.output)
+ except yaml.YAMLError, x:
+ parser.error("cannot parse stream: %s" % x)
+ except ElfError, msg:
+ print msg
+ sys.exit(1)
+
+
+
+# Local Variables:
+# mode: python
+# tab-width: 4
+# py-indent-offset: 4
+# End:
diff --git a/test/libelf/tset/common/Makefile b/test/libelf/tset/common/Makefile
new file mode 100644
index 0000000000000..5dd5bf9c1a5b3
--- /dev/null
+++ b/test/libelf/tset/common/Makefile
@@ -0,0 +1,36 @@
+# $Id: Makefile 1719 2011-08-12 08:24:14Z jkoshy $
+
+TOP= ../../../..
+
+YAML_FILES= check_elf \
+ getclass \
+ ehdr \
+ fsize \
+ newehdr newscn newscn2 \
+ phdr \
+ rdwr rdwr1 rdwr2 \
+ shdr \
+ u1 \
+ versioning \
+ xlate xscn-1 xscn-2 xscn-3 \
+ zerosection
+
+# Generate ELF binary files from their YAML desciptions.
+.for f in ${YAML_FILES}
+. for e in msb lsb
+. for c in 32 64
+_YAML_ELF+= ${f}.${e}${c}
+${f}.${e}${c}: ${f}.yaml
+ _E=`echo ${e} | tr '[a-z]' '[A-Z]'`; _C=`echo ${c} | tr '[a-z]' '[A-Z]'`; \
+ cat ${.CURDIR}/${f}.yaml | sed -e "s/ELFDATANONE/ELFDATA2$${_E}/g" \
+ -e "s/ELFCLASSNONE/ELFCLASS$${_C}/g" | \
+ ${TS_ROOT}/bin/elfc -o ${.TARGET}
+. endfor
+. endfor
+.endfor
+
+CLEANFILES+= ${_YAML_ELF}
+
+all: ${_YAML_ELF}
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/common/check_elf.yaml b/test/libelf/tset/common/check_elf.yaml
new file mode 100644
index 0000000000000..6c9bc06cd00e0
--- /dev/null
+++ b/test/libelf/tset/common/check_elf.yaml
@@ -0,0 +1,16 @@
+%YAML 1.1
+# $Id: check_elf.yaml 2053 2011-10-26 11:50:18Z jkoshy $
+---
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_data: ELFDATANONE
+ ei_osabi: ELFOSABI_FREEBSD
+ ei_abiversion: 1
+ ei_class: ELFCLASSNONE
+ e_type: ET_REL
+ e_machine: EM_NONE
+ e_version: EV_CURRENT
+ e_flags: [2, 1]
+ e_entry: 0xdeadbeef
+ e_phoff: 0
+ e_shoff: 0
diff --git a/test/libelf/tset/common/ehdr.yaml b/test/libelf/tset/common/ehdr.yaml
new file mode 100644
index 0000000000000..cf4edf9da6153
--- /dev/null
+++ b/test/libelf/tset/common/ehdr.yaml
@@ -0,0 +1,23 @@
+%YAML 1.1
+# $Id: ehdr.yaml 2053 2011-10-26 11:50:18Z jkoshy $
+---
+ehdr: !Ehdr
+ e_ident: !Ident # e_ident[] members
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
+ ei_osabi: ELFOSABI_FREEBSD
+ ei_abiversion: 1
+ # other members
+ e_type: ET_REL
+ e_machine: 0x42
+ e_version: EV_CURRENT
+ e_entry: 0xF0F0F0F0
+ e_phoff: 0x0E0E0E0E
+ e_shoff: 0xD0D0D0D0
+ e_flags: [ 64, 8, 2, 1]
+ e_ehsize: 0x0A0A
+ e_phentsize: 0xB0B0
+ e_phnum: 0x0C0C
+ e_shentsize: 0xD0D0
+ e_shnum: 0x0E0E
+ e_shstrndx: 0xF0F0
diff --git a/test/libelf/tset/common/ehdr_template.m4 b/test/libelf/tset/common/ehdr_template.m4
new file mode 100644
index 0000000000000..4f60fffa1a3ea
--- /dev/null
+++ b/test/libelf/tset/common/ehdr_template.m4
@@ -0,0 +1,371 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: ehdr_template.m4 2077 2011-10-27 03:59:40Z jkoshy $
+ */
+
+include(`elfts.m4')
+
+/*
+ * Boilerplate for testing the *_getehdr and *_newehdr APIs.
+ *
+ * This template is to be used as follows:
+ *
+ * `define(`TS_EHDRFUNC',`_getehdr')' (or `_newehdr')
+ * `define(`TS_EHDRSZ',`32')' (or `64')
+ * `include(`ehdr_template.m4')'
+ */
+
+ifdef(`TS_EHDRFUNC',`',`errprint(`TS_EHDRFUNC was not defined')m4exit(1)')
+ifdef(`TS_EHDRSZ',`',`errprint(`TS_EHDRSZ was not defined')m4exit(1)')
+define(`TS_OTHERSIZE',`ifelse(TS_EHDRSZ,32,64,32)')
+
+#include <sys/cdefs.h>
+
+define(`TS_ICFUNC',`elf'TS_EHDRSZ`'TS_EHDRFUNC)
+define(`TS_EHDR',`Elf'TS_EHDRSZ`_Ehdr')
+define(`TS_ICNAME',TS_ICFUNC)
+define(`TS_ELFCLASS',`ELFCLASS'TS_EHDRSZ)
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * Checks for the contents of an Ehdr structure. The values here must
+ * match that in the "ehdr.yaml" file in the test case directory.
+ */
+
+#define CHECK_SIGFIELD(E,I,V) do { \
+ if ((E)->e_ident[EI_##I] != (V)) \
+ TP_FAIL(#I " value 0x%x != " \
+ "expected 0x%x.", (E)->e_ident[EI_##I], \
+ (V)); \
+ } while (0)
+
+#define CHECK_SIG(E,ED,EC,EV,EABI,EABIVER) do { \
+ if ((E)->e_ident[EI_MAG0] != ELFMAG0 || \
+ (E)->e_ident[EI_MAG1] != ELFMAG1 || \
+ (E)->e_ident[EI_MAG2] != ELFMAG2 || \
+ (E)->e_ident[EI_MAG3] != ELFMAG3) \
+ TP_FAIL("incorrect ELF signature " \
+ "(%x %x %x %x).", (E)->e_ident[EI_MAG0], \
+ (E)->e_ident[EI_MAG1], (E)->e_ident[EI_MAG2],\
+ (E)->e_ident[EI_MAG3]); \
+ CHECK_SIGFIELD(E,CLASS, EC); \
+ CHECK_SIGFIELD(E,DATA, ED); \
+ CHECK_SIGFIELD(E,VERSION, EV); \
+ CHECK_SIGFIELD(E,OSABI, EABI); \
+ CHECK_SIGFIELD(E,ABIVERSION, EABIVER); \
+ } while (0)
+
+
+#define CHECK_FIELD(E,FIELD,VALUE) do { \
+ if ((E)->e_##FIELD != (VALUE)) \
+ TP_FAIL("field \"%s\" actual 0x%jx " \
+ "!= expected 0x%jx.", #FIELD, \
+ (uintmax_t) (E)->e_##FIELD, \
+ (uintmax_t) (VALUE)); \
+ } while (0)
+
+#define CHECK_EHDR(E,ED,EC) do { \
+ CHECK_SIG(E,ED,EC,EV_CURRENT,ELFOSABI_FREEBSD,1); \
+ CHECK_FIELD(E,type, ET_REL); \
+ CHECK_FIELD(E,machine, 0x42); \
+ CHECK_FIELD(E,version, EV_CURRENT); \
+ CHECK_FIELD(E,entry, 0xF0F0F0F0); \
+ CHECK_FIELD(E,phoff, 0x0E0E0E0E); \
+ CHECK_FIELD(E,shoff, 0xD0D0D0D0); \
+ CHECK_FIELD(E,flags, 64+8+2+1); \
+ CHECK_FIELD(E,ehsize, 0x0A0A); \
+ CHECK_FIELD(E,phentsize,0xB0B0); \
+ CHECK_FIELD(E,phnum, 0x0C0C); \
+ CHECK_FIELD(E,shentsize,0xD0D0); \
+ CHECK_FIELD(E,shnum, 0x0E0E); \
+ CHECK_FIELD(E,shstrndx, 0xF0F0); \
+ } while (0)
+
+/*
+ * Check behaviour when passed a NULL argument.
+ */
+
+void
+tcNullArgument(void)
+{
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TS_ICNAME`'(NULL) fails with ELF_E_ARGUMENT.");
+
+ if (TS_ICFUNC`'(NULL) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ tet_result(TET_FAIL);
+ else
+ tet_result(TET_PASS);
+}
+
+/*
+ * Check behaviour when passed a pointer to a non-ELF object.
+ */
+
+static char data[] = "This isn't an ELF file.";
+
+void
+tcNonElfData(void)
+{
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TS_ICNAME`'(non-ELF) fails with ELF_E_ARGUMENT.");
+
+ TS_OPEN_MEMORY(e, data);
+
+ if (TS_ICFUNC`'(e) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ tet_result(TET_FAIL);
+ else
+ tet_result(TET_PASS);
+
+ (void) elf_end(e);
+}
+
+
+/*
+ * Check behaviour when an object with a malformed ELF header.
+ */
+
+static char badelftemplate[EI_NIDENT+1] = {
+ [EI_MAG0] = '\177',
+ [EI_MAG1] = 'E',
+ [EI_MAG2] = 'L',
+ [EI_MAG3] = 'F',
+ [EI_CLASS] = ELFCLASS64,
+ [EI_DATA] = ELFDATA2MSB,
+ [EI_NIDENT] = '@'
+};
+
+/*
+ * Verify that the version number is checked before other kinds
+ * of errors.
+ */
+
+void
+tcBadElfVersion(void)
+{
+ int err, result;
+ Elf *e;
+ TS_EHDR *eh;
+ char badelf[sizeof(badelftemplate)];
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TS_ICNAME`'() with an unsupported version "
+ "fails with ELF_E_VERSION.");
+
+ (void) memcpy(badelf, badelftemplate, sizeof(badelf));
+
+ badelf[EI_VERSION] = EV_NONE;
+ badelf[EI_CLASS] = TS_ELFCLASS;
+
+ TS_OPEN_MEMORY(e, badelf);
+
+ result = TET_PASS;
+
+ if ((eh = TS_ICFUNC`'(e)) != NULL ||
+ (err = elf_errno()) != ELF_E_VERSION)
+ TP_FAIL("error=%d eh=%p.", err, (void *) eh);
+
+ (void) elf_end(e);
+
+ tet_result(result);
+}
+
+void
+tcBadElf(void)
+{
+ int err, result;
+ Elf *e;
+ TS_EHDR *eh;
+ char badelf[sizeof(badelftemplate)];
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TS_ICNAME`'() on a malformed ELF file "
+ "fails with ELF_E_HEADER.");
+
+ (void) memcpy(badelf, badelftemplate, sizeof(badelf));
+ badelf[EI_VERSION] = EV_CURRENT;
+ badelf[EI_CLASS] = TS_ELFCLASS;
+
+ TS_OPEN_MEMORY(e, badelf);
+
+ result = TET_PASS;
+ if ((eh = TS_ICFUNC`'(e)) != NULL ||
+ (err = elf_errno()) != ELF_E_HEADER)
+ TP_FAIL("error=%d eh=%p.", err, (void *) eh);
+
+ (void) elf_end(e);
+
+ tet_result(result);
+}
+
+/*
+ * Verify non-NULL return for a legal ELF object.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcValidElfNonNull$1(void)
+{
+ int fd;
+ Elf *e;
+ TS_EHDR *eh;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TS_ICNAME`'($1) on valid EHDR returns non-NULL.");
+
+ TS_OPEN_FILE(e,"ehdr.TOLOWER($1)`'TS_EHDRSZ",ELF_C_READ,fd);
+
+ if ((eh = TS_ICFUNC`'(e)) == NULL)
+ tet_result(TET_FAIL);
+ else
+ tet_result(TET_PASS);
+
+ (void) elf_end(e);
+ (void) close(fd);
+}')
+
+FN(`LSB')
+FN(`MSB')
+
+/*
+ * Verify accuracy of the return header.
+ */
+
+define(`FN',`
+void
+tcValidElf$1(void)
+{
+ int fd, result;
+ Elf *e;
+ TS_EHDR *eh;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TS_ICNAME`'($1) returns the correct $1 ehdr.");
+
+ TS_OPEN_FILE(e,"ehdr.TOLOWER($1)`'TS_EHDRSZ",ELF_C_READ,fd);
+
+ if ((eh = TS_ICFUNC`'(e)) == NULL) {
+ TP_UNRESOLVED("TS_ICNAME`'() failed.");
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ CHECK_EHDR(eh, ELFDATA2$1, TS_ELFCLASS);
+
+done:
+ (void) elf_end(e);
+ (void) close(fd);
+
+ tet_result(result);
+
+}')
+
+FN(`LSB')
+FN(`MSB')
+
+/*
+ * Verify duplicate handling.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcElfDup$1(void)
+{
+ int fd, result;
+ Elf *e;
+ TS_EHDR *eh1, *eh2;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("Successful calls to TS_ICNAME`'($1) return "
+ "identical pointers.");
+
+ TS_OPEN_FILE(e,"ehdr.TOLOWER($1)`'TS_EHDRSZ",ELF_C_READ,fd);
+
+ if ((eh1 = TS_ICFUNC`'(e)) == NULL ||
+ (eh2 = TS_ICFUNC`'(e)) == NULL) {
+ TP_UNRESOLVED("TS_ICNAME`'() failed.");
+ tet_result(result);
+ return;
+ }
+
+ tet_result(eh1 == eh2 ? TET_PASS : TET_FAIL);
+
+ (void) elf_end(e);
+ (void) close(fd);
+}')
+
+FN(`LSB')
+FN(`MSB')
+
+/*
+ * Verify the error reported for incorrectly sized ELF objects.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcElfWrongSize$1(void)
+{
+ int error, fd, result;
+ Elf *e;
+ char *fn;
+ TS_EHDR *eh;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TS_ICNAME`'($1.TS_OTHERSIZE) fails with ELF_E_CLASS.");
+
+ result = TET_PASS;
+
+ fn = "ehdr.TOLOWER($1)`'TS_OTHERSIZE";
+ TS_OPEN_FILE(e,fn,ELF_C_READ,fd);
+ if ((eh = TS_ICFUNC`'(e)) != NULL ||
+ (error = elf_errno()) != ELF_E_CLASS)
+ TP_FAIL("\"%s\" opened (error %d).", fn, error);
+
+ (void) elf_end(e);
+ (void) close(fd);
+
+ tet_result(result);
+
+}')
+
+FN(`LSB')
+FN(`MSB')
diff --git a/test/libelf/tset/common/elf_flag.m4 b/test/libelf/tset/common/elf_flag.m4
new file mode 100644
index 0000000000000..cc92f3e68c22f
--- /dev/null
+++ b/test/libelf/tset/common/elf_flag.m4
@@ -0,0 +1,184 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: elf_flag.m4 1412 2011-02-05 10:09:22Z jkoshy $
+ */
+
+/*
+ * M4 macros for use with the elf_flag*() APIs.
+ */
+
+divert(-1)
+
+define(`_TP_FLAG_FN',`
+void
+$1(void)
+{
+ int result;
+$2
+$3
+$4
+ tet_result(result);
+}')
+
+define(`TP_FLAG_NULL',`_TP_FLAG_FN(`tcArgsNull',`
+ int error, ret;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("A NULL first parameter returns zero.");',`
+ result = TET_PASS;
+ if ((ret = $1(NULL, ELF_C_SET, ELF_F_DIRTY)) != 0 ||
+ (error = elf_errno()) != ELF_E_NONE)
+ TP_FAIL("ret=%d, error=%d \"%s\".", ret, error,
+ elf_errmsg(error));',`')')
+
+/*
+ * TP_FLAG_ILLEGAL_CMD(FN,ARG)
+ *
+ * Check that illegal `cmd' values are rejected.
+ */
+define(`TP_FLAG_ILLEGAL_CMD',`_TP_FLAG_FN(`tcArgsIllegalCmd',`
+ int error, ret;
+ Elf_Cmd cmd;
+ _TP_DECLARATIONS
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("Illegal CMD values are rejected.");
+
+ _TP_PROLOGUE',`
+ result = TET_PASS;
+ for (cmd = ELF_C_NULL-1; cmd <= ELF_C_NUM; cmd++) {
+ if (cmd == ELF_C_CLR || cmd == ELF_C_SET)
+ continue;
+ if ((ret = $1($2, ELF_C_NUM, ELF_F_DIRTY)) != 0 ||
+ (error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("cmd=%d ret=%d, error=%d \"%s\".", cmd, ret,
+ error, elf_errmsg(error));
+ goto done;
+ }
+ }',`_TP_EPILOGUE')')
+
+/*
+ * TP_FLAG_SET(FN,ARG)
+ *
+ * Check that an ELF_C_SET works.
+ */
+define(`TP_FLAG_SET',`_TP_FLAG_FN(`tcArgsSet',`
+ int error, flag;
+ _TP_DECLARATIONS
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("ELF_C_SET works correctly.");
+
+ _TP_PROLOGUE',`
+ result = TET_PASS;
+
+ if ((flag = $1($2, ELF_C_SET, ELF_F_DIRTY)) != ELF_F_DIRTY) {
+ error = elf_errno();
+ TP_FAIL("flag=0x%x, expected 0x%x, error=%d \"%s\".", flag,
+ ELF_F_DIRTY, error, elf_errmsg(error));
+ goto done;
+ }',`_TP_EPILOGUE')')
+
+/*
+ * TP_FLAG_CLR(FN,ARG)
+ *
+ * Check that an ELF_C_CLR works.
+ */
+define(`TP_FLAG_CLR',`_TP_FLAG_FN(`tcArgsClr',`
+ int error, flag;
+ _TP_DECLARATIONS
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("ELF_C_CLR works correctly.");
+
+ _TP_PROLOGUE',`
+ result = TET_PASS;
+
+ (void) $1($2, ELF_C_SET, ELF_F_DIRTY);
+ if ((flag = $1($2, ELF_C_CLR, ELF_F_DIRTY)) != 0) {
+ error = elf_errno();
+ TP_FAIL("flag=0x%x, error=%d \"%s\".", flag, error,
+ elf_errmsg(error));
+ goto done;
+ }',`_TP_EPILOGUE')')
+
+/*
+ * TP_FLAG_ILLEGAL_CMD(FN, ARG, LEGALFLAGS)
+ *
+ * Check that all flag values other than those in LEGALFLAGS are
+ * rejected with ELF_E_ARGUMENT.
+ */
+define(`TP_FLAG_ILLEGAL_FLAG',`_TP_FLAG_FN(`tcArgsIllegalFlags',`
+ int error, ret;
+ unsigned int flags;
+
+ _TP_DECLARATIONS
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("Illegal flag values are rejected.");
+
+ _TP_PROLOGUE',`
+ result = TET_PASS;
+ for (flags = 0x1; flags; flags <<= 1) {
+ if (flags & ($3))
+ continue;
+ if ((ret = $1($2, ELF_C_SET, flags)) != 0 ||
+ (error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("ret=%d, error=%d \"%s\".", ret, error,
+ elf_errmsg(error));
+ goto done;
+ }
+ }',`_TP_EPILOGUE')')
+
+/*
+ * TP_FLAG_NON_ELF(FN,ARG)
+ *
+ * Check that a non-elf file is rejected.
+ */
+define(`TP_FLAG_NON_ELF',`
+char *rawdata = "This is not an ELF file.";
+_TP_FLAG_FN(`tcArgsNonElf',`
+ int error, ret;
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("Non-ELF files are rejected.");
+
+ TS_OPEN_MEMORY(e, rawdata);',`
+ result = TET_PASS;
+ if ((ret = $1(e, ELF_C_SET, ELF_F_DIRTY)) != 0 ||
+ (error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("ret=%d, error=%d \"%s\".", ret, error,
+ elf_errmsg(error));
+ }',`')')
+
+divert(0)
diff --git a/test/libelf/tset/common/elfts-compare-files.c b/test/libelf/tset/common/elfts-compare-files.c
new file mode 100644
index 0000000000000..6d22dc9f0dd34
--- /dev/null
+++ b/test/libelf/tset/common/elfts-compare-files.c
@@ -0,0 +1,125 @@
+/*-
+ * Copyright (c) 2006,2010 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: elfts-compare-files.c 1193 2010-09-12 05:43:52Z jkoshy $
+ */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+
+/*
+ * A helper function to compare a generated file against
+ * a reference.
+ */
+
+int
+elfts_compare_files(const char *rfn, const char *fn)
+{
+ int fd, result, rfd;
+ struct stat sb, rsb;
+ char *m, *rm;
+ size_t c, nc;
+
+ fd = rfd = -1;
+ m = rm = NULL;
+ result = TET_UNRESOLVED;
+
+ if ((fd = open(fn, O_RDONLY, 0)) < 0) {
+ tet_printf("U: open \"%s\" failed: %s.", fn,
+ strerror(errno));
+ goto done;
+ }
+
+ if ((rfd = open(rfn, O_RDONLY, 0)) < 0) {
+ tet_printf("U: open \"%s\" failed: %s.", rfn,
+ strerror(errno));
+ goto done;
+ }
+
+ if (fstat(fd, &sb) < 0) {
+ tet_printf("U: fstat \"%s\" failed: %s.", fn,
+ strerror(errno));
+ goto done;
+ }
+
+ if (fstat(rfd, &rsb) < 0) {
+ tet_printf("U: fstat \"%s\" failed: %s.", rfn,
+ strerror(errno));
+ goto done;
+ }
+
+ if (sb.st_size != rsb.st_size) {
+ tet_printf("F: refsz(%d) != target(%d).", rsb.st_size, sb.st_size);
+ result = TET_FAIL;
+ goto done;
+ }
+
+ if ((m = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd,
+ (off_t) 0)) == MAP_FAILED) {
+ tet_printf("U: mmap \"%s\" failed: %s.", fn,
+ strerror(errno));
+ goto done;
+ }
+
+ if ((rm = mmap(NULL, rsb.st_size, PROT_READ, MAP_SHARED, rfd,
+ (off_t) 0)) == MAP_FAILED) {
+ tet_printf("U: mmap \"%s\" failed: %s.", rfn,
+ strerror(errno));
+ goto done;
+ }
+
+ result = TET_PASS;
+ nc = sb.st_size;
+
+ /* Compare bytes. */
+ for (c = 0; c < nc && *m == *rm; c++, m++, rm++)
+ ;
+ if (c != nc) {
+ tet_printf("F: @ offset 0x%x ref[%d] != actual[%d].", c,
+ *rm, *m);
+ result = TET_FAIL;
+ }
+
+ done:
+ if (m)
+ (void) munmap(m, sb.st_size);
+ if (rm)
+ (void) munmap(rm, rsb.st_size);
+ if (fd != -1)
+ (void) close(fd);
+ if (rfd != -1)
+ (void) close(rfd);
+ return (result);
+
+}
diff --git a/test/libelf/tset/common/elfts-copy-file.c b/test/libelf/tset/common/elfts-copy-file.c
new file mode 100644
index 0000000000000..1fef268e3dbd0
--- /dev/null
+++ b/test/libelf/tset/common/elfts-copy-file.c
@@ -0,0 +1,107 @@
+/*-
+ * Copyright (c) 2010 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: elfts-copy-file.c 2077 2011-10-27 03:59:40Z jkoshy $
+ */
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "elfts.h"
+
+/*
+ * A helper function to copy a file to a temporary. Returns the name
+ * of the temporary file created.
+ */
+
+#define ELFTS_BUFSIZE 4096
+#define ELFTS_NAME_TEMPLATE "elftsXXXXXXXX"
+
+char *
+elfts_copy_file(const char *rfn, int *error)
+{
+ int rfd, wfd;
+ ssize_t nr, nw, wrem;
+ char buf[ELFTS_BUFSIZE], *bp, *wfn;
+
+ *error = 0;
+ rfd = wfd = -1;
+ bp = wfn = NULL;
+
+ if ((wfn = malloc(sizeof(ELFTS_NAME_TEMPLATE))) == NULL)
+ return NULL;
+
+ (void) strcpy(wfn, ELFTS_NAME_TEMPLATE);
+
+ if ((wfd = mkstemp(wfn)) == -1)
+ goto error;
+
+ if ((rfd = open(rfn, O_RDONLY)) == -1)
+ goto error;
+
+ /*
+ * Copy the bits over.
+ *
+ * Explicitly check for the POSIX `EINTR` error return so that
+ * the code works correctly non-BSD systems.
+ */
+ for (;;) {
+ if ((nr = read(rfd, buf, sizeof(buf))) < 0) {
+ if (errno == EINTR)
+ continue;
+ goto error;
+ }
+
+ if (nr == 0)
+ break; /* EOF */
+
+ for (bp = buf, wrem = nr; wrem > 0; bp += nw, wrem -= nw) {
+ if ((nw = write(wfd, bp, wrem)) < 0) {
+ if (errno == EINTR)
+ continue;
+ goto error;
+ }
+ }
+ }
+
+ (void) close(rfd);
+ (void) close(wfd);
+ return (wfn);
+
+ error:
+ *error = errno;
+
+ if (wfd)
+ (void) close(wfd);
+ if (rfd)
+ (void) close(rfd);
+ if (wfn) {
+ (void) unlink(wfn);
+ free(wfn);
+ }
+ return (NULL);
+}
+
diff --git a/test/libelf/tset/common/elfts-initversion.c b/test/libelf/tset/common/elfts-initversion.c
new file mode 100644
index 0000000000000..bab1cc91d7e88
--- /dev/null
+++ b/test/libelf/tset/common/elfts-initversion.c
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2006 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: elfts-initversion.c 223 2008-08-10 15:40:06Z jkoshy $
+ */
+
+#include <libelf.h>
+
+#include "tet_api.h"
+
+/*
+ * A TET startup() function for test cases that need elf_version()
+ * to be called before each invocable component.
+ */
+
+int elfts_tcinit = TET_PASS;
+
+void
+elfts_init_version(void)
+{
+ if (elf_version(EV_CURRENT) != EV_CURRENT) {
+ tet_printf("setup: elf_version() failed: %s",
+ elf_errmsg(-1));
+ elfts_tcinit = TET_UNRESOLVED;
+ }
+}
diff --git a/test/libelf/tset/common/elfts-openfile.c b/test/libelf/tset/common/elfts-openfile.c
new file mode 100644
index 0000000000000..6f6640a489f60
--- /dev/null
+++ b/test/libelf/tset/common/elfts-openfile.c
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 2006,2010 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: elfts-openfile.c 1192 2010-09-12 05:40:00Z jkoshy $
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <string.h>
+
+#include "tet_api.h"
+
+#include "elfts.h"
+
+/*
+ * A TET startup() function for test cases that need elf_version()
+ * to be called before each invocable component.
+ */
+
+Elf *
+elfts_open_file(const char *fn, Elf_Cmd cmd, int *fdp)
+{
+ Elf *e;
+ int fd, mode;
+
+ switch (cmd) {
+ case ELF_C_WRITE:
+ mode = O_WRONLY | O_CREAT;
+ break;
+ case ELF_C_READ:
+ mode = O_RDONLY;
+ break;
+ case ELF_C_RDWR:
+ mode = O_RDWR;
+ break;
+ default:
+ tet_printf("internal error: unknown cmd=%d.", cmd);
+ return (NULL);
+ }
+
+ if ((fd = open(fn, mode, 0644)) < 0) {
+ tet_printf("setup: open \"%s\" failed: %s.", fn,
+ strerror(errno));
+ return (NULL);
+ }
+
+ if (fdp)
+ *fdp = fd;
+
+ if ((e = elf_begin(fd, cmd, NULL)) == NULL) {
+ tet_printf("setup: elf_begin(%s) failed: %s.", fn,
+ elf_errmsg(-1));
+ tet_result(TET_UNRESOLVED);
+ }
+
+ return (e);
+}
diff --git a/test/libelf/tset/common/elfts.h b/test/libelf/tset/common/elfts.h
new file mode 100644
index 0000000000000..b1632da831d67
--- /dev/null
+++ b/test/libelf/tset/common/elfts.h
@@ -0,0 +1,118 @@
+/*-
+ * Copyright (c) 2006,2010 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: elfts.h 1337 2010-12-31 15:38:31Z jkoshy $
+ */
+
+#ifndef _ELF_TS_H_
+#define _ELF_TS_H_ 1
+
+/*
+ * Common definitions used by test cases.
+ */
+
+/* Invocable component requires elf_version() to be set. */
+#define IC_REQUIRES_VERSION_INIT() \
+ extern int elfts_tcinit; \
+ void (*tet_startup)(void) = elfts_init_version
+
+/* Test purpose needs to check for initialization success */
+#define TP_CHECK_INITIALIZATION() do { \
+ if (elfts_tcinit != TET_PASS) { \
+ tet_infoline("unresolved: test case setup " \
+ "failed."); \
+ tet_result(elfts_tcinit); \
+ return; \
+ } \
+ } while (0)
+
+/* Treat a memory area as containing ELF data */
+#define TS_OPEN_MEMORY(E,M) do { \
+ if (((E) = elf_memory((M), sizeof((M)))) == NULL) { \
+ tet_infoline("unresolved: elf_memory() " \
+ "failed."); \
+ tet_result(TET_UNRESOLVED); \
+ return; \
+ } \
+ } while (0)
+
+/* Get an ELF descriptor for a file */
+#define _TS_OPEN_FILE(E,FN,CMD,FD,ACTION) do { \
+ if (((E) = elfts_open_file((FN),(CMD),&(FD))) == NULL) \
+ ACTION \
+ } while (0)
+
+#define TS_OPEN_FILE(E,FN,CMD,FD) _TS_OPEN_FILE(E,FN,CMD,FD,return;)
+
+#define _TS_WRITE_FILE(FN,DATA,DSZ,ACTION) do { \
+ int _fd; \
+ if ((_fd = open((FN), O_CREAT|O_WRONLY, 0666)) < 0) { \
+ tet_printf("unresolved: open("FN") failed: %s.",\
+ strerror(errno)); \
+ ACTION \
+ } \
+ if (write(_fd, (DATA), (DSZ)) != (DSZ)) { \
+ tet_printf("unresolved: write("FN") failed: %s.",\
+ strerror(errno)); \
+ ACTION \
+ } \
+ (void) close(_fd); \
+ } while (0)
+
+#define _TS_READ_FILE(FN,DATA,DSZ,ACTION) do { \
+ int _fd; \
+ size_t _rsz, _sz; \
+ struct stat _sb; \
+ if ((_fd = open((FN), O_RDONLY, 0)) < 0) { \
+ tet_printf("unresolved: open("FN") failed: %s.", \
+ strerror(errno)); \
+ ACTION \
+ } \
+ if (fstat(_fd, &_sb) < 0) { \
+ tet_printf("unresolved: fstat("FN") failed: %s.", \
+ strerror(errno)); \
+ ACTION \
+ } \
+ if ((DSZ) < _sb.st_size) \
+ _sz = (DSZ); \
+ else \
+ _sz = _sb.st_size; \
+ if ((_rsz = read(_fd, (DATA), _sz)) != _sz) { \
+ tet_printf("unresolved: read("FN") failed: %s.", \
+ strerror(errno)); \
+ ACTION \
+ } \
+ (void) close(_fd); \
+ } while (0)
+
+#define TS_NEWFILE "new.file"
+
+void elfts_init_version(void);
+
+Elf *elfts_open_file(const char *_fn, Elf_Cmd _cmd, int *_fdp);
+int elfts_compare_files(const char *_reffn, const char *fn);
+char *elfts_copy_file(const char *_fn, int *_error);
+
+#endif /* _LIBELF_TS_H_ */
diff --git a/test/libelf/tset/common/fsize.yaml b/test/libelf/tset/common/fsize.yaml
new file mode 100644
index 0000000000000..cd6cbe7b1cbec
--- /dev/null
+++ b/test/libelf/tset/common/fsize.yaml
@@ -0,0 +1,16 @@
+%YAML 1.1
+# $Id: fsize.yaml 2053 2011-10-26 11:50:18Z jkoshy $
+---
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_data: ELFDATANONE
+ ei_osabi: ELFOSABI_FREEBSD
+ ei_abiversion: 1
+ ei_class: ELFCLASSNONE
+ e_type: ET_REL
+ e_machine: EM_NONE
+ e_version: EV_CURRENT
+ e_flags: [2, 1]
+ e_entry: 0xdeadbeef
+ e_phoff: 0
+ e_shoff: 0
diff --git a/test/libelf/tset/common/gelf_ehdr_template.h b/test/libelf/tset/common/gelf_ehdr_template.h
new file mode 100644
index 0000000000000..741409e28d024
--- /dev/null
+++ b/test/libelf/tset/common/gelf_ehdr_template.h
@@ -0,0 +1,167 @@
+/*-
+ * Copyright (c) 2006 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: gelf_ehdr_template.h 223 2008-08-10 15:40:06Z jkoshy $
+ */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+
+/*
+ * Boilerplate for testing gelf_getehdr() and gelf_newehdr().
+ *
+ * Usage:
+ *
+ * For gelf_getehdr() define:
+ * #define TC_ICFUNC(E,V) gelf_getehdr(E,V)
+ * For gelf_newehdr() define:
+ # #define TC_ICFUNC(E,V)
+ * #include "gelf_getehdr_template.c"
+ */
+
+#include <sys/cdefs.h>
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * The values here must match those in the "ehdr.yaml" file.
+ */
+
+#define CHECK_SIGFIELD(E,I,V) do { \
+ if ((E)->e_ident[EI_##I] != (V)) { \
+ tet_printf("fail: " #I " value 0x%x != " \
+ "expected 0x%x.", (E)->e_ident[EI_##I], \
+ (V)); \
+ result = TET_FAIL; \
+ } \
+ } while (0)
+
+#define CHECK_SIG(E,ED,EC,EV,EABI,EABIVER) do { \
+ if ((E)->e_ident[EI_MAG0] != ELFMAG0 || \
+ (E)->e_ident[EI_MAG1] != ELFMAG1 || \
+ (E)->e_ident[EI_MAG2] != ELFMAG2 || \
+ (E)->e_ident[EI_MAG3] != ELFMAG3) { \
+ tet_printf("fail: incorrect ELF signature " \
+ "(%x %x %x %x).", (E)->e_ident[EI_MAG0], \
+ (E)->e_ident[EI_MAG1], (E)->e_ident[EI_MAG2],\
+ (E)->e_ident[EI_MAG3]); \
+ result = TET_FAIL; \
+ } \
+ CHECK_SIGFIELD(E,CLASS, EC); \
+ CHECK_SIGFIELD(E,DATA, ED); \
+ CHECK_SIGFIELD(E,VERSION, EV); \
+ CHECK_SIGFIELD(E,OSABI, EABI); \
+ CHECK_SIGFIELD(E,ABIVERSION, EABIVER); \
+ } while (0)
+
+
+#define CHECK_FIELD(E,FIELD,VALUE) do { \
+ if ((E)->e_##FIELD != (VALUE)) { \
+ tet_printf("fail: field \"%s\" actual 0x%jx " \
+ "!= expected 0x%jx.", #FIELD, \
+ (uintmax_t) (E)->e_##FIELD, \
+ (uintmax_t) (VALUE)); \
+ tet_result(TET_FAIL); \
+ return; \
+ } \
+ } while (0)
+
+#define CHECK_EHDR(E,ED,EC) do { \
+ CHECK_SIG(E,ED,EC,EV_CURRENT,ELFOSABI_FREEBSD,1); \
+ CHECK_FIELD(E,type, ET_REL); \
+ CHECK_FIELD(E,machine, 0x42); \
+ CHECK_FIELD(E,version, EV_CURRENT); \
+ CHECK_FIELD(E,entry, 0xF0F0F0F0); \
+ CHECK_FIELD(E,phoff, 0x0E0E0E0E); \
+ CHECK_FIELD(E,shoff, 0xD0D0D0D0); \
+ CHECK_FIELD(E,flags, 64+8+2+1); \
+ CHECK_FIELD(E,ehsize, 0x0A0A); \
+ CHECK_FIELD(E,phentsize,0xB0B0); \
+ CHECK_FIELD(E,phnum, 0x0C0C); \
+ CHECK_FIELD(E,shentsize,0xD0D0); \
+ CHECK_FIELD(E,shnum, 0x0E0E); \
+ CHECK_FIELD(E,shstrndx, 0xF0F0); \
+ } while (0)
+
+#define COMPARE_SIG(FN,H1,H2) do { \
+ if (memcmp(H1.e_ident,H2.e_ident,EI_NIDENT) != 0) { \
+ tet_printf("fail: \"%s\" e_ident mismatch.", \
+ FN); \
+ result = TET_FAIL; \
+ } \
+ } while (0)
+#define COMPARE_FIELD(FN,H1,H2,FIELD) do { \
+ if (H1.e_##FIELD != H2.e_##FIELD) { \
+ tet_printf("fail: \"%s\" (e_" #FIELD ") 0x%jx " \
+ "!= 0x%jx.", FN, (uintmax_t) H1.e_##FIELD, \
+ (uintmax_t) H2.e_##FIELD); \
+ result = TET_FAIL; \
+ } \
+ } while (0)
+#define COMPARE_EHDR(FN,H1,H2) do { \
+ COMPARE_SIG(FN,H1,H2); \
+ COMPARE_FIELD(FN,H1,H2,type); \
+ COMPARE_FIELD(FN,H1,H2,machine); \
+ COMPARE_FIELD(FN,H1,H2,version); \
+ COMPARE_FIELD(FN,H1,H2,entry); \
+ COMPARE_FIELD(FN,H1,H2,phoff); \
+ COMPARE_FIELD(FN,H1,H2,shoff); \
+ COMPARE_FIELD(FN,H1,H2,flags); \
+ COMPARE_FIELD(FN,H1,H2,ehsize); \
+ COMPARE_FIELD(FN,H1,H2,phentsize); \
+ COMPARE_FIELD(FN,H1,H2,phnum); \
+ COMPARE_FIELD(FN,H1,H2,shentsize); \
+ COMPARE_FIELD(FN,H1,H2,shnum); \
+ COMPARE_FIELD(FN,H1,H2,shstrndx); \
+ } while (0)
+
+/*
+ * Non-ELF data.
+ */
+
+static char data[] = "This isn't an ELF file.";
+
+
+/*
+ * A malformed (too short) ELF header.
+ */
+
+static char badelftemplate[EI_NIDENT+1] = {
+ [EI_MAG0] = '\177',
+ [EI_MAG1] = 'E',
+ [EI_MAG2] = 'L',
+ [EI_MAG3] = 'F',
+ [EI_NIDENT] = '@'
+};
+
diff --git a/test/libelf/tset/common/getclass.yaml b/test/libelf/tset/common/getclass.yaml
new file mode 100644
index 0000000000000..f438651febcc5
--- /dev/null
+++ b/test/libelf/tset/common/getclass.yaml
@@ -0,0 +1,16 @@
+%YAML 1.1
+# $Id: getclass.yaml 2053 2011-10-26 11:50:18Z jkoshy $
+---
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_data: ELFDATANONE
+ ei_osabi: ELFOSABI_FREEBSD
+ ei_abiversion: 1
+ ei_class: ELFCLASSNONE
+ e_type: ET_REL
+ e_machine: EM_NONE
+ e_version: EV_CURRENT
+ e_flags: [2, 1]
+ e_entry: 0xdeadbeef
+ e_phoff: 0
+ e_shoff: 0
diff --git a/test/libelf/tset/common/getshdr.m4 b/test/libelf/tset/common/getshdr.m4
new file mode 100644
index 0000000000000..060c1f44a4206
--- /dev/null
+++ b/test/libelf/tset/common/getshdr.m4
@@ -0,0 +1,171 @@
+/*-
+ * Copyright (c) 2006 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: getshdr.m4 223 2008-08-10 15:40:06Z jkoshy $
+ */
+
+/*
+ * TP_NULL(CLASS)
+ *
+ * Check that a NULL argument returns ELF_E_ARGUMENT.
+ */
+
+define(`TP_NULL',`
+void
+tcNull_tpNull$1(void)
+{
+ int error, result;
+ Elf$1_Shdr *sh;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf$1_getshdr(NULL) fails with ELF_E_ARGUMENT.");
+
+ result = TET_PASS;
+ if ((sh = elf$1_getshdr(NULL)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("sh=%p error=%d \"%s\".", (void *) sh,
+ error, elf_errmsg(error));
+
+ tet_result(result);
+}')
+
+/* TP_CHECK_FIELD(I, SH,REF,FIELD) */
+define(`TP_CHECK_FIELD',`do {
+ if ($2->$4 != $3->$4) {
+ TP_FAIL("field[%d] \"$4\" %jd != ref %jd.", $1,
+ (uintmax_t) $2->$4, (uintmax_t) $3->$4);
+ goto done;
+ }
+ } while (0)')
+/* TP_CHECK_SHDR(IND, SH, REF) */
+define(`TP_CHECK_SHDR',`do {
+ TP_CHECK_FIELD($1,$2,$3,sh_name);
+ TP_CHECK_FIELD($1,$2,$3,sh_type);
+ TP_CHECK_FIELD($1,$2,$3,sh_flags);
+ TP_CHECK_FIELD($1,$2,$3,sh_addr);
+ TP_CHECK_FIELD($1,$2,$3,sh_offset);
+ TP_CHECK_FIELD($1,$2,$3,sh_size);
+ TP_CHECK_FIELD($1,$2,$3,sh_link);
+ TP_CHECK_FIELD($1,$2,$3,sh_info);
+ TP_CHECK_FIELD($1,$2,$3,sh_addralign);
+ TP_CHECK_FIELD($1,$2,$3,sh_entsize);
+ } while (0)')
+
+/*
+ * TC_MAKE_REF_SHDR(CLASS)
+ *
+ * This must match the values in "shdr.yaml".
+ */
+define(`TC_MAKE_REF_SHDR',`
+static Elf$1_Shdr RefShdr$1[] = {
+ /* index 0 */
+ { .sh_type = SHT_NULL },
+ /* index 1 : .shstrtab */
+ { .sh_name = 1, .sh_type = SHT_STRTAB, .sh_flags = SHF_ALLOC | SHF_STRINGS,
+ .sh_offset = 256, .sh_link = ~0, .sh_info = ~0, .sh_addralign = 1,
+ .sh_entsize = 0, .sh_size = 38 },
+ /* index 2 : SHT_PROGBITS */
+ { .sh_name = 11, .sh_type = SHT_PROGBITS, .sh_flags = SHF_ALLOC, .sh_offset = 128,
+ .sh_link = 0xdeadc0de, .sh_info = 0xcafebabe, .sh_addralign = 8,
+ .sh_entsize = 0 }
+};
+
+#define NSHDR (sizeof(RefShdr$1)/sizeof(RefShdr$1[0]))
+')
+
+/*
+ * TP_SHDR(CLASS,ENDIANNESS)
+ *
+ * Check that the Shdrs returned are valid.
+ */
+
+define(`TP_SHDR',`
+void
+tcShdr_tpValid$1`'TOUPPER($2)(void)
+{
+ int i, fd;
+ Elf *e;
+ Elf$1_Shdr *sh, *rs;
+ Elf_Scn *scn;
+ int error, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: Check shdr contents.");
+
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ _TS_OPEN_FILE(e, "shdr.$2$1", ELF_C_READ, fd, goto done;);
+
+ i = SHN_UNDEF;
+ rs = RefShdr$1;
+
+ if ((scn = elf_getscn(e, i)) == NULL) {
+ TP_UNRESOLVED("elf_getscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_FAIL("elf$1_getshdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ TP_CHECK_SHDR(i, sh, rs);
+
+ while ((scn = elf_nextscn(e, scn)) != NULL) {
+
+ i++; rs++;
+
+ if (i >= NSHDR) {
+ TP_UNRESOLVED("Too many (%d) sections.", i);
+ goto done;
+ }
+
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_FAIL("elf$1_getshdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ TP_CHECK_SHDR(i, sh, rs);
+
+ }
+
+ result = TET_PASS;
+ if ((error = elf_errno()) != ELF_E_NONE)
+ TP_UNRESOLVED("error=%d \"%s\".", error, elf_errmsg(error));
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ tet_result(result);
+}')
diff --git a/test/libelf/tset/common/newehdr.yaml b/test/libelf/tset/common/newehdr.yaml
new file mode 100644
index 0000000000000..bc717dbe61679
--- /dev/null
+++ b/test/libelf/tset/common/newehdr.yaml
@@ -0,0 +1,7 @@
+%YAML 1.1
+# $Id: newehdr.yaml 2053 2011-10-26 11:50:18Z jkoshy $
+---
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
diff --git a/test/libelf/tset/common/newehdr_template.m4 b/test/libelf/tset/common/newehdr_template.m4
new file mode 100644
index 0000000000000..52a7cea3ec86f
--- /dev/null
+++ b/test/libelf/tset/common/newehdr_template.m4
@@ -0,0 +1,243 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: newehdr_template.m4 1376 2011-01-23 04:15:51Z jkoshy $
+ */
+
+#include <stdlib.h>
+
+/*
+ * Boilerplate for testing newehdr{32,64} behaviour that is not
+ * common to the getehdr{32,64} functions.
+ */
+
+define(`TS_NEWELF',`"new.elf"')
+
+ifdef(`TS_ICNAME',`',
+ `errprint(`File included before "ehdr_template.m4".')m4exit(1)')
+
+#define CHECK_NEWEHDR(E,VER) do { \
+ if ((E)->e_ident[EI_MAG0] != ELFMAG0 || \
+ (E)->e_ident[EI_MAG1] != ELFMAG1 || \
+ (E)->e_ident[EI_MAG2] != ELFMAG2 || \
+ (E)->e_ident[EI_MAG3] != ELFMAG3 || \
+ (E)->e_ident[EI_CLASS] != TS_ELFCLASS || \
+ (E)->e_ident[EI_DATA] != ELFDATANONE || \
+ (E)->e_ident[EI_VERSION] != (VER) || \
+ (E)->e_machine != EM_NONE || \
+ (E)->e_type != ELF_K_NONE || \
+ (E)->e_version != (VER)) \
+ TP_FAIL("TS_ICNAME`'() header mismatch."); \
+ } while (0)
+
+/*
+ * Verify that a new ehdr has the appropriate defaults.
+ */
+
+void
+tcAllocateCheckDefaults(void)
+{
+ TS_EHDR *eh;
+ Elf *e;
+ int fd, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TS_ICNAME`'() allocates an ehdr with the "
+ "documented defaults.");
+
+ TS_OPEN_FILE(e, TS_NEWELF, ELF_C_WRITE, fd);
+
+ result = TET_PASS;
+
+ if ((eh = TS_ICFUNC`'(e)) == NULL) {
+ TP_FAIL("TS_ICNAME`'() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ CHECK_NEWEHDR(eh,EV_CURRENT);
+
+ done:
+ (void) elf_end(e);
+ (void) close(fd);
+ (void) unlink(TS_NEWELF);
+
+ tet_result(result);
+}
+
+/*
+ * Verify that a new ehdr is marked `dirty'. This test uses extended
+ * functionality in libelf.
+ */
+
+void
+tcAllocateFlagDirty(void)
+{
+ TS_EHDR *eh;
+ Elf *e;
+ int fd, flags, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TS_ICNAME`'() marks the new Ehdr as \"dirty\".");
+
+ TS_OPEN_FILE(e, TS_NEWELF, ELF_C_WRITE, fd);
+
+ if ((eh = TS_ICFUNC`'(e)) == NULL) {
+ TP_UNRESOLVED("TS_ICNAME`'() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ flags = elf_flagehdr(e, ELF_C_CLR, 0); /* Our extension */
+
+ tet_result((flags & ELF_F_DIRTY) == 0 ? TET_FAIL : TET_PASS);
+
+ done:
+ (void) unlink(TS_NEWELF);
+ (void) elf_end(e);
+ (void) close(fd);
+}
+
+/* Declare fixed sizes associated with an ELF header. */
+ifelse(`TS_EHDRSZ',`32',`
+#define TS_EHSIZE 52
+#define TS_PHENTSIZE 32
+#define TS_SHENTSIZE 40
+',`
+#define TS_EHSIZE 64
+#define TS_PHENTSIZE 56
+#define TS_SHENTSIZE 64
+')
+
+define(`TS_REFELF',`newehdr')
+
+/*
+ * Verify that the correct header is written out.
+ */
+
+define(`FN',`
+void
+tcUpdate$1`'TS_EHDRSZ`'(void)
+{
+ TS_EHDR *eh;
+ Elf *e;
+ int fd, reffd, result;
+ off_t offset;
+ size_t fsz;
+ void *t, *tref;
+ char *ref = "TS_REFELF.TOLOWER($1)`'TS_EHDRSZ";
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("the contents of the Ehdr for byteorder $1 are correct.");
+
+ t = tref = NULL;
+ fd = reffd = -1;
+
+ TS_OPEN_FILE(e, TS_NEWELF, ELF_C_WRITE, fd);
+
+ result = TET_UNRESOLVED;
+
+ if ((eh = TS_ICFUNC`'(e)) == NULL) {
+ TP_UNRESOLVED("TS_ICNAME`'() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ eh->e_ident[EI_DATA] = ELFDATA2$1;
+
+ /* Write out the new ehdr. */
+ if ((offset = elf_update(e, ELF_C_WRITE)) < 0) {
+ TP_UNRESOLVED("elf_update() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ /* check that the correct number of bytes were written out. */
+ fsz = elf`'TS_EHDRSZ`'_fsize(ELF_T_EHDR, 1, EV_CURRENT);
+
+ if (offset != fsz) {
+ TP_FAIL("elf_update() -> %d, expected %d.", offset, fsz);
+ goto done;
+ }
+
+ (void) elf_end(e); e = NULL;
+ (void) close(fd); fd = -1;
+
+ if ((t = malloc(fsz)) == NULL) {
+ TP_UNRESOLVED("malloc %d bytes failed: %s.", fsz,
+ strerror(errno));
+ goto done;
+ }
+
+ if ((fd = open(TS_NEWELF, O_RDONLY, 0)) < 0) {
+ TP_UNRESOLVED("open() failed: %s.", strerror(errno));
+ goto done;
+ }
+
+ if (read(fd, t, fsz) != fsz) {
+ TP_UNRESOLVED("read %d bytes failed: %s.", fsz,
+ strerror(errno));
+ goto done;
+ }
+
+ if ((reffd = open(ref, O_RDONLY, 0)) < 0) {
+ TP_UNRESOLVED("open(%s) failed: %s.", ref,
+ strerror(errno));
+ goto done;
+ }
+
+ if ((tref = malloc(fsz)) == NULL) {
+ TP_UNRESOLVED("malloc %d bytes failed: %s.", fsz,
+ strerror(errno));
+ goto done;
+ }
+
+ if (read(reffd, tref, fsz) != fsz) {
+ TP_UNRESOLVED("unresolved: read \"%s\" failed: %s.", ref,
+ strerror(errno));
+ goto done;
+ }
+
+ /* Read it back in */
+ result = TET_PASS;
+ if (memcmp(t, tref, fsz) != 0)
+ TP_FAIL("memcmp(" TS_NEWELF ",%s) failed.", ref);
+
+ done:
+ (void) unlink(TS_NEWELF);
+ if (e)
+ (void) elf_end(e);
+ if (tref)
+ free(tref);
+ if (t)
+ free(t);
+ if (fd != -1)
+ (void) close(fd);
+ if (reffd != -1)
+ (void) close(reffd);
+ tet_result(result);
+}')
+
+FN(`LSB')
+FN(`MSB')
diff --git a/test/libelf/tset/common/newscn.yaml b/test/libelf/tset/common/newscn.yaml
new file mode 100644
index 0000000000000..735a450238150
--- /dev/null
+++ b/test/libelf/tset/common/newscn.yaml
@@ -0,0 +1,27 @@
+%YAML 1.1
+# $Id: newscn.yaml 2053 2011-10-26 11:50:18Z jkoshy $
+---
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
+ e_type: ET_REL
+
+sections:
+ - !Section # index 0
+ sh_type: SHT_NULL
+
+ - !Section
+ sh_name: .shstrtab
+ sh_type: SHT_STRTAB
+ sh_data:
+ - .shstrtab
+ - .foobar
+
+ - !Section
+ sh_name: .foobar
+ sh_offset: 2048
+ sh_type: SHT_PROGBITS
+ sh_data:
+ - 0x01234567
+ - 0x89ABCDEF
diff --git a/test/libelf/tset/common/newscn2.yaml b/test/libelf/tset/common/newscn2.yaml
new file mode 100644
index 0000000000000..f9f2c7d8dfe24
--- /dev/null
+++ b/test/libelf/tset/common/newscn2.yaml
@@ -0,0 +1,28 @@
+%YAML 1.1
+# $Id: newscn2.yaml 2077 2011-10-27 03:59:40Z jkoshy $
+#
+# This is the library-defined layout of the 'newscn' ELF object.
+---
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
+ e_type: ET_REL
+
+sections:
+ - !Section # index 0
+ sh_type: SHT_NULL
+
+ - !Section
+ sh_name: .shstrtab
+ sh_type: SHT_STRTAB
+ sh_data:
+ - .shstrtab
+ - .foobar
+
+ - !Section
+ sh_name: .foobar
+ sh_type: SHT_PROGBITS
+ sh_data:
+ - 0x01234567
+ - 0x89ABCDEF
diff --git a/test/libelf/tset/common/phdr.yaml b/test/libelf/tset/common/phdr.yaml
new file mode 100644
index 0000000000000..14ad5d1bb0afb
--- /dev/null
+++ b/test/libelf/tset/common/phdr.yaml
@@ -0,0 +1,38 @@
+%YAML 1.1
+# $Id: phdr.yaml 2053 2011-10-26 11:50:18Z jkoshy $
+---
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
+#
+# These values should match those in "common/phdr_template.c"
+#
+phdrtab:
+ - !Phdr
+ p_type: PT_NULL
+ p_offset: 1
+ p_vaddr: 2
+ p_paddr: 3
+ p_filesz: 4
+ p_memsz: 5
+ p_flags: [ PF_X ]
+ p_align: 1
+ - !Phdr
+ p_type: PT_LOPROC
+ p_offset: 6
+ p_vaddr: 7
+ p_paddr: 8
+ p_filesz: 9
+ p_memsz: 10
+ p_flags: [ PF_R ]
+ p_align: 4
+ - !Phdr
+ p_type: PT_INTERP
+ p_offset: 11
+ p_vaddr: 12
+ p_paddr: 13
+ p_filesz: 14
+ p_memsz: 15
+ p_flags: [ PF_W ]
+ p_align: 8
diff --git a/test/libelf/tset/common/phdr_template.c b/test/libelf/tset/common/phdr_template.c
new file mode 100644
index 0000000000000..808743d9639d2
--- /dev/null
+++ b/test/libelf/tset/common/phdr_template.c
@@ -0,0 +1,418 @@
+/*-
+ * Copyright (c) 2006 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: phdr_template.c 1074 2010-08-09 11:43:34Z jkoshy $
+ */
+
+/*
+ * Boilerplate for testing the *_getphdr and *_newphdr APIs.
+ *
+ * This template is to be used as follows:
+ *
+ * #define TS_PHDRFUNC _getphdr (or _newphdr)
+ * #define TS_PHDRSZ 32 (or 64)
+ * #include "phdr_template.c"
+ */
+
+#include <sys/cdefs.h>
+
+/* Variations of __CONCAT and __STRING which expand their arguments. */
+#define __XCONCAT(x,y) __CONCAT(x,y)
+#ifndef __XSTRING
+#define __XSTRING(x) __STRING(x)
+#endif
+
+#define TS_ICFUNC __XCONCAT(elf,__XCONCAT(TS_PHDRSZ,TS_PHDRFUNC))
+#define TS_PHDR __XCONCAT(Elf,__XCONCAT(TS_PHDRSZ,_Phdr))
+#define TS_ICNAME __XSTRING(TS_ICFUNC)
+#define TS_ELFCLASS __XCONCAT(ELFCLASS,TS_PHDRSZ)
+
+#define TS_GETEHDR __XCONCAT(elf,__XCONCAT(TS_PHDRSZ,_getehdr))
+#define TS_EHDR __XCONCAT(Elf,__XCONCAT(TS_PHDRSZ,_Ehdr))
+
+#define TS_NPHDR 3 /* should match "phdr.yaml" */
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * Reference data for the contents of an Phdr structure. The values
+ * here must match that in the "phdr.yaml" file.
+ */
+
+static TS_PHDR phdr_testdata[TS_NPHDR] = {
+ {
+ .p_type = PT_NULL,
+ .p_offset = 1,
+ .p_vaddr = 2,
+ .p_paddr = 3,
+ .p_filesz = 4,
+ .p_memsz = 5,
+ .p_flags = PF_X,
+ .p_align = 1
+ },
+ {
+ .p_type = PT_NULL,
+ .p_offset = 6,
+ .p_vaddr = 7,
+ .p_paddr = 8,
+ .p_filesz = 9,
+ .p_memsz = 10,
+ .p_flags = PF_R,
+ .p_align = 4
+ },
+ {
+ .p_type = PT_INTERP,
+ .p_offset = 11,
+ .p_vaddr = 12,
+ .p_paddr = 13,
+ .p_filesz = 14,
+ .p_memsz = 15,
+ .p_flags = PF_W,
+ .p_align = 8
+ }
+};
+
+static int
+check_phdr(TS_PHDR *p)
+{
+ int i, result;
+ TS_PHDR *pt;
+
+ result = TET_PASS;
+ for (pt = phdr_testdata, i = 0; i < TS_NPHDR; i++) {
+
+#define CHECK_PH_FIELD(FIELD) do { \
+ if (p->p_##FIELD != pt->p_##FIELD) { \
+ tet_printf("fail: [%d] field \"%s\" actual " \
+ "0x%jx != expected 0x%jx.", i, #FIELD, \
+ (uintmax_t) p->p_##FIELD, \
+ (uintmax_t) pt->p_##FIELD); \
+ result = TET_FAIL; \
+ } \
+ } while (0)
+
+ CHECK_PH_FIELD(type);
+ CHECK_PH_FIELD(offset);
+ CHECK_PH_FIELD(vaddr);
+ CHECK_PH_FIELD(paddr);
+ CHECK_PH_FIELD(filesz);
+ CHECK_PH_FIELD(memsz);
+ CHECK_PH_FIELD(flags);
+ CHECK_PH_FIELD(align);
+
+ if (result != TET_PASS)
+ return (result);
+ }
+
+ return (result);
+}
+
+void
+tcNull_tpGet(void)
+{
+ TP_CHECK_INITIALIZATION();
+
+ tet_infoline("assertion: " TS_ICNAME "(NULL) fails with "
+ "ELF_E_ARGUMENT.");
+
+ if (TS_ICFUNC(NULL) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ tet_result(TET_FAIL);
+ else
+ tet_result(TET_PASS);
+}
+
+static char data[] = "This isn't an ELF file.";
+
+void
+tcData_tpElf(void)
+{
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ tet_infoline("assertion: " TS_ICNAME "(E) for non-ELF (E) fails with "
+ "ELF_E_ARGUMENT.");
+
+ TS_OPEN_MEMORY(e, data);
+
+ if (TS_ICFUNC(e) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ tet_result(TET_FAIL);
+ else
+ tet_result(TET_PASS);
+
+ (void) elf_end(e);
+}
+
+
+/*
+ * A malformed (too short) ELF header.
+ */
+
+static char badelftemplate[EI_NIDENT+1] = {
+ [EI_MAG0] = '\177',
+ [EI_MAG1] = 'E',
+ [EI_MAG2] = 'L',
+ [EI_MAG3] = 'F',
+ [EI_CLASS] = ELFCLASS64,
+ [EI_DATA] = ELFDATA2MSB,
+ [EI_NIDENT] = '@'
+};
+
+void
+tcBadElfVersion_tpElf(void)
+{
+ int err;
+ Elf *e;
+ TS_PHDR *ph;
+ char badelf[sizeof(badelftemplate)];
+
+ TP_CHECK_INITIALIZATION();
+
+ tet_infoline("assertion: " TS_ICNAME "() with an unsupported version "
+ "fails with ELF_E_VERSION.");
+
+ (void) memcpy(badelf, badelftemplate, sizeof(badelf));
+
+ badelf[EI_VERSION] = EV_NONE;
+ badelf[EI_CLASS] = TS_ELFCLASS;
+
+ TS_OPEN_MEMORY(e, badelf);
+
+ if ((ph = TS_ICFUNC(e)) != NULL ||
+ (err = elf_errno()) != ELF_E_VERSION) {
+ tet_printf("fail: error=%d ph=%p.", err, (void *) ph);
+ tet_result(TET_FAIL);
+ } else
+ tet_result(TET_PASS);
+
+ (void) elf_end(e);
+}
+
+void
+tcBadElf_tpElf(void)
+{
+ int err;
+ Elf *e;
+ TS_PHDR *ph;
+ char badelf[sizeof(badelftemplate)];
+
+ TP_CHECK_INITIALIZATION();
+
+ tet_infoline("assertion: " TS_ICNAME "() on a malformed ELF file "
+ "fails with ELF_E_HEADER.");
+
+ (void) memcpy(badelf, badelftemplate, sizeof(badelf));
+ badelf[EI_VERSION] = EV_CURRENT;
+ badelf[EI_CLASS] = TS_ELFCLASS;
+
+ TS_OPEN_MEMORY(e, badelf);
+
+ if ((ph = TS_ICFUNC(e)) != NULL ||
+ (err = elf_errno()) != ELF_E_HEADER) {
+ tet_printf("fail: error=%d ph=%p.", err, (void *) ph);
+ tet_result(TET_FAIL);
+ } else
+ tet_result(TET_PASS);
+
+ (void) elf_end(e);
+}
+
+void
+tcElf_tpCorruptEhdr(void)
+{
+ int err, fd, result;
+ char *fn;
+ Elf *e;
+ TS_PHDR *ph;
+
+ TP_CHECK_INITIALIZATION();
+
+ tet_infoline("assertion: " TS_ICNAME "(E) with corrupt phdr values "
+ "the header returns E_HEADER.");
+
+ fn = "ehdr.msb" __XSTRING(TS_PHDRSZ);
+ TS_OPEN_FILE(e, fn, ELF_C_READ, fd);
+
+ result = TET_PASS;
+
+ if ((ph = TS_ICFUNC(e)) != NULL ||
+ (err = (elf_errno() != ELF_E_HEADER))) {
+ tet_printf("fail: \"%s\" (ph %p, error %d)", fn, (void *) ph,
+ err);
+ result = TET_FAIL;
+ }
+ (void) elf_end(e);
+ (void) close(fd);
+
+ if (result != TET_PASS) {
+ tet_result(result);
+ return;
+ }
+
+ fn = "ehdr.lsb" __XSTRING(TS_PHDRSZ);
+ TS_OPEN_FILE(e, fn, ELF_C_READ, fd);
+
+ if ((ph = TS_ICFUNC(e)) != NULL ||
+ (err = (elf_errno() != ELF_E_HEADER))) {
+ tet_printf("fail: \"%s\" (ph %p, error %d)", fn, (void *) ph,
+ err);
+ result = TET_FAIL;
+ }
+ (void) elf_end(e);
+ (void) close(fd);
+
+ tet_result(result);
+}
+
+void
+tcElf_tpElfLSB(void)
+{
+ int fd;
+ Elf *e;
+ TS_PHDR *ph;
+
+ TP_CHECK_INITIALIZATION();
+
+ tet_infoline("assertion: " TS_ICNAME "(E) returns the correct LSB phdr.");
+
+ TS_OPEN_FILE(e,"phdr.lsb" __XSTRING(TS_PHDRSZ),ELF_C_READ,fd);
+
+ if ((ph = TS_ICFUNC(e)) == NULL) {
+ tet_infoline("fail: " TS_ICNAME "() failed.");
+ tet_result(TET_FAIL);
+ return;
+ }
+
+ tet_result(check_phdr(ph));
+
+ (void) elf_end(e);
+ (void) close(fd);
+}
+
+void
+tcElf_tpElfMSB(void)
+{
+ int fd;
+ Elf *e;
+ TS_PHDR *ph;
+
+ TP_CHECK_INITIALIZATION();
+
+ tet_infoline("assertion:" TS_ICNAME "(E) returns the correct MSB phdr.");
+
+ TS_OPEN_FILE(e,"phdr.msb" __XSTRING(TS_PHDRSZ),ELF_C_READ,fd);
+
+ if ((ph = TS_ICFUNC(e)) == NULL) {
+ tet_infoline("fail: " TS_ICNAME "() failed.");
+ tet_result(TET_FAIL);
+ return;
+ }
+
+ tet_result(check_phdr(ph));
+
+ (void) elf_end(e);
+ (void) close(fd);
+}
+
+void
+tcElf_tpElfDup(void)
+{
+ int fd;
+ Elf *e;
+ TS_PHDR *ph1, *ph2;
+
+ TP_CHECK_INITIALIZATION();
+
+ tet_infoline("assertion: successful calls to " TS_ICNAME "() return "
+ "identical pointers.");
+
+ TS_OPEN_FILE(e,"phdr.msb" __XSTRING(TS_PHDRSZ),ELF_C_READ,fd);
+
+ if ((ph1 = TS_ICFUNC(e)) == NULL ||
+ (ph2 = TS_ICFUNC(e)) == NULL) {
+ tet_infoline("unresolved: " TS_ICNAME "() failed.");
+ tet_result(TET_UNRESOLVED);
+ return;
+ }
+
+ tet_result(ph1 == ph2 ? TET_PASS : TET_FAIL);
+
+ (void) elf_end(e);
+ (void) close(fd);
+}
+
+#if TS_PHDRSZ == 32
+#define TS_OTHERSIZE 64
+#else
+#define TS_OTHERSIZE 32
+#endif
+
+void
+tcElf_tpElfWrongSize(void)
+{
+ int error, fd, result;
+ Elf *e;
+ char *fn;
+ TS_PHDR *ph;
+
+ TP_CHECK_INITIALIZATION();
+
+ tet_infoline("assertion: a call to " TS_ICNAME "() and a mismatched "
+ "ELF class fails with ELF_E_CLASS.");
+
+ result = TET_PASS;
+
+ fn = "phdr.msb" __XSTRING(TS_OTHERSIZE);
+ TS_OPEN_FILE(e,fn,ELF_C_READ,fd);
+
+ if ((ph = TS_ICFUNC(e)) != NULL ||
+ (error = elf_errno()) != ELF_E_CLASS) {
+ tet_printf("fail: \"%s\" opened (error %d).", fn, error);
+ result = TET_FAIL;
+ }
+
+ (void) elf_end(e);
+ (void) close(fd);
+
+ if (result != TET_PASS) {
+ tet_result(result);
+ return;
+ }
+
+ fn = "phdr.lsb" __XSTRING(TS_OTHERSIZE);
+ TS_OPEN_FILE(e,fn,ELF_C_READ,fd);
+ if ((ph = TS_ICFUNC(e)) != NULL ||
+ (error = elf_errno()) != ELF_E_CLASS) {
+ tet_printf("fail: \"%s\" opened (error %d).", fn, error);
+ result = TET_FAIL;
+ }
+
+ (void) elf_end(e);
+ (void) close(fd);
+
+ tet_result(result);
+}
diff --git a/test/libelf/tset/common/rdwr.yaml b/test/libelf/tset/common/rdwr.yaml
new file mode 100644
index 0000000000000..927c5a4865d4a
--- /dev/null
+++ b/test/libelf/tset/common/rdwr.yaml
@@ -0,0 +1,27 @@
+%YAML 1.1
+---
+# $Id: rdwr.yaml 2077 2011-10-27 03:59:40Z jkoshy $
+#
+# This file is used for tests requiring a well-formed ELF file
+# opened in ELF_C_RDWR mode.
+#
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
+ e_type: ET_REL
+
+sections:
+ - !Section
+ sh_type: SHT_NULL
+ - !Section
+ sh_type: SHT_PROGBITS
+ sh_name: .progbits
+ sh_data:
+ - hello world
+ - !Section
+ sh_type: SHT_STRTAB
+ sh_name: .shstrtab
+ sh_data:
+ - .shstrtab
+ - .progbits
diff --git a/test/libelf/tset/common/rdwr1.yaml b/test/libelf/tset/common/rdwr1.yaml
new file mode 100644
index 0000000000000..433106b967a7c
--- /dev/null
+++ b/test/libelf/tset/common/rdwr1.yaml
@@ -0,0 +1,27 @@
+%YAML 1.1
+# $Id: rdwr1.yaml 2077 2011-10-27 03:59:40Z jkoshy $
+---
+#
+# This file is used for tests requiring a well-formed ELF file
+# opened in ELF_C_RDWR mode.
+#
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
+ e_type: ET_DYN
+
+sections:
+ - !Section
+ sh_type: SHT_NULL
+ - !Section
+ sh_type: SHT_PROGBITS
+ sh_name: .progbits
+ sh_data:
+ - hello world
+ - !Section
+ sh_type: SHT_STRTAB
+ sh_name: .shstrtab
+ sh_data:
+ - .shstrtab
+ - .progbits
diff --git a/test/libelf/tset/common/rdwr2.yaml b/test/libelf/tset/common/rdwr2.yaml
new file mode 100644
index 0000000000000..abb579132ed70
--- /dev/null
+++ b/test/libelf/tset/common/rdwr2.yaml
@@ -0,0 +1,28 @@
+%YAML 1.1
+# $Id: rdwr2.yaml 2077 2011-10-27 03:59:40Z jkoshy $
+---
+#
+# This file is used for tests requiring a well-formed ELF file
+# opened in ELF_C_RDWR mode.
+#
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
+ e_type: ET_REL
+
+sections:
+ - !Section
+ sh_type: SHT_NULL
+ - !Section
+ sh_type: SHT_PROGBITS
+ sh_name: .progbits
+ sh_data:
+ - hello world
+ - goodbye world
+ - !Section
+ sh_type: SHT_STRTAB
+ sh_name: .shstrtab
+ sh_data:
+ - .shstrtab
+ - .progbits
diff --git a/test/libelf/tset/common/shdr.yaml b/test/libelf/tset/common/shdr.yaml
new file mode 100644
index 0000000000000..c8c67a055a226
--- /dev/null
+++ b/test/libelf/tset/common/shdr.yaml
@@ -0,0 +1,42 @@
+%YAML 1.1
+# $Id: shdr.yaml 2053 2011-10-26 11:50:18Z jkoshy $
+---
+#
+# This file is used for tests requiring a set of valid section
+# headers.
+#
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
+ e_type: ET_REL
+
+sections:
+ - !Section # index 0
+ sh_type: SHT_NULL
+ - !Section
+ sh_name: .shstrtab
+ sh_type: SHT_STRTAB
+ sh_flags: [ SHF_ALLOC , SHF_STRINGS ]
+ sh_offset: 256
+ sh_link: 0xFFFFFFFF
+ sh_info: 0xFFFFFFFF
+ sh_addralign: 1
+ sh_entsize: 0
+ sh_data:
+ - .shstrtab
+ - .dynsym
+ - yet another string
+ - !Section
+ sh_name: .dynsym
+ sh_type: SHT_PROGBITS
+ sh_flags: [ SHF_ALLOC ]
+ sh_offset: 128
+ sh_link: 0xdeadc0de
+ sh_info: 0xcafebabe
+ sh_addralign: 8
+ sh_entsize: 0
+
+
+
+
diff --git a/test/libelf/tset/common/u1.yaml b/test/libelf/tset/common/u1.yaml
new file mode 100644
index 0000000000000..992ddd0aded79
--- /dev/null
+++ b/test/libelf/tset/common/u1.yaml
@@ -0,0 +1,29 @@
+%YAML 1.1
+# $Id: u1.yaml 2053 2011-10-26 11:50:18Z jkoshy $
+---
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
+ e_type: ET_REL
+
+phdrtab:
+ - !Phdr
+ p_type: PT_NULL
+ p_offset: 0x0F0F0F0F
+ p_vaddr: 0xA0A0A0A0
+ p_filesz: 0x1234
+ p_memsz: 0x5678
+ p_flags: [ PF_X, PF_R ]
+ p_align: 64
+
+sections:
+ - !Section # index 0
+ sh_type: SHT_NULL
+
+ - !Section
+ sh_name: .shstrtab
+ sh_type: SHT_STRTAB
+ sh_data:
+ - .shstrtab
+
diff --git a/test/libelf/tset/common/versioning.yaml b/test/libelf/tset/common/versioning.yaml
new file mode 100644
index 0000000000000..37e8995b6c466
--- /dev/null
+++ b/test/libelf/tset/common/versioning.yaml
@@ -0,0 +1,55 @@
+%YAML 1.1
+---
+# $Id: versioning.yaml 2077 2011-10-27 03:59:40Z jkoshy $
+#
+# This file is used to test handling of sections with symbol
+# versioning information.
+#
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
+ e_type: ET_REL
+
+sections:
+ - !Section
+ sh_type: SHT_NULL
+ - !Section
+ sh_type: SHT_GNU_verdef
+ sh_name: .gnu.version_d
+ sh_data:
+ - !Verdef
+ vd_version: 1
+ vd_flags: 0
+ vd_ndx: 1
+ vd_cnt: 1
+ vd_hash: 0x1234
+ vd_aux: 42
+ vd_next: 0
+ - !Verdaux
+ vda_name: 1
+ vda_next: 0
+ - !Section
+ sh_type: SHT_GNU_verneed
+ sh_name: .gnu.version_r
+ sh_data:
+ - !Verneed
+ vn_version: 1
+ vn_cnt: 1
+ vn_file: 0x1234
+ vn_aux: 42
+ vn_next: 0
+ - !Vernaux
+ vna_hash: 0x4321
+ vna_flags: 0x1
+ vna_other: 0
+ vna_name: 1
+ vna_next: 0
+ - !Section
+ sh_type: SHT_STRTAB
+ sh_name: .shstrtab
+ sh_data:
+ - .shstrtab
+ - .gnu.version_d
+ - .gnu.version_r
+
diff --git a/test/libelf/tset/common/xlate.yaml b/test/libelf/tset/common/xlate.yaml
new file mode 100644
index 0000000000000..bd4aa7e0171aa
--- /dev/null
+++ b/test/libelf/tset/common/xlate.yaml
@@ -0,0 +1,23 @@
+%YAML 1.1
+# $Id: xlate.yaml 2053 2011-10-26 11:50:18Z jkoshy $
+---
+ehdr: !Ehdr
+ e_ident: !Ident # e_ident[] members
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
+ ei_osabi: ELFOSABI_FREEBSD
+ ei_abiversion: 1
+ # other members
+ e_type: ET_REL
+ e_machine: 0x42
+ e_version: EV_CURRENT
+ e_entry: 0xF0F0F0F0
+ e_phoff: 0x0E0E0E0E
+ e_shoff: 0xD0D0D0D0
+ e_flags: [64, 8, 2, 1]
+ e_ehsize: 0x0A0A
+ e_phentsize: 0xB0B0
+ e_phnum: 0x0C0C
+ e_shentsize: 0xD0D0
+ e_shnum: 0x0E0E
+ e_shstrndx: 0xF0F0
diff --git a/test/libelf/tset/common/xlate_template.c b/test/libelf/tset/common/xlate_template.c
new file mode 100644
index 0000000000000..84bdb4c1b97ab
--- /dev/null
+++ b/test/libelf/tset/common/xlate_template.c
@@ -0,0 +1,1825 @@
+/*-
+ * Copyright (c) 2006,2010-2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: xlate_template.c 2586 2012-09-15 14:32:47Z jkoshy $
+ */
+
+/*
+ * Boilerplate for testing the *_xlate() functions.
+ *
+ * Usage:
+ *
+ * #define TS_XLATESZ 32 (or 64)
+ * #include "xlate_template.c"
+ */
+
+#include <sys/param.h>
+#include <sys/cdefs.h>
+
+#define __XCONCAT(x,y) __CONCAT(x,y)
+#ifndef __XSTRING
+#define __XSTRING(x) __STRING(x)
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define TS_XLATETOF __XCONCAT(elf,__XCONCAT(TS_XLATESZ,_xlatetof))
+#define TS_XLATETOM __XCONCAT(elf,__XCONCAT(TS_XLATESZ,_xlatetom))
+
+#define BYTE_VAL 0xFF
+#define BYTE_SEQ_LSB 0xFF,
+#define BYTE_SEQ_MSB 0xFF,
+
+#define HALF_VAL 0xFEDC
+#define HALF_SEQ_LSB 0xDC,0xFE,
+#define HALF_SEQ_MSB 0xFE,0xDC,
+
+#define WORD_VAL 0xFEDCBA98UL
+#define WORD_SEQ_LSB 0x98,0xBA,0xDC,0xFE,
+#define WORD_SEQ_MSB 0xFE,0xDC,0xBA,0x98,
+
+#define QUAD_VAL 0xFEDCBA9876543210ULL
+#define QUAD_SEQ_LSB 0x10,0x32,0x54,0x76,\
+ 0x98,0xBA,0xDC,0xFE,
+#define QUAD_SEQ_MSB 0xFE,0xDC,0xBA,0x98,\
+ 0x76,0x54,0x32,0x10,
+
+#define IDENT_BYTES 46,33,46,64,46,35,46,36,46,37,46,94,46,38,46,42
+#define IDENT_VAL { IDENT_BYTES }
+#define IDENT_SEQ_LSB IDENT_BYTES,
+#define IDENT_SEQ_MSB IDENT_BYTES,
+
+
+#define TYPEDEFNAME(E,N) __XCONCAT(__XCONCAT(td_, \
+ __XCONCAT(E,TS_XLATESZ)), __XCONCAT(_,N))
+#define TYPEDEFINITION(E,N) __XCONCAT(ELF_TYPE_E,__XCONCAT(TS_XLATESZ, \
+ __XCONCAT(_, N)))
+#define CHKFNNAME(N) __XCONCAT(__XCONCAT(td_chk_,TS_XLATESZ), \
+ __XCONCAT(_,N))
+#define MEMSIZENAME(N) __XCONCAT(N,__XCONCAT(TS_XLATESZ,_SIZE))
+#define MEMSTRUCTNAME(N) __XCONCAT(N,__XCONCAT(TS_XLATESZ,_mem))
+
+/*
+ * Definitions of 32 bit ELF file structures.
+ */
+
+#define ELF_TYPE_E32_CAP() \
+ MEMBER(c_tag, WORD) \
+ MEMBER(c_un.c_val, WORD)
+
+#define ELF_TYPE_E32_DYN() \
+ MEMBER(d_tag, WORD) \
+ MEMBER(d_un.d_val, WORD)
+
+#define ELF_TYPE_E32_EHDR() \
+ MEMBER(e_ident, IDENT) \
+ MEMBER(e_type, HALF) \
+ MEMBER(e_machine, HALF) \
+ MEMBER(e_version, WORD) \
+ MEMBER(e_entry, WORD) \
+ MEMBER(e_phoff, WORD) \
+ MEMBER(e_shoff, WORD) \
+ MEMBER(e_flags, WORD) \
+ MEMBER(e_ehsize, HALF) \
+ MEMBER(e_phentsize, HALF) \
+ MEMBER(e_phnum, HALF) \
+ MEMBER(e_shentsize, HALF) \
+ MEMBER(e_shnum, HALF) \
+ MEMBER(e_shstrndx, HALF)
+
+#define ELF_TYPE_E32_MOVE() \
+ MEMBER(m_value, QUAD) \
+ MEMBER(m_info, WORD) \
+ MEMBER(m_poffset, WORD) \
+ MEMBER(m_repeat, HALF) \
+ MEMBER(m_stride, HALF)
+
+#define ELF_TYPE_E32_PHDR() \
+ MEMBER(p_type, WORD) \
+ MEMBER(p_offset, WORD) \
+ MEMBER(p_vaddr, WORD) \
+ MEMBER(p_paddr, WORD) \
+ MEMBER(p_filesz, WORD) \
+ MEMBER(p_memsz, WORD) \
+ MEMBER(p_flags, WORD) \
+ MEMBER(p_align, WORD)
+
+#define ELF_TYPE_E32_REL() \
+ MEMBER(r_offset, WORD) \
+ MEMBER(r_info, WORD)
+
+#define ELF_TYPE_E32_RELA() \
+ MEMBER(r_offset, WORD) \
+ MEMBER(r_info, WORD) \
+ MEMBER(r_addend, WORD)
+
+#define ELF_TYPE_E32_SHDR() \
+ MEMBER(sh_name, WORD) \
+ MEMBER(sh_type, WORD) \
+ MEMBER(sh_flags, WORD) \
+ MEMBER(sh_addr, WORD) \
+ MEMBER(sh_offset, WORD) \
+ MEMBER(sh_size, WORD) \
+ MEMBER(sh_link, WORD) \
+ MEMBER(sh_info, WORD) \
+ MEMBER(sh_addralign, WORD) \
+ MEMBER(sh_entsize, WORD)
+
+#define ELF_TYPE_E32_SYM() \
+ MEMBER(st_name, WORD) \
+ MEMBER(st_value, WORD) \
+ MEMBER(st_size, WORD) \
+ MEMBER(st_info, BYTE) \
+ MEMBER(st_other, BYTE) \
+ MEMBER(st_shndx, HALF)
+
+#define ELF_TYPE_E32_SYMINFO() \
+ MEMBER(si_boundto, HALF) \
+ MEMBER(si_flags, HALF)
+
+/*
+ * Definitions of 64 bit ELF file structures.
+ */
+
+#define ELF_TYPE_E64_CAP() \
+ MEMBER(c_tag, QUAD) \
+ MEMBER(c_un.c_val, QUAD)
+
+#define ELF_TYPE_E64_DYN() \
+ MEMBER(d_tag, QUAD) \
+ MEMBER(d_un.d_val, QUAD)
+
+#define ELF_TYPE_E64_EHDR() \
+ MEMBER(e_ident, IDENT) \
+ MEMBER(e_type, HALF) \
+ MEMBER(e_machine, HALF) \
+ MEMBER(e_version, WORD) \
+ MEMBER(e_entry, QUAD) \
+ MEMBER(e_phoff, QUAD) \
+ MEMBER(e_shoff, QUAD) \
+ MEMBER(e_flags, WORD) \
+ MEMBER(e_ehsize, HALF) \
+ MEMBER(e_phentsize, HALF) \
+ MEMBER(e_phnum, HALF) \
+ MEMBER(e_shentsize, HALF) \
+ MEMBER(e_shnum, HALF) \
+ MEMBER(e_shstrndx, HALF)
+
+#define ELF_TYPE_E64_MOVE() \
+ MEMBER(m_value, QUAD) \
+ MEMBER(m_info, QUAD) \
+ MEMBER(m_poffset, QUAD) \
+ MEMBER(m_repeat, HALF) \
+ MEMBER(m_stride, HALF)
+
+#define ELF_TYPE_E64_PHDR() \
+ MEMBER(p_type, WORD) \
+ MEMBER(p_flags, WORD) \
+ MEMBER(p_offset, QUAD) \
+ MEMBER(p_vaddr, QUAD) \
+ MEMBER(p_paddr, QUAD) \
+ MEMBER(p_filesz, QUAD) \
+ MEMBER(p_memsz, QUAD) \
+ MEMBER(p_align, QUAD)
+
+#define ELF_TYPE_E64_REL() \
+ MEMBER(r_offset, QUAD) \
+ MEMBER(r_info, QUAD)
+
+#define ELF_TYPE_E64_RELA() \
+ MEMBER(r_offset, QUAD) \
+ MEMBER(r_info, QUAD) \
+ MEMBER(r_addend, QUAD)
+
+#define ELF_TYPE_E64_SHDR() \
+ MEMBER(sh_name, WORD) \
+ MEMBER(sh_type, WORD) \
+ MEMBER(sh_flags, QUAD) \
+ MEMBER(sh_addr, QUAD) \
+ MEMBER(sh_offset, QUAD) \
+ MEMBER(sh_size, QUAD) \
+ MEMBER(sh_link, WORD) \
+ MEMBER(sh_info, WORD) \
+ MEMBER(sh_addralign, QUAD) \
+ MEMBER(sh_entsize, QUAD)
+
+#define ELF_TYPE_E64_SYM() \
+ MEMBER(st_name, WORD) \
+ MEMBER(st_info, BYTE) \
+ MEMBER(st_other, BYTE) \
+ MEMBER(st_shndx, HALF) \
+ MEMBER(st_value, QUAD) \
+ MEMBER(st_size, QUAD) \
+
+#define ELF_TYPE_E64_SYMINFO() \
+ MEMBER(si_boundto, HALF) \
+ MEMBER(si_flags, HALF)
+
+static unsigned char TYPEDEFNAME(L,CAP)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_LSB
+ TYPEDEFINITION(L,CAP)()
+};
+static unsigned char TYPEDEFNAME(M,CAP)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_MSB
+ TYPEDEFINITION(M,CAP)()
+};
+
+static unsigned char TYPEDEFNAME(L,DYN)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_LSB
+ TYPEDEFINITION(L,DYN)()
+};
+static unsigned char TYPEDEFNAME(M,DYN)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_MSB
+ TYPEDEFINITION(M,DYN)()
+};
+
+static unsigned char TYPEDEFNAME(L,EHDR)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_LSB
+ TYPEDEFINITION(L,EHDR)()
+};
+static unsigned char TYPEDEFNAME(M,EHDR)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_MSB
+ TYPEDEFINITION(M,EHDR)()
+};
+
+static unsigned char TYPEDEFNAME(L,HALF)[] = {
+ HALF_SEQ_LSB
+};
+static unsigned char TYPEDEFNAME(M,HALF)[] = {
+ HALF_SEQ_MSB
+};
+
+static unsigned char TYPEDEFNAME(L,MOVE)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_LSB
+ TYPEDEFINITION(L,MOVE)()
+};
+static unsigned char TYPEDEFNAME(M,MOVE)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_MSB
+ TYPEDEFINITION(M,MOVE)()
+};
+
+static unsigned char TYPEDEFNAME(L,PHDR)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_LSB
+ TYPEDEFINITION(L,PHDR)()
+};
+static unsigned char TYPEDEFNAME(M,PHDR)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_MSB
+ TYPEDEFINITION(M,PHDR)()
+};
+
+static unsigned char TYPEDEFNAME(L,REL)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_LSB
+ TYPEDEFINITION(L,REL)()
+};
+static unsigned char TYPEDEFNAME(M,REL)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_MSB
+ TYPEDEFINITION(M,REL)()
+};
+
+static unsigned char TYPEDEFNAME(L,RELA)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_LSB
+ TYPEDEFINITION(L,RELA)()
+};
+static unsigned char TYPEDEFNAME(M,RELA)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_MSB
+ TYPEDEFINITION(M,RELA)()
+};
+
+static unsigned char TYPEDEFNAME(L,SHDR)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_LSB
+ TYPEDEFINITION(L,SHDR)()
+};
+static unsigned char TYPEDEFNAME(M,SHDR)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_MSB
+ TYPEDEFINITION(M,SHDR)()
+};
+
+static unsigned char TYPEDEFNAME(L,SYM)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_LSB
+ TYPEDEFINITION(L,SYM)()
+};
+static unsigned char TYPEDEFNAME(M,SYM)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_MSB
+ TYPEDEFINITION(M,SYM)()
+};
+
+static unsigned char TYPEDEFNAME(L,SYMINFO)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_LSB
+ TYPEDEFINITION(L,SYMINFO)()
+};
+static unsigned char TYPEDEFNAME(M,SYMINFO)[] = {
+#undef MEMBER
+#define MEMBER(N,K) K##_SEQ_MSB
+ TYPEDEFINITION(M,SYMINFO)()
+};
+
+static unsigned char TYPEDEFNAME(L,QUAD)[] = {
+ QUAD_SEQ_LSB
+};
+
+static unsigned char TYPEDEFNAME(M,QUAD)[] = {
+ QUAD_SEQ_MSB
+};
+
+static unsigned char TYPEDEFNAME(L,WORD)[] = {
+ WORD_SEQ_LSB
+};
+static unsigned char TYPEDEFNAME(M,WORD)[] = {
+ WORD_SEQ_MSB
+};
+
+#if TS_XLATESZ == 32
+/*
+ * 32 bit reference structures.
+ */
+
+#define td_L32_ADDR td_L32_WORD
+#define td_M32_ADDR td_M32_WORD
+#define td_L32_SWORD td_L32_WORD
+#define td_M32_SWORD td_M32_WORD
+#define td_L32_OFF td_L32_WORD
+#define td_M32_OFF td_M32_WORD
+
+static Elf32_Addr MEMSTRUCTNAME(ADDR) = WORD_VAL;
+#define ADDR32_SIZE sizeof(Elf32_Addr)
+
+static Elf32_Cap MEMSTRUCTNAME(CAP) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E32_CAP()
+};
+#define CAP32_SIZE sizeof(Elf32_Cap)
+
+static Elf32_Dyn MEMSTRUCTNAME(DYN) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E32_DYN()
+};
+#define DYN32_SIZE sizeof(Elf32_Dyn)
+
+static Elf32_Ehdr MEMSTRUCTNAME(EHDR) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E32_EHDR()
+};
+#define EHDR32_SIZE sizeof(Elf32_Ehdr)
+
+static Elf32_Half MEMSTRUCTNAME(HALF) = HALF_VAL;
+#define HALF32_SIZE sizeof(Elf32_Half)
+
+static Elf32_Move MEMSTRUCTNAME(MOVE) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E32_MOVE()
+};
+#define MOVE32_SIZE sizeof(Elf32_Move)
+
+static Elf32_Off MEMSTRUCTNAME(OFF) = WORD_VAL;
+#define OFF32_SIZE sizeof(Elf32_Off)
+
+static Elf32_Phdr MEMSTRUCTNAME(PHDR) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E32_PHDR()
+};
+#define PHDR32_SIZE sizeof(Elf32_Phdr)
+
+static Elf32_Rel MEMSTRUCTNAME(REL) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E32_REL()
+};
+#define REL32_SIZE sizeof(Elf32_Rel)
+
+static Elf32_Rela MEMSTRUCTNAME(RELA) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E32_RELA()
+};
+#define RELA32_SIZE sizeof(Elf32_Rela)
+
+static Elf32_Shdr MEMSTRUCTNAME(SHDR) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E32_SHDR()
+};
+#define SHDR32_SIZE sizeof(Elf32_Shdr)
+
+static Elf32_Sword MEMSTRUCTNAME(SWORD) = WORD_VAL;
+#define SWORD32_SIZE sizeof(Elf32_Sword)
+
+static Elf32_Sym MEMSTRUCTNAME(SYM) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E32_SYM()
+};
+#define SYM32_SIZE sizeof(Elf32_Sym)
+
+static Elf32_Syminfo MEMSTRUCTNAME(SYMINFO) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E32_SYMINFO()
+};
+#define SYMINFO32_SIZE sizeof(Elf32_Syminfo)
+
+static Elf32_Word MEMSTRUCTNAME(WORD) = WORD_VAL;
+#define WORD32_SIZE sizeof(Elf32_Word)
+
+#else
+/*
+ * 64 bit reference structures.
+ */
+
+#define td_L64_ADDR td_L64_QUAD
+#define td_M64_ADDR td_M64_QUAD
+#define td_L64_OFF td_L64_QUAD
+#define td_M64_OFF td_M64_QUAD
+#define td_L64_SWORD td_L64_WORD
+#define td_M64_SWORD td_M64_WORD
+#define td_L64_SXWORD td_L64_QUAD
+#define td_M64_SXWORD td_M64_QUAD
+#define td_L64_XWORD td_L64_QUAD
+#define td_M64_XWORD td_M64_QUAD
+
+static Elf64_Addr MEMSTRUCTNAME(ADDR) = QUAD_VAL;
+#define ADDR64_SIZE sizeof(Elf64_Addr)
+
+static Elf64_Cap MEMSTRUCTNAME(CAP) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E64_CAP()
+};
+#define CAP64_SIZE sizeof(Elf64_Cap)
+
+static Elf64_Dyn MEMSTRUCTNAME(DYN) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E64_DYN()
+};
+#define DYN64_SIZE sizeof(Elf64_Dyn)
+
+static Elf64_Ehdr MEMSTRUCTNAME(EHDR) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E64_EHDR()
+};
+#define EHDR64_SIZE sizeof(Elf64_Ehdr)
+
+static Elf64_Half MEMSTRUCTNAME(HALF) = HALF_VAL;
+#define HALF64_SIZE sizeof(Elf64_Half)
+
+static Elf64_Move MEMSTRUCTNAME(MOVE) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E64_MOVE()
+};
+#define MOVE64_SIZE sizeof(Elf64_Move)
+
+static Elf64_Phdr MEMSTRUCTNAME(PHDR) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E64_PHDR()
+};
+#define PHDR64_SIZE sizeof(Elf64_Phdr)
+
+static Elf64_Off MEMSTRUCTNAME(OFF) = QUAD_VAL;
+#define OFF64_SIZE sizeof(Elf64_Off)
+
+static Elf64_Rel MEMSTRUCTNAME(REL) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E64_REL()
+};
+#define REL64_SIZE sizeof(Elf64_Rel)
+
+static Elf64_Rela MEMSTRUCTNAME(RELA) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E64_RELA()
+};
+#define RELA64_SIZE sizeof(Elf64_Rela)
+
+static Elf64_Shdr MEMSTRUCTNAME(SHDR) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E64_SHDR()
+};
+#define SHDR64_SIZE sizeof(Elf64_Shdr)
+
+static Elf64_Sword MEMSTRUCTNAME(SWORD) = WORD_VAL;
+#define SWORD64_SIZE sizeof(Elf64_Sword)
+
+static Elf64_Sxword MEMSTRUCTNAME(SXWORD) = QUAD_VAL;
+#define SXWORD64_SIZE sizeof(Elf64_Sxword)
+
+static Elf64_Sym MEMSTRUCTNAME(SYM) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E64_SYM()
+};
+#define SYM64_SIZE sizeof(Elf64_Sym)
+
+static Elf64_Syminfo MEMSTRUCTNAME(SYMINFO) = {
+#undef MEMBER
+#define MEMBER(N,K) .N = K##_VAL ,
+ ELF_TYPE_E64_SYMINFO()
+};
+#define SYMINFO64_SIZE sizeof(Elf64_Syminfo)
+
+static Elf64_Word MEMSTRUCTNAME(WORD) = WORD_VAL;
+#define WORD64_SIZE sizeof(Elf64_Word)
+
+static Elf64_Xword MEMSTRUCTNAME(XWORD) = QUAD_VAL;
+#define XWORD64_SIZE sizeof(Elf64_Xword)
+
+#endif /* TS_XLATESZ == 32 */
+
+
+#ifndef _TESTDATA_STRUCT_
+#define _TESTDATA_STRUCT_ 1
+struct testdata {
+ char *tsd_name;
+ Elf_Type tsd_type;
+ void *tsd_mem;
+ size_t tsd_fsz;
+ size_t tsd_msz;
+ const unsigned char *tsd_lsb;
+ const unsigned char *tsd_msb;
+};
+#endif /*_TESTDATA_STRUCT_*/
+
+#define TESTDATASET __XCONCAT(tests,TS_XLATESZ)
+static struct testdata TESTDATASET [] = {
+#undef DEFINE_TEST_DATA
+#define DEFINE_TEST_DATA(N) { \
+ .tsd_name = #N, \
+ .tsd_type = ELF_T_##N, \
+ .tsd_fsz = sizeof(TYPEDEFNAME(L,N)), \
+ .tsd_msz = MEMSIZENAME(N), \
+ .tsd_mem = (void *) &MEMSTRUCTNAME(N), \
+ .tsd_lsb = TYPEDEFNAME(L,N), \
+ .tsd_msb = TYPEDEFNAME(M,N), \
+ }
+#if TS_XLATESZ == 32
+ DEFINE_TEST_DATA(ADDR),
+ DEFINE_TEST_DATA(CAP),
+ DEFINE_TEST_DATA(DYN),
+ DEFINE_TEST_DATA(EHDR),
+ DEFINE_TEST_DATA(HALF),
+ DEFINE_TEST_DATA(MOVE),
+ DEFINE_TEST_DATA(OFF),
+ DEFINE_TEST_DATA(PHDR),
+ DEFINE_TEST_DATA(REL),
+ DEFINE_TEST_DATA(RELA),
+ DEFINE_TEST_DATA(SHDR),
+ DEFINE_TEST_DATA(SWORD),
+ DEFINE_TEST_DATA(SYM),
+ DEFINE_TEST_DATA(SYMINFO),
+ DEFINE_TEST_DATA(WORD),
+#else
+ DEFINE_TEST_DATA(ADDR),
+ DEFINE_TEST_DATA(CAP),
+ DEFINE_TEST_DATA(DYN),
+ DEFINE_TEST_DATA(EHDR),
+ DEFINE_TEST_DATA(HALF),
+ DEFINE_TEST_DATA(MOVE),
+ DEFINE_TEST_DATA(OFF),
+ DEFINE_TEST_DATA(PHDR),
+ DEFINE_TEST_DATA(REL),
+ DEFINE_TEST_DATA(RELA),
+ DEFINE_TEST_DATA(SHDR),
+ DEFINE_TEST_DATA(SWORD),
+ DEFINE_TEST_DATA(SXWORD),
+ DEFINE_TEST_DATA(SYM),
+ DEFINE_TEST_DATA(SYMINFO),
+ DEFINE_TEST_DATA(WORD),
+ DEFINE_TEST_DATA(XWORD),
+#endif /* TS_XLATESZ == 32 */
+ { .tsd_name = NULL }
+};
+
+
+#define NCOPIES 3
+#define NOFFSET 8 /* check every alignment in a quad word */
+
+#ifndef NO_TESTCASE_FUNCTIONS
+
+static int
+check_xlate(Elf_Data *xlator(Elf_Data *d, const Elf_Data *s, unsigned int enc),
+ int ed, Elf_Data *dst, Elf_Data *src, struct testdata *td, int ncopies)
+{
+ Elf_Data *dstret;
+ size_t msz;
+
+ msz = td->tsd_msz;
+
+ /* Invoke translator */
+ if ((dstret = xlator(dst, src, ed)) != dst) {
+ tet_printf("fail: \"%s\" " __XSTRING(TC_XLATETOM)
+ ": %s", td->tsd_name, elf_errmsg(-1));
+ tet_result(TET_FAIL);
+ return (0);
+ }
+
+ /* Check return parameters. */
+ if (dst->d_type != td->tsd_type || dst->d_size != msz*ncopies) {
+ tet_printf("fail: \"%s\" type(ret=%d,expected=%d) "
+ "size (ret=%d,expected=%d).", td->tsd_name,
+ dst->d_type, td->tsd_type, dst->d_size, msz*ncopies);
+ tet_result(TET_FAIL);
+ return (0);
+ }
+
+ return (1);
+}
+
+/*
+ * Check byte conversions:
+ */
+
+void
+__XCONCAT(tcXlate_tpByte,TS_XLATESZ)(void)
+{
+ Elf_Data dst, src;
+ int i, offset, sz;
+ char *filebuf, *membuf, *t, *ref;
+
+ ref = TYPEDEFNAME(L,QUAD);
+ sz = sizeof(TYPEDEFNAME(L,QUAD));
+
+ if ((membuf = malloc(sz*NCOPIES)) == NULL ||
+ (filebuf = malloc(sz*NCOPIES+NOFFSET)) == NULL) {
+ if (membuf)
+ free(membuf);
+ tet_infoline("unresolved: malloc() failed.");
+ tet_result(TET_UNRESOLVED);
+ return;
+ }
+
+ /*
+ * Check memory to file conversions.
+ */
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++)
+ t = memcpy(t, ref, sz) + sz;
+
+ src.d_buf = membuf;
+ src.d_size = sz*NCOPIES;
+ src.d_type = ELF_T_BYTE;
+ src.d_version = EV_CURRENT;
+
+ tet_infoline("assertion: Byte TOF() succeeds.");
+
+ for (offset = 0; offset < NOFFSET; offset++) {
+ /*
+ * LSB
+ */
+ dst.d_buf = filebuf + offset;
+ dst.d_size = sz*NCOPIES;
+ dst.d_version = EV_CURRENT;
+
+ if (TS_XLATETOF(&dst,&src,ELFDATA2LSB) != &dst ||
+ dst.d_size != sz*NCOPIES) {
+ tet_infoline("fail: LSB TOF() conversion.");
+ tet_result(TET_FAIL);
+ goto done;
+ }
+
+ if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) {
+ tet_infoline("fail: LSB TOF() memcmp().");
+ tet_result(TET_FAIL);
+ goto done;
+ }
+
+ /*
+ * MSB
+ */
+ dst.d_buf = filebuf + offset;
+ dst.d_size = sz*NCOPIES;
+ dst.d_version = EV_CURRENT;
+
+ if (TS_XLATETOF(&dst,&src,ELFDATA2MSB) != &dst ||
+ dst.d_size != sz*NCOPIES) {
+ tet_infoline("fail: MSB TOF() conversion.");
+ tet_result(TET_FAIL);
+ goto done;
+ }
+
+ if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) {
+ tet_infoline("fail: MSB TOF() memcmp().");
+ tet_result(TET_FAIL);
+ goto done;
+ }
+ }
+
+ /*
+ * Check file to memory conversions.
+ */
+
+ tet_infoline("assertion: Byte TOM() succeeds.");
+
+ ref = TYPEDEFNAME(M,QUAD);
+ sz = sizeof(TYPEDEFNAME(M,QUAD));
+
+ for (offset = 0; offset < NOFFSET; offset++) {
+
+ src.d_buf = t = filebuf + offset;
+ for (i = 0; i < NCOPIES; i++)
+ t = memcpy(t,ref,sz);
+
+ src.d_size = sz*NCOPIES;
+ src.d_type = ELF_T_BYTE;
+ src.d_version = EV_CURRENT;
+
+ /*
+ * LSB
+ */
+ dst.d_buf = membuf;
+ dst.d_size = sz*NCOPIES;
+ dst.d_version = EV_CURRENT;
+
+ if (TS_XLATETOM(&dst,&src,ELFDATA2LSB) != &dst ||
+ dst.d_size != sz * NCOPIES) {
+ tet_infoline("fail: LSB TOM() conversion.");
+ tet_result(TET_FAIL);
+ goto done;
+ }
+
+ if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) {
+ tet_infoline("fail: LSB TOM() memcmp().");
+ tet_result(TET_FAIL);
+ goto done;
+ }
+
+ /*
+ * MSB
+ */
+ dst.d_buf = membuf;
+ dst.d_size = sz*NCOPIES;
+ dst.d_version = EV_CURRENT;
+
+ if (TS_XLATETOM(&dst,&src,ELFDATA2MSB) != &dst ||
+ dst.d_size != sz * NCOPIES) {
+ tet_infoline("fail: MSB TOM() conversion.");
+ tet_result(TET_FAIL);
+ goto done;
+ }
+
+ if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) {
+ tet_infoline("fail: MSB TOM() memcmp().");
+ tet_result(TET_FAIL);
+ goto done;
+ }
+ }
+
+ tet_result(TET_PASS);
+
+ done:
+ if (membuf)
+ free(membuf);
+ if (filebuf)
+ free(filebuf);
+}
+
+/*
+ * Check a byte conversion on a shared buffer.
+ */
+
+void
+__XCONCAT(tcXlate_tpByteShared,TS_XLATESZ)(void)
+{
+ int i;
+ size_t sz;
+ Elf_Data dst, src;
+ char *membuf, *t, *ref;
+
+#define PREPARE_SHARED(T,SZ) do { \
+ src.d_buf = dst.d_buf = membuf; \
+ src.d_size = dst.d_size = (SZ) * NCOPIES; \
+ src.d_type = dst.d_type = (T); \
+ src.d_version = dst.d_version = EV_CURRENT; \
+ } while (0)
+
+#define VERIFY(R,SZ) do { \
+ t = dst.d_buf; \
+ for (i = 0; i < NCOPIES; i++, t += (SZ)) \
+ if (memcmp((R), t, (SZ))) { \
+ tet_infoline("fail: LSB TOF() " \
+ "memcmp()."); \
+ tet_result(TET_FAIL); \
+ goto done; \
+ } \
+ } while (0)
+
+ membuf = NULL;
+ ref = TYPEDEFNAME(L,QUAD);
+ sz = sizeof(TYPEDEFNAME(L,QUAD));
+
+ if ((membuf = malloc(sz * NCOPIES)) == NULL) {
+ tet_infoline("unresolved: malloc() failed.");
+ tet_result(TET_UNRESOLVED);
+ return;
+ }
+
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++)
+ t = memcpy(t, ref, sz) + sz;
+
+ tet_infoline("assertion: byte TOF() on a shared dst/src arena "
+ "succeeds.");
+
+ PREPARE_SHARED(ELF_T_BYTE, sz);
+ if (TS_XLATETOF(&dst, &src, ELFDATA2LSB) != &dst ||
+ dst.d_size != sz * NCOPIES ||
+ dst.d_buf != src.d_buf) {
+ tet_printf("fail: LSB TOF() conversion: %s.",
+ elf_errmsg(-1));
+ tet_result(TET_FAIL);
+ goto done;
+ }
+ VERIFY(ref,sz);
+
+ PREPARE_SHARED(ELF_T_BYTE, sz);
+ if (TS_XLATETOF(&dst, &src, ELFDATA2MSB) != &dst ||
+ dst.d_size != sz * NCOPIES ||
+ dst.d_buf != src.d_buf) {
+ tet_printf("fail: MSB TOF() conversion: %s.",
+ elf_errmsg(-1));
+ tet_result(TET_FAIL);
+ goto done;
+ }
+ VERIFY(ref,sz);
+
+ tet_infoline("assertion: byte TOM() on a shared dst/src arena "
+ "succeeds.");
+
+ PREPARE_SHARED(ELF_T_BYTE, sz);
+ if (TS_XLATETOM(&dst, &src, ELFDATA2LSB) != &dst ||
+ dst.d_size != sz * NCOPIES ||
+ dst.d_buf != src.d_buf) {
+ tet_printf("fail: LSB TOM() conversion: %s.",
+ elf_errmsg(-1));
+ tet_result(TET_FAIL);
+ goto done;
+ }
+ VERIFY(ref,sz);
+
+ PREPARE_SHARED(ELF_T_BYTE, sz);
+ if (TS_XLATETOM(&dst, &src, ELFDATA2MSB) != &dst ||
+ dst.d_size != sz * NCOPIES ||
+ dst.d_buf != src.d_buf) {
+ tet_printf("fail: MSB TOM() conversion: %s.",
+ elf_errmsg(-1));
+ tet_result(TET_FAIL);
+ goto done;
+ }
+ VERIFY(ref,sz);
+
+ tet_result(TET_PASS);
+
+ done:
+ free(membuf);
+}
+
+/*
+ * Check non-byte conversions from file representations to memory.
+ */
+void
+__XCONCAT(tcXlate_tpToM,TS_XLATESZ)(void)
+{
+ Elf_Data dst, src;
+ struct testdata *td;
+ size_t fsz, msz;
+ int i, offset;
+ char *srcbuf, *membuf, *t;
+
+ srcbuf = NULL; /* file data (bytes) */
+ membuf = NULL; /* memory data (struct) */
+
+ /* Loop over all types */
+ for (td = TESTDATASET; td->tsd_name; td++) {
+
+ fsz = __XCONCAT(__XCONCAT(elf,TS_XLATESZ),_fsize)(td->tsd_type,
+ 1, EV_CURRENT);
+
+ msz = td->tsd_msz;
+
+ if (msz == 0 ||
+ fsz != td->tsd_fsz) {
+ tet_printf("? %s: msz=%d fsz=%d td->fsz=%d.",
+ td->tsd_name, msz, fsz, td->tsd_fsz);
+ }
+
+ assert(fsz == td->tsd_fsz);
+
+ /*
+ * allocate space for NCOPIES of data + offset for file data and
+ * NCOPIES of memory data.
+ */
+ if ((srcbuf = malloc(NCOPIES*fsz+NOFFSET)) == NULL ||
+ ((membuf = malloc(NCOPIES*msz))) == NULL) {
+ if (srcbuf)
+ free(srcbuf);
+ tet_infoline("unresolved: malloc() failed.");
+ tet_result(TET_UNRESOLVED);
+ return;
+ }
+
+
+ tet_printf("assertion: "__XSTRING(TS_XLATETOM)"(%s) succeeds.",
+ td->tsd_name);
+
+ for (offset = 0; offset < NOFFSET; offset++) {
+
+ src.d_buf = t = srcbuf + offset;
+ src.d_size = fsz * NCOPIES;
+ src.d_type = td->tsd_type;
+ src.d_version = EV_CURRENT;
+
+ dst.d_buf = membuf;
+ dst.d_size = msz * NCOPIES;
+ dst.d_version = EV_CURRENT;
+
+
+ /*
+ * Check conversion of LSB encoded data.
+ */
+
+ /* copy `NCOPIES*fsz' bytes in `srcbuf+offset' */
+ for (i = 0; i < NCOPIES; i++) {
+ (void) memcpy(t, td->tsd_lsb, fsz);
+ t += fsz;
+ }
+ (void) memset(membuf, 0, NCOPIES*msz);
+
+ if (check_xlate(TS_XLATETOM, ELFDATA2LSB, &dst, &src,
+ td, NCOPIES) == 0)
+ goto done;
+
+ /* compare the retrieved data with the canonical value */
+ t = dst.d_buf;
+ for (i = 0; i < NCOPIES; i++) {
+ if (memcmp(t, td->tsd_mem, msz)) {
+ tet_printf("fail: \"%s\" LSB memory "
+ "compare failed.", td->tsd_name);
+ tet_result(TET_FAIL);
+ goto done;
+ }
+ t += msz;
+ }
+
+ /*
+ * Check conversion of MSB encoded data.
+ */
+
+ t = srcbuf + offset;
+ for (i = 0; i < NCOPIES; i++) {
+ (void) memcpy(t, td->tsd_msb, fsz);
+ t += fsz;
+ }
+ (void) memset(membuf, 0, NCOPIES*msz);
+ if (check_xlate(TS_XLATETOM, ELFDATA2MSB, &dst, &src,
+ td, NCOPIES) == 0)
+ goto done;
+
+ /* compare the retrieved data with the canonical value */
+ t = dst.d_buf;
+ for (i = 0; i < NCOPIES; i++) {
+ if (memcmp(t, td->tsd_mem, msz)) {
+ tet_printf("fail: \"%s\" MSB memory "
+ "compare failed.", td->tsd_name);
+ tet_result(TET_FAIL);
+ goto done;
+ }
+ t += msz;
+ }
+ }
+
+ free(srcbuf); srcbuf = NULL;
+ free(membuf); membuf = NULL;
+ }
+
+ tet_result(TET_PASS);
+
+ done:
+ if (srcbuf)
+ free(srcbuf);
+ if (membuf)
+ free(membuf);
+}
+
+void
+__XCONCAT(tcXlate_tpToMShared,TS_XLATESZ)(void)
+{
+ Elf_Data dst, src;
+ struct testdata *td;
+ size_t fsz, msz;
+ int i, result;
+ char *membuf, *t;
+
+ membuf = NULL;
+
+ for (td = TESTDATASET; td->tsd_name; td++) {
+
+ tet_printf("assertion: in-place "__XSTRING(TS_XLATETOM)"(\"%s\").",
+ td->tsd_name);
+
+ fsz = __XCONCAT(__XCONCAT(elf,TS_XLATESZ),_fsize)(td->tsd_type,
+ 1, EV_CURRENT);
+ msz = td->tsd_msz;
+
+ assert(msz >= fsz);
+
+ if ((membuf = malloc(fsz * NCOPIES)) == NULL) {
+ tet_printf("unresolved: \"%s\" malloc() failed.",
+ td->tsd_name);
+ tet_result(TET_UNRESOLVED);
+ goto done;
+ }
+
+ /*
+ * In-place conversion of LSB data.
+ */
+
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++)
+ t = memcpy(t, td->tsd_lsb, fsz) + fsz;
+
+ PREPARE_SHARED(td->tsd_type, fsz);
+ result = TS_XLATETOM(&dst, &src, ELFDATA2LSB) == &dst;
+
+ if (fsz < msz) {
+ /* conversion should fail with ELF_E_DATA */
+ if (result || elf_errno() != ELF_E_DATA) {
+ tet_printf("fail: \"%s\" LSB TOM() succeeded "
+ "with fsz < msz", td->tsd_name);
+ tet_result(TET_FAIL);
+ goto done;
+ }
+ free(membuf); membuf = NULL;
+ continue;
+ }
+
+ /* conversion should have succeeded. */
+ if (!result) {
+ tet_printf("fail: \"%s\" LSB TOM() failed.",
+ td->tsd_name);
+ tet_result(TET_FAIL);
+ goto done;
+ }
+
+ VERIFY(td->tsd_mem,msz);
+
+ /*
+ * In-place conversion of MSB data.
+ */
+
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++)
+ t = memcpy(t, td->tsd_msb, fsz) + fsz;
+
+ PREPARE_SHARED(td->tsd_type, fsz);
+ result = TS_XLATETOM(&dst, &src, ELFDATA2MSB) == &dst;
+
+ if (fsz < msz) {
+ /* conversion should fail with ELF_E_DATA */
+ if (result || elf_errno() != ELF_E_DATA) {
+ tet_printf("fail: \"%s\" MSB TOM() succeeded "
+ "with fsz < msz", td->tsd_name);
+ tet_result(TET_FAIL);
+ goto done;
+ }
+ free(membuf); membuf = NULL;
+ continue;
+ }
+
+ /* conversion should have succeeded. */
+ if (!result) {
+ tet_printf("fail: \"%s\" MSB TOM() failed.",
+ td->tsd_name);
+ tet_result(TET_FAIL);
+ goto done;
+ }
+
+ VERIFY(td->tsd_mem,msz);
+
+ }
+
+ tet_result(TET_PASS);
+
+ done:
+ if (membuf)
+ free(membuf);
+}
+
+
+/*
+ * Check non-byte conversions from memory to file.
+ */
+void
+__XCONCAT(tcXlate_tpToF,TS_XLATESZ)(void)
+{
+ Elf_Data dst, src;
+ struct testdata *td;
+ size_t fsz, msz;
+ int i, offset;
+ char *filebuf, *membuf, *t;
+
+ filebuf = NULL; /* file data (bytes) */
+ membuf = NULL; /* memory data (struct) */
+
+ /* Loop over all types */
+ for (td = TESTDATASET; td->tsd_name; td++) {
+
+ fsz = __XCONCAT(__XCONCAT(elf,TS_XLATESZ),_fsize)(td->tsd_type,
+ 1, EV_CURRENT);
+
+ msz = td->tsd_msz;
+
+ if (msz == 0 ||
+ fsz != td->tsd_fsz) {
+ tet_printf("? %s: msz=%d fsz=%d td->fsz=%d.",
+ td->tsd_name, msz, fsz, td->tsd_fsz);
+ }
+
+ assert(msz > 0);
+ assert(fsz == td->tsd_fsz);
+
+ /*
+ * allocate space for NCOPIES of data + offset for file data and
+ * NCOPIES of memory data.
+ */
+ if ((filebuf = malloc(NCOPIES*fsz+NOFFSET)) == NULL ||
+ ((membuf = malloc(NCOPIES*msz))) == NULL) {
+ if (filebuf)
+ free(filebuf);
+ tet_infoline("unresolved: malloc() failed.");
+ tet_result(TET_UNRESOLVED);
+ return;
+ }
+
+
+ tet_printf("assertion: "__XSTRING(TS_XLATETOF)"(%s) succeeds.",
+ td->tsd_name);
+
+ for (offset = 0; offset < NOFFSET; offset++) {
+
+ src.d_buf = membuf;
+ src.d_size = msz * NCOPIES;
+ src.d_type = td->tsd_type;
+ src.d_version = EV_CURRENT;
+
+ /*
+ * Check LSB conversion.
+ */
+
+ /* copy `NCOPIES' of canonical memory data to the src buffer */
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++) {
+ (void) memcpy(t, td->tsd_mem, msz);
+ t += msz;
+ }
+ (void) memset(filebuf, 0, NCOPIES*fsz+NOFFSET);
+
+ dst.d_buf = filebuf + offset;
+ dst.d_size = fsz * NCOPIES;
+ dst.d_version = EV_CURRENT;
+
+ if (check_xlate(TS_XLATETOF, ELFDATA2LSB, &dst, &src,
+ td, NCOPIES) == 0)
+ goto done;
+
+ /* compare converted data to canonical form */
+ t = filebuf + offset;
+ for (i = 0; i < NCOPIES; i++) {
+ if (memcmp(t, td->tsd_lsb, fsz)) {
+ tet_printf("fail: \"%s\" LSB memory "
+ "compare.", td->tsd_name);
+ tet_result(TET_FAIL);
+ goto done;
+ }
+ t += fsz;
+ }
+
+ /*
+ * Check MSB conversion.
+ */
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++) {
+ (void) memcpy(t, td->tsd_mem, msz);
+ t += msz;
+ }
+ (void) memset(filebuf, 0, NCOPIES*fsz+NOFFSET);
+
+ dst.d_buf = filebuf + offset;
+ dst.d_size = fsz * NCOPIES;
+ dst.d_version = EV_CURRENT;
+
+ if (check_xlate(TS_XLATETOF, ELFDATA2MSB, &dst, &src,
+ td, NCOPIES) == 0)
+ goto done;
+
+ /* compare converted data to canonical form */
+ t = filebuf + offset;
+ for (i = 0; i < NCOPIES; i++) {
+ if (memcmp(t, td->tsd_msb, fsz)) {
+ tet_printf("fail: \"%s\" MSB memory "
+ "compare.", td->tsd_name);
+ tet_result(TET_FAIL);
+ goto done;
+ }
+ t += fsz;
+ }
+ }
+
+ free(filebuf); filebuf = NULL;
+ free(membuf); membuf = NULL;
+ }
+
+ tet_result(TET_PASS);
+
+ done:
+ if (filebuf)
+ free(filebuf);
+ if (membuf)
+ free(membuf);
+}
+
+void
+__XCONCAT(tcXlate_tpToFShared,TS_XLATESZ)(void)
+{
+ Elf_Data dst, src;
+ struct testdata *td;
+ size_t fsz, msz;
+ int i;
+ char *membuf, *t;
+
+ membuf = NULL;
+
+ for (td = TESTDATASET; td->tsd_name; td++) {
+
+ tet_printf("assertion: in-place "__XSTRING(TS_XLATETOF)"(\"%s\").",
+ td->tsd_name);
+
+ fsz = __XCONCAT(__XCONCAT(elf,TS_XLATESZ),_fsize)(td->tsd_type,
+ 1, EV_CURRENT);
+ msz = td->tsd_msz;
+
+ assert(msz >= fsz);
+
+ if ((membuf = malloc(msz * NCOPIES)) == NULL) {
+ tet_printf("unresolved: \"%s\" malloc() failed.",
+ td->tsd_name);
+ tet_result(TET_UNRESOLVED);
+ goto done;
+ }
+
+ /*
+ * In-place conversion to LSB data.
+ */
+
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++)
+ t = memcpy(t, td->tsd_mem, msz) + msz;
+
+ PREPARE_SHARED(td->tsd_type, msz);
+ if (TS_XLATETOF(&dst, &src, ELFDATA2LSB) != &dst) {
+ tet_printf("fail: \"%s\" LSB TOF() failed: %s.",
+ td->tsd_name, elf_errmsg(-1));
+ tet_result(TET_FAIL);
+ goto done;
+ }
+ VERIFY(td->tsd_lsb,fsz);
+
+ /*
+ * In-place conversion to MSB data.
+ */
+
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++)
+ t = memcpy(t, td->tsd_mem, msz) + msz;
+
+ PREPARE_SHARED(td->tsd_type, msz);
+ if (TS_XLATETOF(&dst, &src, ELFDATA2MSB) != &dst) {
+ tet_printf("fail: \"%s\" MSB TOF() failed: %s.",
+ td->tsd_name, elf_errmsg(-1));
+ tet_result(TET_FAIL);
+ goto done;
+ }
+ VERIFY(td->tsd_msb,fsz);
+
+ }
+
+ tet_result(TET_PASS);
+
+ done:
+ if (membuf)
+ free(membuf);
+}
+
+
+
+/*
+ * Various checks for invalid arguments.
+ */
+
+void
+__XCONCAT(tcArgs_tpNullArgs,TS_XLATESZ)(void)
+{
+ Elf_Data ed;
+ int result;
+
+ tet_infoline("assertion: "__XSTRING(TS_XLATETOF) "/"
+ __XSTRING(TS_XLATETOM) " with NULL arguments fail "
+ "with ELF_E_ARGUMENT.");
+
+ result = TET_PASS;
+
+ if (TS_XLATETOF(NULL,&ed,ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ if (TS_XLATETOF(&ed,NULL,ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ if (TS_XLATETOM(NULL,&ed,ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ if (TS_XLATETOM(&ed,NULL,ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ tet_result(result);
+}
+
+void
+__XCONCAT(tcArgs_tpBadType,TS_XLATESZ)(void)
+{
+ Elf_Data ed, es;
+ int result;
+ char buf[1024];
+
+ tet_infoline("assertion: "__XSTRING(TS_XLATETOF) "/"
+ __XSTRING(TS_XLATETOM) " with an out of range type "
+ "fails with ELF_E_DATA.");
+
+ result = TET_PASS;
+
+ es.d_version = ed.d_version = EV_CURRENT;
+ es.d_buf = ed.d_buf = buf;
+ es.d_size = ed.d_size = sizeof(buf);
+
+ es.d_type = (Elf_Type) -1;
+
+ if (TS_XLATETOF(&ed,&es,ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ if (TS_XLATETOM(&ed,&es,ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ es.d_type = ELF_T_NUM;
+
+ if (TS_XLATETOF(&ed,&es,ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ if (TS_XLATETOM(&ed,&es,ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ tet_result(result);
+}
+
+void
+__XCONCAT(tcArgs_tpBadEncoding,TS_XLATESZ)(void)
+{
+ Elf_Data ed, es;
+ int result;
+
+ tet_infoline("assertion: "__XSTRING(TS_XLATETOF) "/"
+ __XSTRING(TS_XLATETOM) " (*,*,BADENCODING) "
+ "fails with ELF_E_ARGUMENT.");
+
+ result = TET_PASS;
+
+ if (TS_XLATETOF(&ed,&es,ELFDATANONE-1) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+ else if (TS_XLATETOF(&ed,&es,ELFDATA2MSB+1) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ if (TS_XLATETOM(&ed,&es,ELFDATANONE-1) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+ else if (TS_XLATETOM(&ed,&es,ELFDATA2MSB+1) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ tet_result(result);
+}
+
+void
+__XCONCAT(tcArg_tpDstSrcVersionToF,TS_XLATESZ)(void)
+{
+ Elf_Data ed, es;
+ int result;
+ char buf[sizeof(int)];
+
+ tet_infoline("assertion: "__XSTRING(TS_XLATETOF)"() / "
+ __XSTRING(TS_XLATETOM) "() with unequal "
+ "src,dst versions fails with ELF_E_UNIMPL.");
+
+ es.d_buf = ed.d_buf = buf;
+ es.d_type = ELF_T_BYTE;
+ es.d_size = ed.d_size = sizeof(buf);
+ es.d_version = EV_CURRENT;
+ ed.d_version = EV_NONE;
+
+ result = TET_PASS;
+
+ if (TS_XLATETOF(&ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_UNIMPL)
+ result = TET_FAIL;
+
+ if (TS_XLATETOM(&ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_UNIMPL)
+ result = TET_FAIL;
+
+ tet_result(result);
+}
+
+/*
+ * Check for an unimplemented type.
+ */
+void
+__XCONCAT(tcArg_tpUnimplemented,TS_XLATESZ)(void)
+{
+ Elf_Data ed, es;
+ int i, result;
+ char *buf;
+
+ tet_infoline("assertion: "__XSTRING(TS_XLATETOF)"() on "
+ "unimplemented types will with ELF_E_UNIMPL.");
+
+ /*
+ * allocate a buffer that is large enough for any potential
+ * ELF data structure.
+ */
+ if ((buf = malloc(1024)) == NULL) {
+ tet_infoline("unresolved: malloc() failed.");
+ tet_result(TET_UNRESOLVED);
+ return;
+ }
+
+ ed.d_buf = es.d_buf = buf;
+ ed.d_size = es.d_size = 1024;
+ ed.d_version = es.d_version = EV_CURRENT;
+
+ result = TET_PASS;
+
+ for (i = 0; i < ELF_T_NUM; i++) {
+ switch (i) {
+ case ELF_T_MOVEP:
+#if TS_XLATESZ == 32
+ case ELF_T_SXWORD:
+ case ELF_T_XWORD:
+#endif
+ break;
+ default:
+ continue;
+ }
+
+ es.d_type = i;
+
+ if (TS_XLATETOF(&ed,&es,ELFDATA2LSB) != NULL ||
+ elf_errno() != ELF_E_UNIMPL) {
+ tet_printf("fail: TOF/LSB/type=%d.", i);
+ result = TET_FAIL;
+ }
+
+ if (TS_XLATETOF(&ed,&es,ELFDATA2MSB) != NULL ||
+ elf_errno() != ELF_E_UNIMPL) {
+ tet_printf("fail: TOF/MSB/type=%d.", i);
+ result = TET_FAIL;
+ }
+
+ if (TS_XLATETOM(&ed,&es,ELFDATA2LSB) != NULL ||
+ elf_errno() != ELF_E_UNIMPL) {
+ tet_printf("fail: TOM/LSB/type=%d.", i);
+ result = TET_FAIL;
+ }
+
+ if (TS_XLATETOM(&ed,&es,ELFDATA2MSB) != NULL ||
+ elf_errno() != ELF_E_UNIMPL) {
+ tet_printf("fail: TOM/MSB/type=%d.", i);
+ result = TET_FAIL;
+ }
+ }
+
+ tet_result(result);
+ free(buf);
+}
+
+/*
+ * Check for null buffer pointers.
+ */
+void
+__XCONCAT(tcBuffer_tpNullDataPtr,TS_XLATESZ)(void)
+{
+ Elf_Data ed, es;
+ int result;
+ char buf[sizeof(int)];
+
+ tet_infoline("assertion: "__XSTRING(TS_XLATETOF)"() / "
+ __XSTRING(TS_XLATETOM) "() with a null "
+ "src,dst buffer pointer fails with ELF_E_DATA.");
+
+ result = TET_PASS;
+
+ es.d_type = ELF_T_BYTE;
+ es.d_size = ed.d_size = sizeof(buf);
+ es.d_version = EV_CURRENT;
+ ed.d_version = EV_CURRENT;
+
+ es.d_buf = NULL;
+ ed.d_buf = buf;
+ if (TS_XLATETOF(&ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ if (TS_XLATETOM(&ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ es.d_buf = buf;
+ ed.d_buf = NULL;
+ if (TS_XLATETOF(&ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ if (TS_XLATETOM(&ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ tet_result(result);
+}
+
+/*
+ * Misaligned data.
+ */
+
+void
+__XCONCAT(tcBuffer_tpMisaligned,TS_XLATESZ)(void)
+{
+ Elf_Data ed, es;
+ int result;
+ size_t fsz, msz;
+ char *sb, *db;
+ struct testdata *td;
+
+ tet_infoline("assertion: misaligned buffers are rejected with "
+ "ELF_E_DATA.");
+
+ sb = db = NULL;
+ if ((sb = malloc(1024)) == NULL ||
+ (db = malloc(1024)) == NULL) {
+ tet_infoline("unresolved: malloc() failed.");
+ tet_result(TET_UNRESOLVED);
+ if (sb)
+ free(sb);
+ return;
+ }
+
+ result = TET_PASS;
+
+ for (td = TESTDATASET; td->tsd_name; td++) {
+ fsz = td->tsd_fsz;
+ msz = td->tsd_msz;
+
+ es.d_type = td->tsd_type;
+ es.d_version = EV_CURRENT;
+
+ /* Misalign the destination for to-memory xfers */
+ es.d_size = (1024 / fsz) * fsz; /* round down */
+ es.d_buf = sb;
+
+ ed.d_buf = db + 1; /* guaranteed to be misaliged */
+ ed.d_version = EV_CURRENT;
+ ed.d_size = 1024;
+
+ if (TS_XLATETOM(&ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ tet_printf("fail: \"%s\" TOM alignment.",
+ td->tsd_name);
+ result = TET_FAIL;
+ }
+
+ /* Misalign the source for to-file xfers */
+ es.d_buf = sb + 1;
+ es.d_size = (1024/msz) * msz; /* round down */
+ ed.d_buf = db;
+
+ if (TS_XLATETOF(&ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ tet_printf("fail: \"%s\" TOF alignment.",
+ td->tsd_name);
+ result = TET_FAIL;
+ }
+ }
+
+ tet_result(result);
+ free(sb);
+ free(db);
+}
+
+
+/*
+ * Overlapping buffers.
+ */
+void
+__XCONCAT(tcBuffer_tpOverlap,TS_XLATESZ)(void)
+{
+ Elf_Data ed, es;
+ int result;
+ char buf[sizeof(int)];
+
+ tet_infoline("assertion: overlapping buffers are rejected with "
+ "ELF_E_DATA.");
+
+ es.d_buf = buf; ed.d_buf = buf+1;
+ es.d_version = ed.d_version = EV_CURRENT;
+ es.d_size = ed.d_size = sizeof(buf);
+ es.d_type = ELF_T_BYTE;
+
+ result = TET_PASS;
+
+ if (TS_XLATETOF(&ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ tet_infoline("fail: "__XSTRING(TS_XLATETOF));
+ result = TET_FAIL;
+ }
+
+ if (TS_XLATETOM(&ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ tet_infoline("fail: "__XSTRING(TS_XLATETOM));
+ result = TET_FAIL;
+ }
+
+ tet_result(result);
+}
+
+/*
+ * Non-integral number of src elements.
+ */
+void
+__XCONCAT(tcBuffer_tpSrcExtra,TS_XLATESZ)(void)
+{
+ Elf_Data ed, es;
+ int result;
+ size_t fsz, msz;
+ char *sb, *db;
+ struct testdata *td;
+
+ tet_infoline("assertion: mis-sized buffers are rejected with "
+ "ELF_E_DATA.");
+
+ sb = db = NULL;
+ if ((sb = malloc(1024)) == NULL ||
+ (db = malloc(1024)) == NULL) {
+ tet_infoline("unresolved: malloc() failed.");
+ tet_result(TET_UNRESOLVED);
+ if (sb)
+ free(sb);
+ return;
+ }
+
+ result = TET_PASS;
+
+ for (td = TESTDATASET; td->tsd_name; td++) {
+ fsz = td->tsd_fsz;
+ msz = td->tsd_msz;
+
+ es.d_type = td->tsd_type;
+ es.d_version = EV_CURRENT;
+ ed.d_version = EV_CURRENT;
+ ed.d_buf = db;
+ es.d_buf = sb;
+ ed.d_size = 1024;
+
+ /* Pad src bytes with extra bytes for to memor */
+ es.d_size = fsz+1;
+
+ if (TS_XLATETOM(&ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ tet_printf("fail: \"%s\" TOM buffer size.",
+ td->tsd_name);
+ result = TET_FAIL;
+ }
+
+ es.d_size = msz+1;
+ if (TS_XLATETOF(&ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ tet_printf("fail: \"%s\" TOF buffer size.",
+ td->tsd_name);
+ result = TET_FAIL;
+ }
+ }
+
+ tet_result(result);
+ free(sb);
+ free(db);
+}
+
+void
+__XCONCAT(tcBuffer_tpDstTooSmall,TS_XLATESZ)(void)
+{
+ Elf_Data ed, es;
+ int result;
+ struct testdata *td;
+ size_t fsz, msz;
+ char buf[1024];
+
+ result = TET_PASS;
+
+ tet_infoline("assertion: too small destination buffers are rejected "
+ "with ELF_E_DATA.");
+
+ for (td = TESTDATASET; td->tsd_name; td++) {
+ msz = td->tsd_msz;
+ fsz = td->tsd_fsz;
+
+ es.d_type = td->tsd_type;
+ es.d_version = ed.d_version = EV_CURRENT;
+ es.d_buf = ed.d_buf = buf;
+
+ es.d_size = (sizeof(buf) / msz) * msz;
+ ed.d_size = 1; /* too small a size */
+
+ if (TS_XLATETOF(&ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ tet_printf("fail: \"%s\" TOF dst size.",
+ td->tsd_name);
+ result = TET_FAIL;
+ }
+
+ es.d_size = (sizeof(buf) / fsz) * fsz;
+ if (TS_XLATETOM(&ed,&es,ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ tet_printf("fail: \"%s\" TOF dst size.",
+ td->tsd_name);
+ result = TET_FAIL;
+ }
+ }
+
+ tet_result(result);
+}
+
+#endif /* NO_TESTCASE_FUNCTIONS */
diff --git a/test/libelf/tset/common/xlate_template.m4 b/test/libelf/tset/common/xlate_template.m4
new file mode 100644
index 0000000000000..05efc59f21071
--- /dev/null
+++ b/test/libelf/tset/common/xlate_template.m4
@@ -0,0 +1,1436 @@
+/*-
+ * Copyright (c) 2006,2010-2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: xlate_template.m4 2053 2011-10-26 11:50:18Z jkoshy $
+ */
+
+/*
+ * Boilerplate for testing the *_xlate() functions.
+ *
+ * This M4-based macro set attempts to generate test functions for
+ * testing the elf{32,54}_xlateto{f,m}() and gelf_xlateto{f,m}()
+ * functions.
+ *
+ * The following needs to be kept in mind:
+ *
+ * - 32 bit ELF code uses a subset of the primitive types used by
+ * 64 bit code. In particular, the Sxword and Xword types do not
+ * exist in the 32 bit ELF definition.
+ * - Elf type identifiers `FOO' usually map to a C type name `Foo',
+ * except in the case of a few types.
+ * - Elf types `ADDR' and `OFF' use ELF class dependent sizes for initializers.
+ * - Each Elf type needs to be associated with a FreeBSD version where
+ * it first appeared, so that the generated code can be made compilable
+ * on older systems.
+ */
+
+divert(-1)
+
+ifdef(`TPFNNAME',`',`errprint(`Macro TPFNNAME must be defined.')m4exit(1)')
+ifelse(index(TPFNNAME,`32'),-1,`define(`ISELF64',`Y')')
+ifelse(index(TPFNNAME,`64'),-1,`define(`ISELF32',`Y')')
+ifelse(index(TPFNNAME,`gelf'),0,`define(`ISGELF',`Y')')
+
+/*
+ * TO_M_OR_F(M_TEXT,F_TEXT)
+ *
+ * Selectively expand one of `M_TEXT' or `F_TEXT' depending on whether
+ * the function being tested is a *_tom() or *_tof() function.
+ */
+
+define(`TO_M_OR_F',`ifelse(eval(index(TPFNNAME,`tom') > 0),1,`$1',`$2')')
+define(`__N__',TOUPPER(substr(TPFNNAME,regexp(TPFNNAME,`to[fm]'))))
+
+/*
+ * DO(SIZE,TEXT)
+ *
+ * Invoke `TEXT' in an environment that defines `__SZ__' to SIZE.
+ */
+define(`DO',`pushdef(`__SZ__',$1)$2`'popdef(`__SZ__')')
+
+/*
+ * ELF_TYPE_LIST((TYPE, VERSION)...)
+ *
+ * Lists all ELF types for which macro expansion is desired and associates
+ * each such type with its `C Name'.
+ *
+ * Note that the following ELF types with variable sized `file'/memory
+ * representations need to be handled specially and are not part of
+ * this list:
+ * - ELF_T_BYTE
+ * - ELF_T_GNUHASH
+ * - ELF_T_NOTE
+ * - ELF_T_VDEF
+ * - ELF_T_VNEED
+ */
+define(`ELF_COMMON_TYPES',
+ ``ADDR, Addr',
+ `CAP, Cap',
+ `DYN, Dyn',
+ `EHDR, Ehdr',
+ `HALF, Half',
+ `LWORD, Lword',
+ `MOVE, Move',
+ `OFF, Off',
+ `PHDR, Phdr',
+ `REL, Rel',
+ `RELA, Rela',
+ `SHDR, Shdr',
+ `SWORD, Sword',
+ `SYM, Sym',
+ `SYMINFO, Syminfo',
+ `WORD, Word'')
+
+define(`ELF32_TYPES',
+ `ELF_COMMON_TYPES,
+ `_, _'')
+
+define(`ELF64_TYPES',
+ `ELF_COMMON_TYPES,
+ `SXWORD, Sxword',
+ `XWORD, Xword',
+ `_, _'')
+
+/*
+ * Tests that need to be written manually: include those for
+ * types: BYTE, NOTE and perhaps VDEF and VNEED.
+ */
+
+/*
+ * _DOTYPE(TYPE)
+ *
+ * Process one type. This invokes `__F__' with args: 1=TYPE, 2=C-Name and the
+ * the additional arguments specified to `DOELFTYPES' below.
+ */
+define(`_DOTYPE',`
+indir(`__F__',$1,$2,__ARGS__)
+')
+
+/*
+ * _DOELFTYPES: iterate over an ELF type list.
+ */
+define(`_DOELFTYPES',
+ `ifelse($#,1,`',
+ `_DOTYPE($1)
+_DOELFTYPES(shift($@))')')
+
+/*
+ * DOELFTYPES(MACRO,ARGS...)
+ *
+ * Invoke `MACRO'(TYPE,C-NAME,ARGS...) for each type in the ELF type list
+ * for the current size in macro `__SZ__'.
+ */
+define(`DOELFTYPES',
+ `pushdef(`__F__',defn(`$1'))pushdef(`__ARGS__',`shift($@)')dnl
+ifelse(__SZ__,32,`_DOELFTYPES(ELF32_TYPES)',`_DOELFTYPES(ELF64_TYPES)')dnl
+popdef(`__ARGS__')popdef(`__F__')')
+
+/*
+ * ELFTYPEDEFINITION(TYPE,SZ,ENDIANNESS)
+ *
+ * Generate the `C' name of the char[] array holding the `raw' bits
+ * for an ELF type.
+ */
+define(`ELFTYPEDEFINITION',`td_$1_$2_$3')
+
+/*
+ * ELFMEMSTRUCT(TYPE,SZ)
+ *
+ * Generate the name for a `C' struct containing the memory
+ * representation of an ELF type.
+ */
+define(`ELFMEMSTRUCT',`$1_$2_mem')
+
+/*
+ * ELFTESTS(SZ)
+ */
+define(`ELFTESTS',`tests$1')
+
+divert(0)
+
+#define TPBUFSIZE 1024
+
+#define BYTE_VAL 0xFF
+#define BYTE_SEQ_LSB 0xFF,
+#define BYTE_SEQ_MSB 0xFF,
+
+#define HALF_SEQ_LSB 0xDC,0xFE,
+#define HALF_SEQ_LSB32 HALF_SEQ_LSB
+#define HALF_SEQ_LSB64 HALF_SEQ_LSB
+#define HALF_SEQ_MSB 0xFE,0xDC,
+#define HALF_SEQ_MSB32 HALF_SEQ_MSB
+#define HALF_SEQ_MSB64 HALF_SEQ_MSB
+#define HALF_VAL 0xFEDC
+#define HALF_VAL32 HALF_VAL
+#define HALF_VAL64 HALF_VAL
+
+#define WORD_SEQ_LSB 0x98,0xBA,0xDC,0xFE,
+#define WORD_SEQ_MSB 0xFE,0xDC,0xBA,0x98,
+#define WORD_SEQ_LSB32 WORD_SEQ_LSB
+#define WORD_SEQ_MSB32 WORD_SEQ_MSB
+#define WORD_SEQ_LSB64 WORD_SEQ_LSB
+#define WORD_SEQ_MSB64 WORD_SEQ_MSB
+#define WORD_VAL 0xFEDCBA98UL
+#define WORD_VAL32 WORD_VAL
+#define WORD_VAL64 WORD_VAL
+
+#define QUAD_SEQ_LSB 0x10,0x32,0x54,0x76,\
+ 0x98,0xBA,0xDC,0xFE,
+#define QUAD_SEQ_MSB 0xFE,0xDC,0xBA,0x98,\
+ 0x76,0x54,0x32,0x10,
+#define QUAD_VAL 0xFEDCBA9876543210ULL
+#define QUAD_VAL32 QUAD_VAL
+#define QUAD_VAL64 QUAD_VAL
+
+#define IDENT_BYTES 46,33,46,64,46,35,46,36,46,37,46,94,46,38,46,42
+#define IDENT_VAL { IDENT_BYTES }
+#define IDENT_SEQ_LSB IDENT_BYTES,
+#define IDENT_SEQ_MSB IDENT_BYTES,
+
+#define LWORD_SEQ_LSB QUAD_SEQ_LSB
+#define LWORD_SEQ_LSB32 QUAD_SEQ_LSB
+#define LWORD_SEQ_LSB64 QUAD_SEQ_LSB
+#define LWORD_SEQ_MSB QUAD_SEQ_MSB
+#define LWORD_SEQ_MSB32 QUAD_SEQ_MSB
+#define LWORD_SEQ_MSB64 QUAD_SEQ_MSB
+#define LWORD_VAL32 QUAD_VAL32
+#define LWORD_VAL64 QUAD_VAL64
+
+#define SWORD_SEQ_LSB WORD_SEQ_LSB
+#define SWORD_SEQ_LSB32 WORD_SEQ_LSB
+#define SWORD_SEQ_LSB64 WORD_SEQ_LSB
+#define SWORD_SEQ_MSB WORD_SEQ_MSB
+#define SWORD_SEQ_MSB32 WORD_SEQ_MSB
+#define SWORD_SEQ_MSB64 WORD_SEQ_MSB
+#define SWORD_VAL32 WORD_VAL32
+#define SWORD_VAL64 WORD_VAL64
+
+#define SXWORD_SEQ_LSB QUAD_SEQ_LSB
+#define SXWORD_SEQ_LSB64 QUAD_SEQ_LSB
+#define SXWORD_SEQ_MSB QUAD_SEQ_MSB
+#define SXWORD_SEQ_MSB64 QUAD_SEQ_MSB
+#define SXWORD_VAL64 QUAD_VAL64
+
+#define XWORD_SEQ_LSB QUAD_SEQ_LSB
+#define XWORD_SEQ_LSB64 QUAD_SEQ_LSB
+#define XWORD_SEQ_MSB QUAD_SEQ_MSB
+#define XWORD_SEQ_MSB64 QUAD_SEQ_MSB
+#define XWORD_VAL64 QUAD_VAL64
+
+/*
+ * ELF class dependent types.
+ */
+#define ADDR_SEQ_LSB32 WORD_SEQ_LSB
+#define ADDR_SEQ_MSB32 WORD_SEQ_MSB
+#define ADDR_VAL32 WORD_VAL32
+#define OFF_SEQ_LSB32 WORD_SEQ_LSB
+#define OFF_SEQ_MSB32 WORD_SEQ_MSB
+#define OFF_VAL32 WORD_VAL32
+
+#define ADDR_SEQ_LSB64 QUAD_SEQ_LSB
+#define ADDR_SEQ_MSB64 QUAD_SEQ_MSB
+#define ADDR_VAL64 QUAD_VAL64
+#define OFF_SEQ_LSB64 QUAD_SEQ_LSB
+#define OFF_SEQ_MSB64 QUAD_SEQ_MSB
+#define OFF_VAL64 QUAD_VAL64
+
+#define NCOPIES 3
+#define NOFFSET 8 /* Every alignment in a quad word. */
+
+divert(-1)
+/*
+ * Definitions of 32 bit ELF file structures.
+ */
+
+define(`ELF_TYPE_E32_CAP',
+ `MEMBER(c_tag, WORD)
+ MEMBER(c_un.c_val, WORD)')
+
+define(`ELF_TYPE_E32_DYN',
+ `MEMBER(d_tag, WORD)
+ MEMBER(d_un.d_val, WORD)')
+
+define(`ELF_TYPE_E32_EHDR',
+ `MEMBER(e_ident, IDENT)
+ MEMBER(e_type, HALF)
+ MEMBER(e_machine, HALF)
+ MEMBER(e_version, WORD)
+ MEMBER(e_entry, WORD)
+ MEMBER(e_phoff, WORD)
+ MEMBER(e_shoff, WORD)
+ MEMBER(e_flags, WORD)
+ MEMBER(e_ehsize, HALF)
+ MEMBER(e_phentsize, HALF)
+ MEMBER(e_phnum, HALF)
+ MEMBER(e_shentsize, HALF)
+ MEMBER(e_shnum, HALF)
+ MEMBER(e_shstrndx, HALF)')
+
+define(`ELF_TYPE_E32_MOVE',
+ `MEMBER(m_value, QUAD)
+ MEMBER(m_info, WORD)
+ MEMBER(m_poffset, WORD)
+ MEMBER(m_repeat, HALF)
+ MEMBER(m_stride, HALF)')
+
+define(`ELF_TYPE_E32_PHDR',
+ `MEMBER(p_type, WORD)
+ MEMBER(p_offset, WORD)
+ MEMBER(p_vaddr, WORD)
+ MEMBER(p_paddr, WORD)
+ MEMBER(p_filesz, WORD)
+ MEMBER(p_memsz, WORD)
+ MEMBER(p_flags, WORD)
+ MEMBER(p_align, WORD)')
+
+define(`ELF_TYPE_E32_REL',
+ `MEMBER(r_offset, WORD)
+ MEMBER(r_info, WORD)')
+
+define(`ELF_TYPE_E32_RELA',
+ `MEMBER(r_offset, WORD)
+ MEMBER(r_info, WORD)
+ MEMBER(r_addend, WORD)')
+
+define(`ELF_TYPE_E32_SHDR',
+ `MEMBER(sh_name, WORD)
+ MEMBER(sh_type, WORD)
+ MEMBER(sh_flags, WORD)
+ MEMBER(sh_addr, WORD)
+ MEMBER(sh_offset, WORD)
+ MEMBER(sh_size, WORD)
+ MEMBER(sh_link, WORD)
+ MEMBER(sh_info, WORD)
+ MEMBER(sh_addralign, WORD)
+ MEMBER(sh_entsize, WORD)')
+
+define(`ELF_TYPE_E32_SYM',
+ `MEMBER(st_name, WORD)
+ MEMBER(st_value, WORD)
+ MEMBER(st_size, WORD)
+ MEMBER(st_info, BYTE)
+ MEMBER(st_other, BYTE)
+ MEMBER(st_shndx, HALF)')
+
+define(`ELF_TYPE_E32_SYMINFO',
+ `MEMBER(si_boundto, HALF)
+ MEMBER(si_flags, HALF)')
+
+define(`ELF_TYPE_E32_VDEF',
+ `MEMBER(vd_version, HALF)
+ MEMBER(vd_flags, HALF)
+ MEMBER(vd_ndx, HALF)
+ MEMBER(vd_cnt, HALF)
+ MEMBER(vd_hash, WORD)
+ MEMBER(vd_aux, WORD)
+ MEMBER(vd_next, WORD)')
+
+define(`ELF_TYPE_E32_VNEED',
+ `MEMBER(vn_version, HALF)
+ MEMBER(vn_cnt, HALF)
+ MEMBER(vn_file, WORD)
+ MEMBER(vn_aux, WORD)
+ MEMBER(vn_next, WORD)')
+
+
+/*
+ * Definitions of 64 bit ELF file structures.
+ */
+
+define(`ELF_TYPE_E64_CAP',
+ `MEMBER(c_tag, QUAD)
+ MEMBER(c_un.c_val, QUAD)')
+
+define(`ELF_TYPE_E64_DYN',
+ `MEMBER(d_tag, QUAD)
+ MEMBER(d_un.d_val, QUAD)')
+
+define(`ELF_TYPE_E64_EHDR',
+ `MEMBER(e_ident, IDENT)
+ MEMBER(e_type, HALF)
+ MEMBER(e_machine, HALF)
+ MEMBER(e_version, WORD)
+ MEMBER(e_entry, QUAD)
+ MEMBER(e_phoff, QUAD)
+ MEMBER(e_shoff, QUAD)
+ MEMBER(e_flags, WORD)
+ MEMBER(e_ehsize, HALF)
+ MEMBER(e_phentsize, HALF)
+ MEMBER(e_phnum, HALF)
+ MEMBER(e_shentsize, HALF)
+ MEMBER(e_shnum, HALF)
+ MEMBER(e_shstrndx, HALF)')
+
+define(`ELF_TYPE_E64_MOVE',
+ `MEMBER(m_value, QUAD)
+ MEMBER(m_info, QUAD)
+ MEMBER(m_poffset, QUAD)
+ MEMBER(m_repeat, HALF)
+ MEMBER(m_stride, HALF)')
+
+define(`ELF_TYPE_E64_PHDR',
+ `MEMBER(p_type, WORD)
+ MEMBER(p_flags, WORD)
+ MEMBER(p_offset, QUAD)
+ MEMBER(p_vaddr, QUAD)
+ MEMBER(p_paddr, QUAD)
+ MEMBER(p_filesz, QUAD)
+ MEMBER(p_memsz, QUAD)
+ MEMBER(p_align, QUAD)')
+
+define(`ELF_TYPE_E64_REL',
+ `MEMBER(r_offset, QUAD)
+ MEMBER(r_info, QUAD)')
+
+define(`ELF_TYPE_E64_RELA',
+ `MEMBER(r_offset, QUAD)
+ MEMBER(r_info, QUAD)
+ MEMBER(r_addend, QUAD)')
+
+define(`ELF_TYPE_E64_SHDR',
+ `MEMBER(sh_name, WORD)
+ MEMBER(sh_type, WORD)
+ MEMBER(sh_flags, QUAD)
+ MEMBER(sh_addr, QUAD)
+ MEMBER(sh_offset, QUAD)
+ MEMBER(sh_size, QUAD)
+ MEMBER(sh_link, WORD)
+ MEMBER(sh_info, WORD)
+ MEMBER(sh_addralign, QUAD)
+ MEMBER(sh_entsize, QUAD)')
+
+define(`ELF_TYPE_E64_SYM',
+ `MEMBER(st_name, WORD)
+ MEMBER(st_info, BYTE)
+ MEMBER(st_other, BYTE)
+ MEMBER(st_shndx, HALF)
+ MEMBER(st_value, QUAD)
+ MEMBER(st_size, QUAD)')
+
+define(`ELF_TYPE_E64_SYMINFO',
+ `MEMBER(si_boundto, HALF)
+ MEMBER(si_flags, HALF)')
+
+define(`ELF_TYPE_E64_VDEF',
+ `MEMBER(vd_version, HALF)
+ MEMBER(vd_flags, HALF)
+ MEMBER(vd_ndx, HALF)
+ MEMBER(vd_cnt, HALF)
+ MEMBER(vd_hash, WORD)
+ MEMBER(vd_aux, WORD)
+ MEMBER(vd_next, WORD)')
+
+define(`ELF_TYPE_E64_VNEED',
+ `MEMBER(vn_version, HALF)
+ MEMBER(vn_cnt, HALF)
+ MEMBER(vn_file, WORD)
+ MEMBER(vn_aux, WORD)
+ MEMBER(vn_next, WORD)')
+
+/*
+ * MKRAWBITS(TYPE,CNAME,ENDIANNESS,SIZE)
+ *
+ * Create a char[] array that holds the type's file representation.
+ */
+define(`MKRAWBITS',
+ `static unsigned char ELFTYPEDEFINITION($1,`'__SZ__`',$3)[] = {
+ifdef(`ELF_TYPE_E'__SZ__`_$1',
+ `pushdef(`MEMBER',`$'2`_SEQ_$3')ELF_TYPE_E'__SZ__`_$1`'popdef(`MEMBER')',
+ `$1_SEQ_$3`'__SZ__') };')
+
+divert(0)
+
+ifdef(`ISELF32',
+ DO(32,`DOELFTYPES(`MKRAWBITS',LSB)')
+ DO(32,`DOELFTYPES(`MKRAWBITS',MSB)'))
+
+ifdef(`ISELF64',
+ `DO(64,`DOELFTYPES(`MKRAWBITS',LSB)')
+ DO(64,`DOELFTYPES(`MKRAWBITS',MSB)')')
+
+divert(-1)
+
+/*
+ * MKMEMSTRUCT(TYPE,CNAME)
+ *
+ * Define a C-structure with test data for TYPE.
+ */
+define(`MKMEMSTRUCT',
+ `static Elf`'__SZ__`'_$2 ELFMEMSTRUCT($1,__SZ__) =
+ifdef(`ELF_TYPE_E'__SZ__`_$1',
+ `pushdef(`MEMBER',.`$'1 = `$'2_VAL `,'){
+ELF_TYPE_E'__SZ__`_$1
+ }popdef(`MEMBER')',
+ `$1_VAL`'__SZ__');')
+
+/*
+ * MKMEMCHECK(TYPE,CNAME)
+ *
+ * Generate code to check a memory structure against reference data.
+ */
+define(`MKMEMCHECK',
+ `ifdef(`ELF_TYPE_E'__SZ__`_$1',dnl Structure type
+ `pushdef(`_T_',defn(`ELF_TYPE_E'__SZ__`_$1'))dnl
+ pushdef(`MEMBER',`
+ 'if (`ifelse'($`'2,IDENT,memcmp(dt->$`'1,ref->$`'1,sizeof(ref->$`'1)),
+ dt->$`'1 != ref->$`'1)) {
+ TP_FAIL("$1: unequal `$'1.");
+ goto done;
+ })
+ _T_
+ dt += 1;
+ popdef(`MEMBER')popdef(`_T_')',`dnl Primitive type.
+ if (memcmp(t, td->tsd_mem, msz) != 0) {
+ TP_FAIL("$1 compare failed.");
+ goto done;
+ }
+ t += msz;')')
+
+divert(0)
+
+ifdef(`ISELF32',`DO(32,`DOELFTYPES(`MKMEMSTRUCT')')')
+ifdef(`ISELF64',`DO(64,`DOELFTYPES(`MKMEMSTRUCT')')')
+
+struct testdata {
+ char *tsd_name;
+ Elf_Type tsd_type;
+
+ size_t tsd_fsz;
+ const unsigned char *tsd_lsb;
+ const unsigned char *tsd_msb;
+ void *tsd_mem;
+ size_t tsd_msz;
+};
+
+define(`DEFINE_TEST_DATA',
+ `[ELF_T_$1] = {
+ .tsd_name = "$1",
+ .tsd_type = ELF_T_$1,
+
+ .tsd_fsz = sizeof(ELFTYPEDEFINITION($1,__SZ__,LSB)),
+ .tsd_lsb = ELFTYPEDEFINITION($1,__SZ__,LSB),
+ .tsd_msb = ELFTYPEDEFINITION($1,__SZ__,MSB),
+
+ .tsd_mem = (void *) &ELFMEMSTRUCT($1,__SZ__),
+ .tsd_msz = sizeof(ELFMEMSTRUCT($1,__SZ__))
+}')
+
+dnl Tests for variable length Elf types.
+define(`DEFINE_TEST_DATA_VARIABLE_LENGTH',`
+[ELF_T_BYTE] = {
+ /* For byte compares, the LSB/MSB and memory data are identical. */
+ .tsd_name = "BYTE",
+ .tsd_type = ELF_T_BYTE,
+ .tsd_fsz = sizeof(ELFTYPEDEFINITION(WORD,__SZ__,LSB)),
+ .tsd_lsb = (void *) &ELFMEMSTRUCT(WORD,__SZ__),
+ .tsd_msb = (void *) &ELFMEMSTRUCT(WORD,__SZ__),
+ .tsd_mem = (void *) &ELFMEMSTRUCT(WORD,__SZ__),
+ .tsd_msz = sizeof(ELFMEMSTRUCT(WORD,__SZ__))
+}')
+define(`MKTD',`DEFINE_TEST_DATA($1) `,'')
+
+ifdef(`ISELF32',`static struct testdata ELFTESTS(32)[] = {
+DO(32,`DEFINE_TEST_DATA_VARIABLE_LENGTH'),
+DO(32,`DOELFTYPES(`MKTD')')
+{ }
+};')
+
+ifdef(`ISELF64',`static struct testdata ELFTESTS(64)[] = {
+DO(64,`DEFINE_TEST_DATA_VARIABLE_LENGTH'),
+DO(64,`DOELFTYPES(`MKTD')')
+{ }
+};')
+
+divert(-1)
+
+/*
+ * CallXlator(ARGS)
+ *
+ * Munge the call sequence depending on whether a gelf_* function is
+ * being tested or not.
+ */
+define(`CallXlator',`ifdef(`USEGELF',`TPFNNAME (e, $*)',`TPFNNAME ($*)')')
+
+/*
+ * CheckXlateResult(SZ)
+ */
+define(`CheckXlateResult',`
+ if (dst->d_type != td->tsd_type || dst->d_size != $1 * ncopies) {
+ TP_FAIL("type: ret=%d/expected=%d size: ret=%d/expected=%d",
+ dst->d_type, td->tsd_type, dst->d_size, $1*ncopies);
+ goto done;
+ }')
+define(`CheckXlateResultM',`CheckXlateResult(msz)')
+define(`CheckXlateResultF',`CheckXlateResult(fsz)')
+
+/*
+ * For all xlate tests we need to do the following:
+ *
+ * 1. Declare variables.
+ * 2. Allocate memory.
+ * 3. Locate reference data.
+ * 4. For each offset:
+ * 4a. if doing a ToF: initialize the source buffer (N copies)
+ * 4b. if doing a ToM: initialize the source (N copies) at the offset
+ * 4c. Invoke the xlator.
+ * 4d. Check by memcmp() against the reference.
+ *
+ * XlatePrelude(TYPE,ENDIANNESS,C-NAME)
+ */
+define(`XlatePrelude',`
+ Elf_Data dst, src, *r;
+ struct testdata *td;
+ size_t expected_size, fsz, msz;
+ int i, offset, result;
+ char *srcbuf, *dstbuf, *t;
+ TO_M_OR_F(`ifdef(`ELF_TYPE_E'__SZ__`_$1',`
+ Elf`'__SZ__`'_$3 *dt, *ref;')',`')
+
+ TP_ANNOUNCE("TPFNNAME""($1,$2) conversion.");
+
+ (void) memset(&dst, 0, sizeof(dst));
+ (void) memset(&src, 0, sizeof(src));
+
+ td = &tests`'__SZ__[ELF_T_$1];
+
+ fsz = elf`'__SZ__`'_fsize(td->tsd_type, 1, EV_CURRENT);
+ msz = td->tsd_msz;
+
+ result = TET_PASS;
+
+ assert(msz > 0);
+ assert(fsz == td->tsd_fsz); /* Sanity check. */
+
+ srcbuf = dstbuf = NULL;
+
+ TO_M_OR_F(`
+ /* Copy to memory. */
+ if ((srcbuf = malloc(NCOPIES*fsz + NOFFSET)) == NULL) {
+ TP_UNRESOLVED("TPFNNAME"" malloc() failed.");
+ goto done;
+ }
+
+ if ((dstbuf = calloc(1,NCOPIES*msz)) == NULL) {
+ TP_UNRESOLVED("TPFNNAME"" malloc() failed.");
+ goto done;
+ }',`
+ /* Copy to file. */
+ if ((srcbuf = malloc(NCOPIES*msz)) == NULL) {
+ TP_UNRESOLVED("TPFNNAME"" malloc() failed.");
+ goto done;
+ }
+
+ if ((dstbuf = calloc(1,NCOPIES*fsz + NOFFSET)) == NULL) {
+ TP_UNRESOLVED("TPFNNAME"" malloc() failed.");
+ goto done;
+ }')
+')
+
+/*
+ * XlateCopySrcData(TYPE,ENDIANNESS)
+ *
+ * Copy bytes of src data, and set the src and dst Elf_Data structures.
+ */
+define(`XlateCopySrcData',`
+TO_M_OR_F(`
+ t = srcbuf + offset;
+ for (i = 0; i < NCOPIES; i++) {
+ (void) memcpy(t, td->tsd_`'TOLOWER($2), fsz);
+ t += fsz;
+ }
+
+ src.d_buf = srcbuf + offset;
+ src.d_size = fsz * NCOPIES;
+ src.d_type = td->tsd_type;
+ src.d_version = EV_CURRENT;
+
+ dst.d_buf = dstbuf;
+ dst.d_size = msz * NCOPIES;
+ dst.d_version = EV_CURRENT;
+ ',`
+ t = srcbuf;
+ for (i = 0; i < NCOPIES; i++) {
+ (void) memcpy(t, td->tsd_mem, msz);
+ t += msz;
+ }
+
+ src.d_buf = srcbuf;
+ src.d_size = msz * NCOPIES;
+ src.d_type = td->tsd_type;
+ src.d_version = EV_CURRENT;
+
+ dst.d_buf = dstbuf + offset;
+ dst.d_size = fsz * NCOPIES;
+ dst.d_version = EV_CURRENT;')')
+
+/*
+ * XlateConvertAndCheck(TYPE,ENDIANNESS,C-NAME)
+ *
+ * Invoke TPFNNAME () and check the returned buffer type and size.
+ */
+define(`XlateConvertAndCheck',`
+ if ((r = CallXlator(&dst, &src, ELFDATA2$2)) != &dst) {
+ TP_FAIL("TPFNNAME""($1:$2) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ expected_size = NCOPIES * TO_M_OR_F(`msz',`fsz');
+
+ if (dst.d_type != td->tsd_type ||
+ dst.d_size != expected_size) {
+ TP_FAIL("TPFNNAME""($1:$2) type(%d != %d expected), "
+ "size(%d != %d expected).", dst.d_type, td->tsd_type,
+ dst.d_size, expected_size);
+ goto done;
+ }
+ TO_M_OR_F(`
+ /* Check returned memory data. */
+ifdef(`ELF_TYPE_E'__SZ__`_$1',`
+ dt = (Elf`'__SZ__`'_$3 *) (uintptr_t) dst.d_buf;
+ ref = (Elf`'__SZ__`'_$3 *) td->tsd_mem;',`
+ t = dst.d_buf;')
+
+ for (i = 0; i < NCOPIES; i++) {
+ MKMEMCHECK($1)
+ }',`
+ /* Check returned file data. */
+ t = dst.d_buf;
+ for (i = 0; i < NCOPIES; i++) {
+ if (memcmp(t, td->tsd_`'TOLOWER($2), fsz) != 0) {
+ TP_FAIL("$1 compare failed.");
+ goto done;
+ }
+ t += fsz;
+ }')
+')
+
+/*
+ * MKCONVERSIONTP(TYPE,C-Name,ENDIANNESS)
+ *
+ * Generate a test purpose that tests conversions for Elf type TYPE.
+ */
+define(`MKCONVERSIONTP',`
+void
+tcXlate_tp$1_$3`'__SZ__ (void)
+{
+ XlatePrelude($1,$3,$2)
+
+ result = TET_PASS;
+
+ for (offset = 0; offset < NOFFSET; offset++) {
+ XlateCopySrcData($1,$3)
+ XlateConvertAndCheck($1,$3,$2)
+ }
+
+ done:
+ if (srcbuf)
+ free(srcbuf);
+ if (dstbuf)
+ free(dstbuf);
+ tet_result(result);
+}')
+
+/*
+ * Xlate_TestConversions_Byte()
+ *
+ * Test byte conversions.
+ */
+define(`Xlate_TestConversions_Byte',`
+void
+tcXlate_tpByte`'__SZ__ (void)
+{
+ Elf_Data dst, src, *r;
+ int i, offset, result;
+ size_t expected_size, fsz, msz;
+ struct testdata *td;
+ char srcbuf[NCOPIES*sizeof(ELFTYPEDEFINITION(WORD,__SZ__,LSB)) + NOFFSET];
+ char dstbuf[sizeof(srcbuf)];
+ char *t;
+
+ TP_ANNOUNCE("TPFNNAME""(BYTE) conversion.");
+
+ (void) memset(&dst, 0, sizeof(dst));
+ (void) memset(&src, 0, sizeof(src));
+
+ td = &tests`'__SZ__[ELF_T_BYTE];
+
+ fsz = msz = sizeof(ELFTYPEDEFINITION(WORD,__SZ__,LSB));
+ expected_size = NCOPIES * msz;
+ result = TET_PASS;
+
+ for (offset = 0; offset < NOFFSET; offset++) {
+
+ XlateCopySrcData(BYTE,LSB);
+ XlateConvertAndCheck(BYTE,LSB);
+ XlateConvertAndCheck(BYTE,MSB,Word);
+ }
+
+ done:
+ tet_result(result);
+}')
+
+define(`Xlate_TestConversions_Note')
+
+/*
+ * Xlate_TestConversions
+ *
+ * Make test cases th non-byte conversions from file representations
+ * to memory.
+ */
+define(`Xlate_TestConversions',`
+ifdef(`ISELF32',dnl
+`DO(32,`Xlate_TestConversions_Byte
+Xlate_TestConversions_Note')
+DO(32,`DOELFTYPES(`MKCONVERSIONTP',LSB)')
+DO(32,`DOELFTYPES(`MKCONVERSIONTP',MSB)')')
+ifdef(`ISELF64',dnl
+`DO(64,`Xlate_TestConversions_Byte
+Xlate_TestConversions_Note')
+DO(64,`DOELFTYPES(`MKCONVERSIONTP',LSB)')
+DO(64,`DOELFTYPES(`MKCONVERSIONTP',MSB)')')')
+
+define(`Xlate_TestSharedConversions_Byte',`
+void
+tcXlate_tpByteShared`'__SZ__ (void)
+{
+ Elf_Data dst, src, *r;
+ int i, offset, result;
+ size_t expected_size, fsz, msz;
+ struct testdata *td;
+ char srcbuf[NCOPIES*sizeof(ELFTYPEDEFINITION(WORD,__SZ__,LSB))];
+ char *dstbuf;
+ char *t;
+
+ TP_ANNOUNCE("Test TPFNNAME""(BYTE) shared-buffer conversion.");
+
+ (void) memset(&dst, 0, sizeof(dst));
+ (void) memset(&src, 0, sizeof(src));
+
+ td = &tests`'__SZ__[ELF_T_BYTE];
+
+ fsz = msz = sizeof(ELFTYPEDEFINITION(WORD,__SZ__,LSB));
+ expected_size = NCOPIES * msz;
+ result = TET_PASS;
+ dstbuf = srcbuf;
+ offset = 0;
+
+ XlateCopySrcData(BYTE,LSB);
+ XlateConvertAndCheck(BYTE,LSB,Word);
+ XlateConvertAndCheck(BYTE,MSB,Word);
+
+ done:
+ tet_result(result);
+}')
+
+define(`Xlate_TestSharedConversions_Note')
+
+define(`MKSHAREDCONVERSIONTP',`
+void
+tcXlate_tpShared$1_$3`'__SZ__ (void)
+{
+ Elf_Data dst, src, *r;
+ struct testdata *td;
+ size_t expected_size, fsz, msz;
+ int i, result;
+ char *srcbuf, *t;
+ TO_M_OR_F(`ifdef(`ELF_TYPE_E'__SZ__`_$1',`
+ Elf`'__SZ__`'_$2 *dt, *ref;')',`')
+
+ TP_ANNOUNCE("TPFNNAME""($1,$3) conversion.");
+
+ (void) memset(&dst, 0, sizeof(dst));
+ (void) memset(&src, 0, sizeof(src));
+
+ td = &tests`'__SZ__[ELF_T_$1];
+
+ fsz = elf`'__SZ__`'_fsize(td->tsd_type, 1, EV_CURRENT);
+ msz = td->tsd_msz;
+
+ result = TET_PASS;
+
+ assert(msz > 0);
+ assert(fsz == td->tsd_fsz); /* Sanity check. */
+
+ srcbuf = t = NULL;
+ if ((srcbuf = malloc(NCOPIES*msz)) == NULL) {
+ TP_UNRESOLVED("TPFNNAME"" malloc() failed.");
+ goto done;
+ }
+
+ src.d_buf = dst.d_buf = srcbuf;
+ src.d_version = dst.d_version = EV_CURRENT;
+ TO_M_OR_F(`src.d_size = fsz * NCOPIES;
+ dst.d_size = msz * NCOPIES;',`dnl
+ src.d_size = msz * NCOPIES;
+ dst.d_size = fsz * NCOPIES;')
+ src.d_type = dst.d_type = ELF_T_$1;
+ t = srcbuf;
+ for (i = 0; i < NCOPIES; i++) {
+ TO_M_OR_F(`
+ (void) memcpy(t, td->tsd_`'TOLOWER($3), fsz);
+ t += fsz;',`
+ (void) memcpy(t, td->tsd_mem, msz);
+ t += msz;')
+ }
+
+ result = TET_PASS;
+
+ XlateConvertAndCheck($1,$3,$2)
+
+ done:
+ if (srcbuf)
+ free(srcbuf);
+ tet_result(result);
+}')
+
+define(`Xlate_TestConversionsSharedBuffer',`
+ifdef(`ISELF32',dnl
+`DO(32,`Xlate_TestSharedConversions_Byte
+Xlate_TestSharedConversions_Note')
+DO(32,`DOELFTYPES(`MKSHAREDCONVERSIONTP',LSB)')
+DO(32,`DOELFTYPES(`MKSHAREDCONVERSIONTP',MSB)')')
+ifdef(`ISELF64',dnl
+`DO(64,`Xlate_TestSharedConversions_Byte
+Xlate_TestSharedConversions_Note')
+DO(64,`DOELFTYPES(`MKSHAREDCONVERSIONTP',LSB)')
+DO(64,`DOELFTYPES(`MKSHAREDCONVERSIONTP',MSB)')')')
+
+define(`Xlate_TestBadArguments',`
+void
+tcArgs_tpNullArgs(void)
+{
+ Elf_Data ed, *r;
+ int error, result;
+
+ TP_ANNOUNCE("TPFNNAME () with NULL arguments fails with "
+ "ELF_E_ARGUMENT");
+
+ memset(&ed, 0, sizeof(ed));
+
+ result = TET_PASS;
+
+ if ((r = CallXlator(NULL, &ed, ELFDATA2LSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("TPFNNAME(NULL, *, LSB) failed: r=%p error=\"%s\".",
+ (void *) r, elf_errmsg(error));
+ goto done;
+ }
+
+ if ((r = CallXlator(NULL, &ed, ELFDATA2MSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("TPFNNAME(NULL, *, MSB) failed: r=%p error=\"%s\".",
+ (void *) r, elf_errmsg(error));
+ goto done;
+ }
+
+ if ((r = CallXlator(&ed, NULL, ELFDATA2LSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("TPFNNAME(*, NULL, LSB) failed: r=%p error=\"%s\".",
+ (void *) r, elf_errmsg(error));
+ goto done;
+ }
+
+ if ((r = CallXlator(&ed, NULL, ELFDATA2MSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("TPFNNAME(*, NULL, MSB) failed: r=%p error=\"%s\".",
+ (void *) r, elf_errmsg(error));
+
+ done:
+ tet_result(result);
+}
+
+void
+tcArgs_tpBadType(void)
+{
+
+ Elf_Data ed, es, *r;
+ int error, result;
+ char buf[1024];
+
+ TP_ANNOUNCE("TPFNNAME () with an out of range type fails with "
+ "ELF_E_DATA.");
+
+ result = TET_PASS;
+
+ (void) memset(&es, 0, sizeof(es));
+ (void) memset(&ed, 0, sizeof(ed));
+
+ es.d_version = ed.d_version = EV_CURRENT;
+ es.d_buf = ed.d_buf = buf;
+ es.d_size = ed.d_size = sizeof(buf);
+
+ es.d_type = (Elf_Type) -1;
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_DATA) {
+ TP_FAIL("TPFNNAME (*, *, LSB) (%d): r=%p error=\"%s\".",
+ es.d_type, (void *) r, elf_errmsg(error));
+ goto done;
+ }
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_DATA) {
+ TP_FAIL("TPFNNAME (*, *, MSB) (%d): r=%p error=\"%s\".",
+ es.d_type, (void *) r, elf_errmsg(error));
+ goto done;
+ }
+
+ es.d_type = ELF_T_NUM;
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_DATA) {
+ TP_FAIL("TPFNNAME (*, *, LSB) (%d): r=%p error=%\"%s\".",
+ es.d_type, (void *) r, elf_errmsg(error));
+ goto done;
+ }
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_DATA)
+ TP_FAIL("TPFNNAME (*, *, MSB) (%d): r=%p error=\"%s\".",
+ es.d_type, (void *) r, elf_errmsg(error));
+
+
+ done:
+ tet_result(result);
+}
+
+void
+tcArgs_tpBadEncoding(void)
+{
+ Elf_Data ed, es, *r;
+ int error, result;
+
+ TP_ANNOUNCE("TPFNNAME (*,*,BADENCODING) fails with "
+ "ELF_E_ARGUMENT.");
+
+ (void) memset(&ed, 0, sizeof(ed));
+ (void) memset(&es, 0, sizeof(es));
+
+ result = TET_PASS;
+
+ if ((r = CallXlator(&ed, &es, ELFDATANONE-1)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("TPFNNAME (*, *, %d): r=%p error=\"%s\".",
+ ELFDATANONE-1, r, elf_errmsg(error));
+ goto done;
+ }
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2MSB+1)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("TPFNNAME (*, *, %d): r=%p error=\"%s\".",
+ ELFDATA2MSB+1, r, elf_errmsg(error));
+
+ done:
+ tet_result(result);
+}
+
+void
+tcArgs_tpDstVersion(void)
+{
+ Elf_Data ed, es, *r;
+ int error, result;
+ char buf[sizeof(int)];
+
+ TP_ANNOUNCE("TPFNNAME (*,*,*) with an illegal dst version "
+ "fails with ELF_E_UNIMPL.");
+
+ (void) memset(&ed, 0, sizeof(ed));
+ (void) memset(&es, 0, sizeof(es));
+
+ es.d_buf = ed.d_buf = buf;
+ es.d_type = ELF_T_BYTE;
+ es.d_size = ed.d_size = sizeof(buf);
+ es.d_version = EV_CURRENT;
+ ed.d_version = EV_NONE;
+
+ result = TET_PASS;
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_UNIMPL) {
+ TP_FAIL("TPFNNAME (*,*,LSB) ver=%d r=%p error=\"%s\".",
+ ed.d_version, r, elf_errmsg(error));
+ goto done;
+ }
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_UNIMPL)
+ TP_FAIL("TPFNNAME (*,*,MSB) ver=%d r=%p error=\"%s\".",
+ ed.d_version, r, elf_errmsg(error));
+
+ done:
+ tet_result(result);
+}
+
+void
+tcArgs_tpSrcVersion(void)
+{
+ Elf_Data ed, es, *r;
+ int error, result;
+ char buf[sizeof(int)];
+
+ TP_ANNOUNCE("TPFNNAME (*,*,*) with an illegal src version fails "
+ "with ELF_E_UNIMPL.");
+
+ (void) memset(&ed, 0, sizeof(ed));
+ (void) memset(&es, 0, sizeof(es));
+
+ es.d_buf = ed.d_buf = buf;
+ es.d_type = ELF_T_BYTE;
+ es.d_size = ed.d_size = sizeof(buf);
+ es.d_version = EV_CURRENT+1;
+ ed.d_version = EV_CURRENT;
+
+ result = TET_PASS;
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_UNIMPL) {
+ TP_FAIL("TPFNNAME (*,*,LSB) ver=%d r=%p error=\"%s\".",
+ es.d_version, r, elf_errmsg(error));
+ goto done;
+ }
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_UNIMPL)
+ TP_FAIL("TPFNNAME (*,*,MSB) ver=%d r=%p error=\"%s\".",
+ es.d_version, r, elf_errmsg(error));
+
+ done:
+ tet_result(result);
+}
+
+/*
+ * Check for an unimplemented type.
+ */
+void
+tcArgs_tpUnimplemented(void)
+{
+ Elf_Data ed, es, *r;
+ int error, i, result;
+ char sbuf[TPBUFSIZE]; /* large enough for any ELF type */
+ char dbuf[TPBUFSIZE];
+
+ TP_ANNOUNCE("TPFNNAME""() on unimplemented types fails with "
+ "ELF_E_UNIMPL.");
+
+ (void) memset(&ed, 0, sizeof(ed));
+ (void) memset(&es, 0, sizeof(es));
+
+ ed.d_buf = dbuf; ed.d_size = sizeof(dbuf);
+ es.d_buf = sbuf; es.d_size = sizeof(sbuf);
+ es.d_version = ed.d_version = EV_CURRENT;
+
+ result = TET_PASS;
+
+ for (i = 0; i < ELF_T_NUM; i++) {
+ /* Skip over supported types. */
+ switch (i) {
+ case ELF_T_MOVEP:
+ ifelse(ISELF64,`Y',`',`
+ case ELF_T_SXWORD:
+ case ELF_T_XWORD:
+')
+ break;
+ default:
+ continue;
+ }
+
+ es.d_type = i;
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_UNIMPL) {
+ TP_FAIL("TPFNNAME (*,*,LSB): type=%d r=%p "
+ "error=\"%s\".", i, r, elf_errmsg(error));
+ goto done;
+ }
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_UNIMPL) {
+ TP_FAIL("TPFNNAME (*,*,LSB): type=%d r=%p "
+ "error=\"%s\".", i, r, elf_errmsg(error));
+ goto done;
+ }
+ }
+
+ done:
+ tet_result(result);
+}
+')
+
+/*
+ * MKMISALIGNEDTP(TYPE,C-NAME)
+ *
+ * Generate a test case for checking misaligned buffers.
+ */
+
+define(`MKMISALIGNEDTP',`
+void
+tcBuffer_tpMisaligned_$1_`'__SZ__`'(void)
+{
+ Elf_Data ed, es, *r;
+ int count, error, result;
+ size_t fsz, msz;
+ char sb[TPBUFSIZE], db[TPBUFSIZE];
+ struct testdata *td;
+
+ TP_ANNOUNCE("TPFNNAME""($1) misaligned buffers with "
+ "ELF_E_DATA.");
+
+ result = TET_PASS;
+
+ td = &tests`'__SZ__[ELF_T_$1];
+ fsz = td->tsd_fsz;
+ msz = td->tsd_msz;
+
+ (void) memset(&ed, 0, sizeof(ed));
+ (void) memset(&es, 0, sizeof(es));
+
+ es.d_type = es.d_type = td->tsd_type;
+ es.d_version = ed.d_version = EV_CURRENT;
+
+ count = sizeof(sb) / msz; /* Note: msz >= fsz always. */
+
+ TO_M_OR_F(`
+ /* Misalign the destination for to-memory xfers. */
+ es.d_size = count * fsz;
+ ed.d_size = count * msz;
+
+ es.d_buf = sb;
+ ed.d_buf = db + 1; /* Guaranteed to be misaliged. */
+ ',`
+ /* Misalign the source for to-file xfers. */
+
+ es.d_size = count * msz;
+ ed.d_size = count * fsz;
+
+ es.d_buf = sb + 1; /* Guaranteed to be misaliged. */
+ ed.d_buf = db;')
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_DATA) {
+ TP_FAIL("TPFNNAME""(LSB) r=%p error=\"%s\".", r,
+ elf_errmsg(error));
+ goto done;
+ }
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_DATA)
+ TP_FAIL("TPFNNAME""(MSB) r=%p error=\"%s\".", r,
+ elf_errmsg(error));
+
+ done:
+ tet_result(result);
+}')
+
+define(`MKNONINTEGRALSRC',`
+void
+tcBuffer_tpSrcExtra_$1_`'__SZ__`'(void)
+{
+ Elf_Data ed, es, *r;
+ int count, error, result;
+ size_t fsz, msz;
+ char sb[TPBUFSIZE], db[TPBUFSIZE];
+ struct testdata *td;
+
+ TP_ANNOUNCE("TPFNNAME""($1) mis-sized source buffer is rejected with "
+ "ELF_E_DATA.");
+
+ result = TET_PASS;
+
+ td = &tests`'__SZ__[ELF_T_$1];
+ fsz = td->tsd_fsz;
+ msz = td->tsd_msz;
+
+ (void) memset(&ed, 0, sizeof(ed));
+ (void) memset(&es, 0, sizeof(es));
+
+ ed.d_type = es.d_type = td->tsd_type;
+ ed.d_version = es.d_version = EV_CURRENT;
+ es.d_buf = sb; ed.d_buf = db;
+
+ count = (sizeof(db) / msz) - 1; /* Note: msz >= fsz always. */
+
+ /* Add an extra byte to the source buffer size. */
+ TO_M_OR_F(`
+ es.d_size = (count * fsz) + 1;
+ ed.d_size = count * msz;',`
+ es.d_size = (count * msz) + 1;
+ ed.d_size = count * fsz;')
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_DATA) {
+ TP_FAIL("TPFNNAME""(LSB) r=%p error=\"%s\".", r,
+ elf_errmsg(error));
+ goto done;
+ }
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_DATA)
+ TP_FAIL("TPFNNAME""(LSB) r=%p error=\"%s\".", r,
+ elf_errmsg(error));
+
+ done:
+ tet_result(result);
+
+}')
+
+define(`MKDSTTOOSMALL',`
+void
+tcBuffer_tpDstTooSmall_$1_`'__SZ__`'(void)
+{
+ Elf_Data ed, es, *r;
+ int count, error, result;
+ struct testdata *td;
+ size_t fsz, msz;
+ char sb[TPBUFSIZE], db[TPBUFSIZE];
+
+ TP_ANNOUNCE("TPFNNAME""($1) small destination buffers are rejected "
+ "with ELF_E_DATA.");
+
+ result = TET_PASS;
+
+ td = &tests`'__SZ__[ELF_T_$1];
+ fsz = td->tsd_fsz;
+ msz = td->tsd_msz;
+
+ (void) memset(&ed, 0, sizeof(ed));
+ (void) memset(&es, 0, sizeof(es));
+
+ count = sizeof(sb) / msz; /* Note: msz >= fsz always. */
+
+ ed.d_type = es.d_type = td->tsd_type;
+ ed.d_version = es.d_version = EV_CURRENT;
+ es.d_buf = sb; ed.d_buf = db;
+ ed.d_size = 1;
+
+ TO_M_OR_F(`es.d_size = sizeof(sb) / fsz;',
+ `es.d_size = sizeof(sb) / msz;')
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_DATA) {
+ TP_FAIL("TPFNNAME""(LSB) r=%p error=\"%s\".", r,
+ elf_errmsg(error));
+ goto done;
+ }
+
+ if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL ||
+ (error = elf_errno()) != ELF_E_DATA)
+ TP_FAIL("TPFNNAME""(LSB) r=%p error=\"%s\".", r,
+ elf_errmsg(error));
+
+ done:
+ tet_result(result);
+}')
+
+define(`Xlate_TestBadBuffers',`
+void
+tcBuffer_tpNullDataPtr(void)
+{
+ Elf_Data ed, es, *r;
+ int error, result;
+ char buf[sizeof(int)];
+
+ TP_ANNOUNCE("TPFNNAME" "(...) with null d_buf pointers fails with "
+ "ELF_E_DATA.");
+
+ (void) memset(&ed, 0, sizeof(ed));
+ (void) memset(&es, 0, sizeof(es));
+
+ result = TET_PASS;
+
+ es.d_type = ELF_T_BYTE;
+ es.d_size = ed.d_size = sizeof(buf);
+ es.d_version = EV_CURRENT;
+ ed.d_version = EV_CURRENT;
+
+ es.d_buf = NULL;
+ ed.d_buf = buf;
+ if ((r = CallXlator(&ed, &es, ELFDATANONE)) != NULL ||
+ (error = elf_errno()) != ELF_E_DATA) {
+ TP_FAIL("TPFNNAME""(...) src.d_buf=NULL r=%d error=\"%s\".",
+ r, elf_errmsg(error));
+ goto done;
+ }
+
+ es.d_buf = buf;
+ ed.d_buf = NULL;
+
+ if ((r = CallXlator(&ed, &es, ELFDATANONE)) != NULL ||
+ (error = elf_errno()) != ELF_E_DATA)
+ TP_FAIL("TPFNNAME""(...) dst.d_buf=NULL r=%d error=\"%s\".",
+ r, elf_errmsg(error));
+
+ done:
+ tet_result(result);
+}
+
+/*
+ * Misaligned data.
+ */
+
+ifdef(`ISELF32',`DO(32,`DOELFTYPES(`MKMISALIGNEDTP')')')
+ifdef(`ISELF64',`DO(64,`DOELFTYPES(`MKMISALIGNEDTP')')')
+
+/*
+ * Overlapping buffers.
+ */
+void
+tcBuffer_tpOverlap(void)
+{
+ Elf_Data ed, es, *r;
+ int error, result;
+ char buf[sizeof(int)];
+
+ TP_ANNOUNCE("TPFNNAME""(...) overlapping buffers are rejected with "
+ "ELF_E_DATA.");
+
+ es.d_buf = buf; ed.d_buf = buf+1;
+ es.d_version = ed.d_version = EV_CURRENT;
+ es.d_size = ed.d_size = sizeof(buf);
+ es.d_type = ELF_T_BYTE;
+
+ result = TET_PASS;
+
+ if ((r = CallXlator(&ed, &es, ELFDATANONE)) != NULL ||
+ (error = elf_errno()) != ELF_E_DATA)
+ TP_FAIL("r=%p error=\"%s\".", r, elf_errmsg(error));
+
+ tet_result(result);
+}
+
+/*
+ * Non-integral number of src elements.
+ */
+ifdef(`ISELF32',`DO(32,`DOELFTYPES(`MKNONINTEGRALSRC')')')
+ifdef(`ISELF64',`DO(64,`DOELFTYPES(`MKNONINTEGRALSRC')')')
+
+/*
+ * Destination too small.
+ */
+ifdef(`ISELF32',`DO(32,`DOELFTYPES(`MKDSTTOOSMALL')')')
+ifdef(`ISELF64',`DO(64,`DOELFTYPES(`MKDSTTOOSMALL')')')
+
+')
+divert(0)
diff --git a/test/libelf/tset/common/xscn-1.yaml b/test/libelf/tset/common/xscn-1.yaml
new file mode 100644
index 0000000000000..113dbcb68d3e2
--- /dev/null
+++ b/test/libelf/tset/common/xscn-1.yaml
@@ -0,0 +1,23 @@
+%YAML 1.1
+---
+# $Id: xscn-1.yaml 2053 2011-10-26 11:50:18Z jkoshy $
+#
+# This file is used for tests requiring malformed extended section
+# numbering. 'e_shnum' is set to zero, but the section at index
+# SHN_UNDEF is not of type SHT_NULL.
+#
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
+ e_type: ET_REL
+ e_shnum: 0
+
+sections:
+ - !Section # index 0
+ sh_type: SHT_PROGBITS
+ - !Section
+ sh_type: SHT_STRTAB
+ sh_name: .shstrtab
+ sh_data:
+ - .shstrtab
diff --git a/test/libelf/tset/common/xscn-2.yaml b/test/libelf/tset/common/xscn-2.yaml
new file mode 100644
index 0000000000000..54b6752e0c96a
--- /dev/null
+++ b/test/libelf/tset/common/xscn-2.yaml
@@ -0,0 +1,22 @@
+%YAML 1.1
+# $Id: xscn-2.yaml 2053 2011-10-26 11:50:18Z jkoshy $
+---
+#
+# This file is used for tests requiring a well-formed ELF file that
+# uses extended section numbering.
+#
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
+ e_type: ET_REL
+
+sections:
+ - !Section
+ sh_type: SHT_NULL
+ - !Section
+ sh_type: SHT_STRTAB
+ sh_index: 65537
+ sh_name: .shstrtab
+ sh_data:
+ - .shstrtab
diff --git a/test/libelf/tset/common/xscn-3.yaml b/test/libelf/tset/common/xscn-3.yaml
new file mode 100644
index 0000000000000..b5edbff46c478
--- /dev/null
+++ b/test/libelf/tset/common/xscn-3.yaml
@@ -0,0 +1,26 @@
+%YAML 1.1
+# $Id: xscn-3.yaml 2053 2011-10-26 11:50:18Z jkoshy $
+---
+#
+# This file is used for tests requiring malformed extended section
+# numbering for elf_getshstrndx(). 'e_shnum' is set to zero, but
+# the section at index SHN_UNDEF is not of type SHT_NULL. `e_shstrndx'
+# corresponds to a section > SHN_LORESERVE.
+
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
+ e_type: ET_REL
+ e_shnum: 0
+ e_shstrndx: 65537
+
+sections:
+ - !Section # index 0
+ sh_type: SHT_PROGBITS
+ - !Section
+ sh_type: SHT_STRTAB
+ sh_index: 65537
+ sh_name: .shstrtab
+ sh_data:
+ - .shstrtab
diff --git a/test/libelf/tset/common/zerosection.yaml b/test/libelf/tset/common/zerosection.yaml
new file mode 100644
index 0000000000000..8bcc2d73c2d1a
--- /dev/null
+++ b/test/libelf/tset/common/zerosection.yaml
@@ -0,0 +1,27 @@
+%YAML 1.1
+---
+# $Id: zerosection.yaml 2077 2011-10-27 03:59:40Z jkoshy $
+#
+# An ELF file containing a zero-sized section.
+
+ehdr: !Ehdr
+ e_ident: !Ident
+ ei_class: ELFCLASSNONE
+ ei_data: ELFDATANONE
+ e_type: ET_REL
+
+sections:
+ - !Section # index 0
+ sh_type: SHT_NULL
+
+ - !Section
+ sh_name: .shstrtab
+ sh_type: SHT_STRTAB
+ sh_data:
+ - .shstrtab
+ - .zerosection
+
+ - !Section
+ sh_name: .zerosection
+ sh_offset: 2048
+ sh_type: SHT_NOBITS
diff --git a/test/libelf/tset/elf32_getehdr/Makefile b/test/libelf/tset/elf32_getehdr/Makefile
new file mode 100644
index 0000000000000..8285b1f8ed6e3
--- /dev/null
+++ b/test/libelf/tset/elf32_getehdr/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1368 2011-01-22 09:09:15Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= ehdr.m4
+TS_YAML= ehdr
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf32_getehdr/ehdr.m4 b/test/libelf/tset/elf32_getehdr/ehdr.m4
new file mode 100644
index 0000000000000..54f058380bcd7
--- /dev/null
+++ b/test/libelf/tset/elf32_getehdr/ehdr.m4
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: ehdr.m4 2054 2011-10-26 12:12:06Z jkoshy $
+ */
+
+#include <sys/cdefs.h>
+
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+#include "elfts.h"
+
+define(`TS_EHDRFUNC',`_getehdr')
+define(`TS_EHDRSZ',`32')
+include(`ehdr_template.m4')
diff --git a/test/libelf/tset/elf32_getphdr/Makefile b/test/libelf/tset/elf32_getphdr/Makefile
new file mode 100644
index 0000000000000..c02b2c4f1029c
--- /dev/null
+++ b/test/libelf/tset/elf32_getphdr/Makefile
@@ -0,0 +1,9 @@
+# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= phdr.m4
+TS_DATA= ehdr.msb32 ehdr.lsb32 \
+ phdr.msb32 phdr.lsb32 phdr.msb64 phdr.lsb64
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf32_getphdr/phdr.m4 b/test/libelf/tset/elf32_getphdr/phdr.m4
new file mode 100644
index 0000000000000..eb27e0ecbb546
--- /dev/null
+++ b/test/libelf/tset/elf32_getphdr/phdr.m4
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2006 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: phdr.m4 2054 2011-10-26 12:12:06Z jkoshy $
+ */
+
+#include <sys/cdefs.h>
+
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+#include "elfts.h"
+
+#define TS_PHDRFUNC _getphdr
+#define TS_PHDRSZ 32
+#include "phdr_template.c"
diff --git a/test/libelf/tset/elf32_getshdr/Makefile b/test/libelf/tset/elf32_getshdr/Makefile
new file mode 100644
index 0000000000000..1a8f5c53902af
--- /dev/null
+++ b/test/libelf/tset/elf32_getshdr/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1189 2010-09-11 16:04:59Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= shdr.m4
+TS_YAML= shdr
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf32_getshdr/shdr.m4 b/test/libelf/tset/elf32_getshdr/shdr.m4
new file mode 100644
index 0000000000000..738d3aad2c929
--- /dev/null
+++ b/test/libelf/tset/elf32_getshdr/shdr.m4
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2006 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: shdr.m4 223 2008-08-10 15:40:06Z jkoshy $
+ */
+
+#include <sys/mman.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+
+#include "elfts.h"
+
+IC_REQUIRES_VERSION_INIT();
+
+include(`elfts.m4')
+
+include(`getshdr.m4')
+
+TP_NULL(32)
+
+TC_MAKE_REF_SHDR(32)
+TP_SHDR(32,lsb)
+TP_SHDR(32,msb)
+
+
diff --git a/test/libelf/tset/elf32_newehdr/Makefile b/test/libelf/tset/elf32_newehdr/Makefile
new file mode 100644
index 0000000000000..78c4f1238af3b
--- /dev/null
+++ b/test/libelf/tset/elf32_newehdr/Makefile
@@ -0,0 +1,9 @@
+# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= ehdr.m4
+TS_DATA= ehdr.msb32 ehdr.lsb32 ehdr.msb64 ehdr.lsb64 \
+ newehdr.lsb32 newehdr.msb32
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf32_newehdr/ehdr.m4 b/test/libelf/tset/elf32_newehdr/ehdr.m4
new file mode 100644
index 0000000000000..fb3fbdd5ed849
--- /dev/null
+++ b/test/libelf/tset/elf32_newehdr/ehdr.m4
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: ehdr.m4 2054 2011-10-26 12:12:06Z jkoshy $
+ */
+
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+#include "elfts.h"
+
+define(`TS_EHDRFUNC',`_newehdr')
+define(`TS_EHDRSZ',`32')
+include(`ehdr_template.m4')
+
+include(`newehdr_template.m4')
diff --git a/test/libelf/tset/elf32_xlatetof/Makefile b/test/libelf/tset/elf32_xlatetof/Makefile
new file mode 100644
index 0000000000000..df8dcc70bd4d5
--- /dev/null
+++ b/test/libelf/tset/elf32_xlatetof/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1080 2010-08-10 14:52:44Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= xlate.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf32_xlatetof/xlate.m4 b/test/libelf/tset/elf32_xlatetof/xlate.m4
new file mode 100644
index 0000000000000..65e5f195e187d
--- /dev/null
+++ b/test/libelf/tset/elf32_xlatetof/xlate.m4
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2006,2010 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: xlate.m4 2206 2011-11-25 11:41:01Z jkoshy $
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+
+#include "elfts.h"
+
+include(`elfts.m4')
+
+define(`TPFNNAME',`elf32_xlatetof')
+
+include(`xlate_template.m4')
+
+Xlate_TestConversions()
+Xlate_TestConversionsSharedBuffer()
+
+Xlate_TestBadArguments()
+Xlate_TestBadBuffers()
diff --git a/test/libelf/tset/elf32_xlatetom/Makefile b/test/libelf/tset/elf32_xlatetom/Makefile
new file mode 100644
index 0000000000000..df8dcc70bd4d5
--- /dev/null
+++ b/test/libelf/tset/elf32_xlatetom/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1080 2010-08-10 14:52:44Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= xlate.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf32_xlatetom/xlate.m4 b/test/libelf/tset/elf32_xlatetom/xlate.m4
new file mode 100644
index 0000000000000..941eb31398630
--- /dev/null
+++ b/test/libelf/tset/elf32_xlatetom/xlate.m4
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2006,2010 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: xlate.m4 2206 2011-11-25 11:41:01Z jkoshy $
+ */
+
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+
+#include "elfts.h"
+
+include(`elfts.m4')
+
+define(`TPFNNAME',`elf32_xlatetom')
+
+include(`xlate_template.m4')
+
+Xlate_TestConversions()
+Xlate_TestConversionsSharedBuffer()
+
+Xlate_TestBadArguments()
+Xlate_TestBadBuffers()
diff --git a/test/libelf/tset/elf64_getehdr/Makefile b/test/libelf/tset/elf64_getehdr/Makefile
new file mode 100644
index 0000000000000..e8bb49ad4d25a
--- /dev/null
+++ b/test/libelf/tset/elf64_getehdr/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= ehdr.m4
+TS_YAML= ehdr
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf64_getehdr/ehdr.m4 b/test/libelf/tset/elf64_getehdr/ehdr.m4
new file mode 100644
index 0000000000000..3cda7e2220063
--- /dev/null
+++ b/test/libelf/tset/elf64_getehdr/ehdr.m4
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: ehdr.m4 2054 2011-10-26 12:12:06Z jkoshy $
+ */
+
+#include <sys/cdefs.h>
+
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+#include "elfts.h"
+
+define(`TS_EHDRFUNC',`_getehdr')
+define(`TS_EHDRSZ',`64')
+include(`ehdr_template.m4')
diff --git a/test/libelf/tset/elf64_getphdr/Makefile b/test/libelf/tset/elf64_getphdr/Makefile
new file mode 100644
index 0000000000000..920c35c320a72
--- /dev/null
+++ b/test/libelf/tset/elf64_getphdr/Makefile
@@ -0,0 +1,9 @@
+# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= phdr.m4
+TS_DATA= ehdr.lsb64 ehdr.msb64 \
+ phdr.lsb32 phdr.msb32 phdr.msb64 phdr.lsb64
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf64_getphdr/phdr.m4 b/test/libelf/tset/elf64_getphdr/phdr.m4
new file mode 100644
index 0000000000000..fbb6154d25836
--- /dev/null
+++ b/test/libelf/tset/elf64_getphdr/phdr.m4
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2006 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: phdr.m4 2054 2011-10-26 12:12:06Z jkoshy $
+ */
+
+#include <sys/cdefs.h>
+
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+#include "elfts.h"
+
+#define TS_PHDRFUNC _getphdr
+#define TS_PHDRSZ 64
+#include "phdr_template.c"
diff --git a/test/libelf/tset/elf64_getshdr/Makefile b/test/libelf/tset/elf64_getshdr/Makefile
new file mode 100644
index 0000000000000..345c020e73cf6
--- /dev/null
+++ b/test/libelf/tset/elf64_getshdr/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1080 2010-08-10 14:52:44Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= shdr.m4
+TS_DATA= shdr.msb64 shdr.lsb64
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf64_getshdr/shdr.m4 b/test/libelf/tset/elf64_getshdr/shdr.m4
new file mode 100644
index 0000000000000..ed877833df0e5
--- /dev/null
+++ b/test/libelf/tset/elf64_getshdr/shdr.m4
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2006 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: shdr.m4 223 2008-08-10 15:40:06Z jkoshy $
+ */
+
+#include <sys/mman.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+
+#include "elfts.h"
+
+IC_REQUIRES_VERSION_INIT();
+
+include(`elfts.m4')
+
+include(`getshdr.m4')
+
+TP_NULL(64)
+
+TC_MAKE_REF_SHDR(64)
+TP_SHDR(64,lsb)
+TP_SHDR(64,msb)
+
+
diff --git a/test/libelf/tset/elf64_newehdr/Makefile b/test/libelf/tset/elf64_newehdr/Makefile
new file mode 100644
index 0000000000000..88ccf4d1791b3
--- /dev/null
+++ b/test/libelf/tset/elf64_newehdr/Makefile
@@ -0,0 +1,9 @@
+# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= ehdr.m4
+TS_DATA= ehdr.msb64 ehdr.lsb64 ehdr.msb32 ehdr.lsb32 \
+ newehdr.lsb64 newehdr.msb64
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf64_newehdr/ehdr.m4 b/test/libelf/tset/elf64_newehdr/ehdr.m4
new file mode 100644
index 0000000000000..a1ee794f1fc5d
--- /dev/null
+++ b/test/libelf/tset/elf64_newehdr/ehdr.m4
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: ehdr.m4 2054 2011-10-26 12:12:06Z jkoshy $
+ */
+
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+#include "elfts.h"
+
+define(`TS_EHDRFUNC',`_newehdr')
+define(`TS_EHDRSZ',`64')
+include(`ehdr_template.m4')
+
+include(`newehdr_template.m4')
diff --git a/test/libelf/tset/elf64_xlatetof/Makefile b/test/libelf/tset/elf64_xlatetof/Makefile
new file mode 100644
index 0000000000000..df8dcc70bd4d5
--- /dev/null
+++ b/test/libelf/tset/elf64_xlatetof/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1080 2010-08-10 14:52:44Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= xlate.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf64_xlatetof/xlate.m4 b/test/libelf/tset/elf64_xlatetof/xlate.m4
new file mode 100644
index 0000000000000..a4c405bc5c666
--- /dev/null
+++ b/test/libelf/tset/elf64_xlatetof/xlate.m4
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2006,2010 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: xlate.m4 2206 2011-11-25 11:41:01Z jkoshy $
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+
+#include "elfts.h"
+
+include(`elfts.m4')
+
+define(`TPFNNAME',`elf64_xlatetof')
+
+include(`xlate_template.m4')
+
+Xlate_TestConversions()
+Xlate_TestConversionsSharedBuffer()
+
+Xlate_TestBadArguments()
+Xlate_TestBadBuffers()
diff --git a/test/libelf/tset/elf64_xlatetom/Makefile b/test/libelf/tset/elf64_xlatetom/Makefile
new file mode 100644
index 0000000000000..df8dcc70bd4d5
--- /dev/null
+++ b/test/libelf/tset/elf64_xlatetom/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1080 2010-08-10 14:52:44Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= xlate.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf64_xlatetom/xlate.m4 b/test/libelf/tset/elf64_xlatetom/xlate.m4
new file mode 100644
index 0000000000000..2b6799f2c5206
--- /dev/null
+++ b/test/libelf/tset/elf64_xlatetom/xlate.m4
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2006,2010 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: xlate.m4 2206 2011-11-25 11:41:01Z jkoshy $
+ */
+
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+
+#include "elfts.h"
+
+include(`elfts.m4')
+
+define(`TPFNNAME',`elf64_xlatetom')
+
+include(`xlate_template.m4')
+
+Xlate_TestConversions()
+Xlate_TestConversionsSharedBuffer()
+
+Xlate_TestBadArguments()
+Xlate_TestBadBuffers()
diff --git a/test/libelf/tset/elf_begin/Makefile b/test/libelf/tset/elf_begin/Makefile
new file mode 100644
index 0000000000000..d5c675cd04493
--- /dev/null
+++ b/test/libelf/tset/elf_begin/Makefile
@@ -0,0 +1,23 @@
+# $Id: Makefile 2933 2013-03-30 01:33:02Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= begin.m4
+TS_DATA= check_elf.msb32 check_elf.lsb32 check_elf.msb64 \
+ check_elf.lsb64 a.ar a-bsd.ar a.o zero
+CLEANFILES+= a.c
+
+a.c: .SILENT
+ echo "int dummy;" > a.c
+
+a.ar: a.o .SILENT
+ ${AR} crv ${.TARGET} ${.ALLSRC} > /dev/null
+
+a-bsd.ar: a.o .SILENT
+ rm -f ${.TARGET}
+ ${ELFTOOLCHAIN_AR} -F bsd -crv ${.TARGET} ${.ALLSRC} > /dev/null
+
+zero: .SILENT
+ rm -f ${.TARGET}; touch ${.TARGET}
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_begin/begin.m4 b/test/libelf/tset/elf_begin/begin.m4
new file mode 100644
index 0000000000000..9a282eb3f7462
--- /dev/null
+++ b/test/libelf/tset/elf_begin/begin.m4
@@ -0,0 +1,636 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: begin.m4 2933 2013-03-30 01:33:02Z jkoshy $
+ */
+
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+
+#include "elfts.h"
+
+include(`elfts.m4')
+
+define(`TS_ARFILE_BSD',`"a-bsd.ar"')
+define(`TS_ARFILE_SVR4',`"a.ar"')
+
+/*
+ * Test the `elf_begin' entry point.
+ */
+
+/*
+ * Calling elf_begin() before elf_version() results in ELF_E_SEQUENCE.
+ * Note that these test cases should run as a separate invocation than
+ * the others since they need to be run before elf_version() is called.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcSequenceUninitialized$1(void)
+{
+ Elf *e;
+ int error, result;
+
+ TP_ANNOUNCE("elf_version() needs to be set before "
+ "using the elf_begin($1) API.");
+
+ result = TET_PASS;
+ if ((e = elf_begin(-1, ELF_C_$1, NULL)) != NULL ||
+ (error = elf_errno()) != ELF_E_SEQUENCE)
+ TP_FAIL("ELF_C_$1: e=%p error=%d \"%s\".", (void *) e, error,
+ elf_errmsg(error));
+
+ tet_result(result);
+}')
+
+FN(`NULL')
+FN(`READ')
+FN(`WRITE')
+FN(`RDWR')
+
+void
+tcCmdInvalid(void)
+{
+ Elf *e;
+ int c, error, result;
+
+ TP_ANNOUNCE("An invalid cmd value returns ELF_E_ARGUMENT.");
+
+ TP_SET_VERSION();
+
+ result = TET_PASS;
+ for (c = ELF_C_NULL-1; c <= ELF_C_NUM; c++) {
+ if (c == ELF_C_READ || c == ELF_C_WRITE || c == ELF_C_RDWR ||
+ c == ELF_C_NULL)
+ continue;
+ if ((e = elf_begin(-1, c, NULL)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("cmd=%d: e=%p error=%d .", c,
+ (void *) e, error);
+ break;
+ }
+ }
+
+ done:
+ tet_result(result);
+}
+
+void
+tcCmdNull(void)
+{
+ Elf *e;
+ int result;
+
+ TP_ANNOUNCE("cmd == ELF_C_NULL returns NULL.");
+
+ TP_SET_VERSION();
+
+ result = (e = elf_begin(-1, ELF_C_NULL, NULL)) != NULL ? TET_FAIL :
+ TET_PASS;
+
+ done:
+ tet_result(result);
+}
+
+
+/*
+ * Verify that opening non-regular files fail with ELF_E_ARGUMENT
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcNonRegular$1(void)
+{
+ Elf *e;
+ int error, fd, result;
+
+ e = NULL;
+ fd = -1;
+ result = TET_FAIL;
+
+ TP_ANNOUNCE("opening a $3 fails with ELF_E_ARGUMENT.");
+
+ TP_SET_VERSION();
+
+ if ((fd = open("$2", O_RDONLY)) < 0) {
+ TP_UNRESOLVED("open \"$2\" failed: %s", strerror(errno));
+ goto done;
+ }
+
+ e = elf_begin(fd, ELF_C_READ, NULL);
+
+ if (e == NULL && (error = elf_errno()) == ELF_E_ARGUMENT)
+ result = TET_PASS; /* Verify the error. */
+
+ done:
+ if (e)
+ elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(`DeviceFile', `/dev/null', `device file')
+FN(`Directory', `.', `directory')
+
+/*
+ * Verify that for command modes ELF_C_READ and ELF_C_RDWR, opening
+ * a zero sized regular file fails with ELF_E_ARGUMENT.
+ */
+
+undefine(`FN',`ZERO')
+define(`ZERO',`"zero"')
+define(`FN',`
+void
+tcZero$1(void)
+{
+ Elf *e;
+ int error, fd, result;
+
+ e = NULL;
+ fd = -1;
+ result = TET_FAIL;
+
+ TP_ANNOUNCE("opening an zero-sized file in mode ELF_C_$1 fails "
+ "with ELF_E_ARGUMENT.");
+
+ TP_SET_VERSION();
+
+ if ((fd = open(ZERO, O_RDONLY)) < 0) {
+ TP_UNRESOLVED("open \"$2\" failed: %s", strerror(errno));
+ goto done;
+ }
+
+ e = elf_begin(fd, ELF_C_$1, NULL);
+
+ if (e == NULL && (error = elf_errno()) == ELF_E_ARGUMENT)
+ result = TET_PASS; /* Verify the error. */
+
+ done:
+ if (e)
+ elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(`READ')
+FN(`RDWR')
+
+#define TEMPLATE "TCXXXXXX"
+#define FILENAME_SIZE 16
+char filename[FILENAME_SIZE];
+
+int
+setup_tempfile(void)
+{
+ int fd;
+
+ (void) strncpy(filename, TEMPLATE, sizeof(filename));
+ filename[sizeof(filename) - 1] = '\0';
+
+ if ((fd = mkstemp(filename)) < 0 ||
+ write(fd, TEMPLATE, sizeof(TEMPLATE)) < 0)
+ return 0;
+
+ (void) close(fd);
+
+ return 1;
+
+}
+
+void
+cleanup_tempfile(void)
+{
+ (void) unlink(filename);
+}
+
+
+define(`FN',`
+void
+tcCmdWriteFdRead_$1(void)
+{
+ Elf *e;
+ Elf$1_Ehdr *eh;
+ int error, fd, result;
+
+ TP_ANNOUNCE("($1): cmd == ELF_C_WRITE fails with a non-writable FD.");
+
+ TP_SET_VERSION();
+
+ if (setup_tempfile() == 0 ||
+ (fd = open(filename, O_RDONLY, 0)) < 0) {
+ TP_UNRESOLVED("setup failed: %s", strerror(errno));
+ goto done;
+ }
+
+ result = TET_PASS;
+ error = -1;
+
+ if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) {
+ TP_UNRESOLVED("elf_begin() failed: %s", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((eh = elf$1_getehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_getehdr() failed: %s", elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Verify that elf_update() fails with the appropriate error. */
+ if (elf_update(e, ELF_C_WRITE) >= 0) {
+ TP_FAIL("fn=%s, elf_update() succeeded unexpectedly.",
+ filename);
+ goto done;
+ }
+
+ if ((error = elf_errno()) != ELF_E_IO)
+ TP_FAIL("fn=%s, error=%d \"%s\".", filename, error,
+ elf_errmsg(error));
+
+ done:
+ cleanup_tempfile();
+ tet_result(result);
+}')
+
+FN(32)
+FN(64)
+
+void
+tcCmdWriteFdRdwr(void)
+{
+ Elf *e;
+ int error, fd, result;
+
+ TP_ANNOUNCE("cmd == ELF_C_WRITE on an 'rdwr' FD passes.");
+
+ TP_SET_VERSION();
+
+ if (setup_tempfile() == 0 ||
+ (fd = open(filename, O_RDWR, 0)) < 0) {
+ TP_UNRESOLVED("setup failed: %s", strerror(errno));
+ goto done;
+ }
+
+ result = TET_PASS;
+ error = -1;
+ if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) {
+ error = elf_errno();
+ TP_FAIL("fn=%s, error=%d \"%s\"", filename, error,
+ elf_errmsg(error));
+ }
+
+ done:
+ cleanup_tempfile();
+ tet_result(result);
+}
+
+void
+tcCmdWriteFdWrite(void)
+{
+ Elf *e;
+ int error, fd, result;
+
+ TP_ANNOUNCE("cmd == ELF_C_WRITE on write-only FD passes.");
+
+ TP_SET_VERSION();
+
+ if (setup_tempfile() == 0 ||
+ (fd = open(filename, O_WRONLY, 0)) < 0) {
+ TP_UNRESOLVED("setup failed: %s", strerror(errno));
+ goto done;
+ }
+
+ result = TET_PASS;
+ error = -1;
+ if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) {
+ error = elf_errno();
+ TP_FAIL("fn=%s, error=%d \"%s\"", filename,
+ error, elf_errmsg(error));
+ }
+
+ done:
+ cleanup_tempfile();
+ tet_result(result);
+}
+
+void
+tcCmdWriteParamIgnored(void)
+{
+ Elf *e, *t;
+ int error, fd, fd1, result;
+
+ TP_ANNOUNCE("cmd == ELF_C_WRITE ignores the last parameter.");
+
+ TP_SET_VERSION();
+
+ if (setup_tempfile() == 0 ||
+ (fd = open(filename, O_WRONLY, 0)) < 0 ||
+ (fd1 = open(filename, O_RDONLY, 0)) < 0) {
+ TP_UNRESOLVED("setup failed: %s", strerror(errno));
+ goto done;
+ }
+
+ if ((t = elf_begin(fd1, ELF_C_READ, NULL)) == NULL) {
+ TP_UNRESOLVED("elf_begin() failed unexpectedly: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ result = TET_PASS;
+ error = -1;
+ if ((e = elf_begin(fd, ELF_C_WRITE, t)) == NULL) {
+ TP_FAIL("elf_begin() failed: \"%s\".", elf_errmsg(-1));
+ }
+
+ done:
+ cleanup_tempfile();
+ tet_result(result);
+}
+
+
+/*
+ * Check that opening various classes/endianness of ELF files
+ * passes.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcElfOpen$1$2(void)
+{
+ Elf *e;
+ int fd, result;
+ char *p;
+
+ TP_ANNOUNCE("open(ELFCLASS$1,ELFDATA2`'TOUPPER($2)) succeeds.");
+
+ TP_SET_VERSION();
+
+ fd = -1;
+ e = NULL;
+ result = TET_UNRESOLVED;
+
+ if ((fd = open ("check_elf.$2$1", O_RDONLY)) < 0) {
+ TP_UNRESOLVED("open() failed: %s.", strerror(errno));
+ goto done;
+ }
+
+ if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
+ TP_FAIL("elf_begin() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((p = elf_getident(e, NULL)) == NULL) {
+ TP_FAIL("elf_getident() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if (p[EI_CLASS] != ELFCLASS$1 ||
+ p[EI_DATA] != ELFDATA2`'TOUPPER($2))
+ TP_FAIL("class %d expected %d, data %d expected %d.",
+ p[EI_CLASS], ELFCLASS$1, p[EI_DATA], ELFDATA2`'TOUPPER($2));
+ else
+ result = TET_PASS;
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+/*
+ * Check an `fd' mismatch is detected.
+ */
+void
+tcFdMismatch(void)
+{
+ Elf *e, *e2;
+ int error, fd, result;
+
+ TP_ANNOUNCE("an fd mismatch is detected.");
+
+ TP_SET_VERSION();
+
+ e = e2 = NULL;
+ fd = -1;
+
+ if ((fd = open("check_elf.msb32", O_RDONLY)) < 0 ||
+ (e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
+ TP_UNRESOLVED("open(check_elf) failed: fd=%d.", fd);
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ if ((e2 = elf_begin(fd+1, ELF_C_READ, e)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("elf_begin(%d+1) -> %p, error=%d \"%s\".", fd,
+ (void *) e2, error, elf_errmsg(error));
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (e2)
+ (void) elf_end(e2);
+ if (fd >= 0)
+ (void) close(fd);
+ tet_result(result);
+}
+
+undefine(`ARFN')
+define(`ARFN',`
+/*
+ * Check that an $1-style AR archive detects a cmd mismatch.
+ */
+void
+tcArCmdMismatchRDWR_$1(void)
+{
+ Elf *e, *e2;
+ int error, fd, result;
+
+ TP_ANNOUNCE("($1): a cmd mismatch is detected.");
+
+ TP_SET_VERSION();
+
+ result = TET_UNRESOLVED;
+ e = e2 = NULL;
+ fd = -1;
+
+ /* Open the archive with ELF_C_READ. */
+ _TS_OPEN_FILE(e, TS_ARFILE_$1, ELF_C_READ, fd, goto done;);
+
+ /* Attempt to iterate through it with ELF_C_RDWR. */
+ result = TET_PASS;
+ if ((e2 = elf_begin(fd, ELF_C_RDWR, e)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("e2=%p error=%d \"%s\".", (void *) e2,
+ error, elf_errmsg(error));
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (e2)
+ (void) elf_end(e2);
+ if (fd >= 0)
+ (void) close(fd);
+ tet_result(result);
+}
+
+/*
+ * Check that a member is correctly retrieved for $1-style archives.
+ */
+void
+tcArRetrieval_$1(void)
+{
+ Elf *e, *e1;
+ int fd, result;
+ Elf_Kind k;
+
+ TP_ANNOUNCE("($1): an archive member is correctly retrieved.");
+
+ TP_SET_VERSION();
+
+ e = e1 = NULL;
+ fd = -1;
+
+ _TS_OPEN_FILE(e, TS_ARFILE_$1, ELF_C_READ, fd, goto done;);
+
+ result = TET_PASS;
+ if ((e1 = elf_begin(fd, ELF_C_READ, e)) == NULL) {
+ TP_FAIL("elf_begin() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((k = elf_kind(e1)) != ELF_K_ELF)
+ TP_FAIL("kind %d, expected %d.", k, ELF_K_ELF);
+
+ done:
+ if (e1)
+ (void) elf_end(e1);
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ tet_result(result);
+}
+
+/*
+ * Check opening of ar(1) archives opened with elf_memory().
+ */
+
+void
+tcArMemoryFdIgnored_$1(void)
+{
+ Elf *e, *e1;
+ int fd, result;
+ Elf_Kind k;
+ struct stat sb;
+ char *b;
+
+ TP_ANNOUNCE("($1): The fd value is ignored for archives opened "
+ "with elf_memory().");
+
+ TP_SET_VERSION();
+
+ e = e1 = NULL;
+ b = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ /*
+ * First, populate a memory area with the contents of
+ * an ar(1) archive.
+ */
+
+ if ((fd = open(TS_ARFILE_$1, O_RDONLY)) < 0) {
+ TP_UNRESOLVED("open of \"" TS_ARFILE_$1 "\" failed: %s",
+ strerror(errno));
+ goto done;
+ }
+
+ if (fstat(fd, &sb) < 0) {
+ TP_UNRESOLVED("fstat failed: %s", strerror(errno));
+ goto done;
+ }
+
+ if ((b = malloc(sb.st_size)) == NULL) {
+ TP_UNRESOLVED("malloc failed: %s", strerror(errno));
+ goto done;
+ }
+
+ if (read(fd, b, sb.st_size) != sb.st_size) {
+ /* Deal with ERESTART? */
+ TP_UNRESOLVED("read failed: %s", strerror(errno));
+ goto done;
+ }
+
+ if ((e = elf_memory(b, sb.st_size)) == NULL) {
+ TP_FAIL("elf_memory failed: %s", elf_errmsg(-1));
+ goto done;
+ }
+
+ /*
+ * Verify that the fd value is ignored for this case.
+ */
+ if ((e1 = elf_begin(-2, ELF_C_READ, e)) == NULL) {
+ TP_FAIL("elf_begin() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((k = elf_kind(e1)) != ELF_K_ELF)
+ TP_FAIL("kind %d, expected %d.", k, ELF_K_ELF);
+
+ result = TET_PASS;
+
+ done:
+ if (b)
+ free(b);
+ if (e1)
+ (void) elf_end(e1);
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ tet_result(result);
+}
+')
+
+ARFN(`BSD')
+ARFN(`SVR4')
diff --git a/test/libelf/tset/elf_cntl/Makefile b/test/libelf/tset/elf_cntl/Makefile
new file mode 100644
index 0000000000000..2f74dac7e7838
--- /dev/null
+++ b/test/libelf/tset/elf_cntl/Makefile
@@ -0,0 +1,16 @@
+# $Id: Makefile 1118 2010-08-22 08:21:53Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= cntl.m4
+TS_DATA= a.ar
+CLEANFILES+= a.c a.o
+
+a.c: .SILENT
+ echo "int foobar;" > ${.TARGET}
+
+a.ar: a.o .SILENT
+ rm -f ${.TARGET}
+ ${AR} crv ${.TARGET} ${.ALLSRC} > /dev/null
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_cntl/cntl.m4 b/test/libelf/tset/elf_cntl/cntl.m4
new file mode 100644
index 0000000000000..33b12f7d0b3bf
--- /dev/null
+++ b/test/libelf/tset/elf_cntl/cntl.m4
@@ -0,0 +1,217 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: cntl.m4 2191 2011-11-21 08:34:02Z jkoshy $
+ */
+
+#include <sys/types.h>
+
+#include <libelf.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+IC_REQUIRES_VERSION_INIT();
+
+include(`elfts.m4')
+
+/*
+ * Test the `elf_cntl' API.
+ */
+
+static char elf_file[] = "\177ELF\001\001\001 \001\000\000\000\000"
+ "\000\000\000\001\000\003\000\001\000\000\000\357\276\255\336"
+ "\000\000\000\000\000\000\000\000\003\000\000\0004\000 \000"
+ "\000\000(\000\000\000\000\000";
+
+/*
+ * A NULL elf parameter causes elf_cntl() to fail.
+ */
+void
+tcInvalidNull(void)
+{
+ int error, result, ret;
+
+ TP_ANNOUNCE("elf_cntl(NULL,...) fails with ELF_E_ARGUMENT.");
+
+ TP_CHECK_INITIALIZATION();
+
+ ret = error = 0;
+ result = TET_PASS;
+ if ((ret = elf_cntl(NULL, ELF_C_FDREAD)) != -1 ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("ret=%d, error=%d \"%s\".", ret, error);
+
+ tet_result(result);
+}
+
+/*
+ * Invalid `cmd' values are rejected.
+ */
+void
+tcInvalidInvalid(void)
+{
+ Elf *e;
+ int c, error, result, ret;
+
+ TP_ANNOUNCE("elf_cntl(e,[INVALID]) fails with ELF_E_ARGUMENT.");
+
+ TP_CHECK_INITIALIZATION();
+
+ TS_OPEN_MEMORY(e, elf_file);
+
+ ret = error = 0;
+ result = TET_PASS;
+ for (c = ELF_C_FIRST-1; c <= ELF_C_LAST; c++) {
+ if (c == ELF_C_FDDONE || c == ELF_C_FDREAD)
+ continue;
+ if ((ret = elf_cntl(e, c)) != -1 ||
+ (error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("returned (%d) / error (%d) for "
+ "c = %d.", ret, error, c);
+ break;
+ }
+ }
+
+ (void) elf_end(e);
+ tet_result(result);
+}
+
+/*
+ * Calling elf_cntl(FDREAD) for files opened in read mode.
+ */
+void
+tcReadFDREAD(void)
+{
+ Elf *e;
+ int result;
+
+ TP_ANNOUNCE("elf_cntl(e,FDREAD) for a read-only descriptor succeeds.");
+
+ TP_CHECK_INITIALIZATION();
+
+ TS_OPEN_MEMORY(e, elf_file);
+
+ result = TET_PASS;
+ if (elf_cntl(e, ELF_C_FDREAD) != 0)
+ TP_FAIL("elf_errmsg=\"%s\".", elf_errmsg(-1));
+
+ (void) elf_end(e);
+ tet_result(result);
+}
+
+static char pathname[PATH_MAX];
+
+/*
+ * elf_cntl(FDREAD) doesn't make sense for a descriptor opened
+ * for writing.
+ */
+void
+tcWriteFDREAD(void)
+{
+ Elf *e;
+ int err, fd, result, ret;
+
+ TP_ANNOUNCE("elf_cntl(e,FDREAD) for a descriptor opened for write "
+ "fails with ELF_E_MODE.");
+
+ TP_CHECK_INITIALIZATION();
+
+ (void) strncpy(pathname, "/tmp/TCXXXXXX", sizeof(pathname));
+ pathname[sizeof(pathname) - 1] = '\0';
+
+ if ((fd = mkstemp(pathname)) == -1 ||
+ (e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) {
+ TP_UNRESOLVED("elf_begin(%d,WRITE,NULL) failed.");
+ goto done;
+ }
+
+ result = TET_PASS;
+ if ((ret = elf_cntl(e, ELF_C_FDREAD)) != -1 ||
+ (err = elf_errno()) != ELF_E_MODE)
+ TP_FAIL("ret (%d) error (%d).", ret, err);
+
+ done:
+ (void) elf_end(e);
+ (void) unlink(pathname);
+ tet_result(result);
+}
+
+/*
+ * An elf_cntl(FDDONE) causes a subsequent elf_update(WRITE) to fail.
+ */
+
+void
+tcWriteFDDONE(void)
+{
+ Elf *e;
+ Elf32_Ehdr *eh;
+ int err, fd, result;
+ off_t ret;
+
+ TP_ANNOUNCE("elf_cntl(e,FDDONE) makes a subsequent "
+ "elf_update(ELF_C_WRITE) fail with ELF_E_SEQUENCE.");
+
+ TP_CHECK_INITIALIZATION();
+
+ (void) strncpy(pathname, "/tmp/TCXXXXXX", sizeof(pathname));
+ pathname[sizeof(pathname) - 1] = '\0';
+
+ if ((fd = mkstemp(pathname)) == -1 ||
+ (e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) {
+ TP_UNRESOLVED("elf_begin(%d,WRITE,NULL) failed.");
+ goto done;
+ }
+
+ if (elf_cntl(e, ELF_C_FDDONE) == -1) {
+ TP_FAIL("elf_cntl(e,FDONE) failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if (elf_flagelf(e, ELF_C_SET, ELF_F_DIRTY) == 0) {
+ TP_UNRESOLVED("elf_flagelf() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((eh = elf32_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf32_newehdr() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ result = TET_PASS;
+ if ((ret = elf_update(e, ELF_C_WRITE)) != (off_t) -1 ||
+ (err = elf_errno()) != ELF_E_SEQUENCE)
+ TP_FAIL("ret (%jd) err (%d).", (uint64_t) ret, err);
+
+ done:
+ tet_result(result);
+
+ (void) elf_end(e);
+ (void) unlink(pathname);
+}
diff --git a/test/libelf/tset/elf_end/Makefile b/test/libelf/tset/elf_end/Makefile
new file mode 100644
index 0000000000000..b2c6368768616
--- /dev/null
+++ b/test/libelf/tset/elf_end/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1348 2011-01-01 15:14:36Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= end.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_end/end.m4 b/test/libelf/tset/elf_end/end.m4
new file mode 100644
index 0000000000000..ef2972eb1ded4
--- /dev/null
+++ b/test/libelf/tset/elf_end/end.m4
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 2006,2010 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: end.m4 1349 2011-01-01 15:18:43Z jkoshy $
+ */
+
+include(`elfts.m4')
+
+#include <libelf.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * Test the `elf_end' entry point.
+ */
+
+void
+tcEndNullOk(void)
+{
+ TP_ANNOUNCE("a NULL argument is allowed.");
+
+ tet_result(elf_end(NULL) == 0 ? TET_PASS : TET_FAIL);
+}
+
+char data[] = "0xDEADC0DE";
+
+void
+tcBeginEndPair(void)
+{
+ Elf *e;
+
+ TP_ANNOUNCE("a single begin/end pair works");
+
+ TP_CHECK_INITIALIZATION();
+
+ TS_OPEN_MEMORY(e,data);
+
+ tet_result (elf_end(e) == 0 ? TET_PASS : TET_FAIL);
+}
+
+void
+tcNestedCount(void)
+{
+ int r1, r2;
+ Elf *e, *e1;
+
+ TP_ANNOUNCE("begin/end pairs nest correctly");
+
+ TP_CHECK_INITIALIZATION();
+
+ TS_OPEN_MEMORY(e,data);
+
+ if ((e1 = elf_begin(-1, ELF_C_READ, e)) != e) {
+ tet_result(TET_UNRESOLVED);
+ return;
+ }
+
+ if ((r1 = elf_end(e1)) != 1 ||
+ (r2 = elf_end(e)) != 0) {
+ tet_printf("fail: r1=%d r2=%d.", r1, r2);
+ tet_result(TET_FAIL);
+ return;
+ }
+
+ tet_result(TET_PASS);
+}
+
+/*
+ * TODO
+ * - closing a member of an archive should decrement the parent's activation
+ * count.
+ * - opening a member of an archive should increment the parent's activation
+ * count.
+ * - What do we do about out of order elf_end()'s on archives and members.
+ */
diff --git a/test/libelf/tset/elf_errmsg/Makefile b/test/libelf/tset/elf_errmsg/Makefile
new file mode 100644
index 0000000000000..1b92d857ae702
--- /dev/null
+++ b/test/libelf/tset/elf_errmsg/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1350 2011-01-01 15:29:05Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= errmsg.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_errmsg/errmsg.m4 b/test/libelf/tset/elf_errmsg/errmsg.m4
new file mode 100644
index 0000000000000..c5d1d17185858
--- /dev/null
+++ b/test/libelf/tset/elf_errmsg/errmsg.m4
@@ -0,0 +1,153 @@
+/*-
+ * Copyright (c) 2006,2010,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: errmsg.m4 2191 2011-11-21 08:34:02Z jkoshy $
+ */
+
+include(`elfts.m4')
+
+#include <libelf.h>
+#include <string.h>
+
+#include "tet_api.h"
+
+/*
+ * Test the `elf_errmsg' entry point.
+ */
+
+/*
+ * Assertion: the function returns NULL if the argument is zero and
+ * there is no pending error in the library.
+ */
+void
+tcZeroNoerror(void)
+{
+
+ TP_ANNOUNCE("returns NULL with zero & no current error");
+
+ (void) elf_errno(); /* discard current error number */
+
+ if (elf_errmsg(0) == NULL)
+ tet_result(TET_PASS);
+ else
+ tet_result(TET_FAIL);
+}
+
+/*
+ * An error value of -1 should return non-NULL
+ */
+
+define(`NO_ERROR_MESSAGE',`"No Error"')dnl Needs to match the string in "libelf/elf_errmsg.c".
+
+void
+tcMinusoneNoerror(void)
+{
+ int result;
+ const char *msg;
+
+ TP_ANNOUNCE("returns non-null for arg -1 & no current error");
+
+ (void) elf_errno(); /* discard stored error */
+
+ result = TET_UNRESOLVED;
+
+ msg = elf_errmsg(-1);
+ if (msg == NULL) {
+ TP_FAIL("null return from elf_errmsg()");
+ goto done;
+ }
+
+ if (strcmp(msg, NO_ERROR_MESSAGE)) {
+ TP_FAIL("unexpected message \"%s\"", msg);
+ goto done;
+ }
+
+ result = TET_PASS;
+
+done:
+ tet_result(result);
+}
+
+/*
+ * Assertion: All error numbers from 1..NUM return a non-null string.
+ */
+
+void
+tcCheckAllValidErrorMessages(void)
+{
+ int n, result;
+ const char *msg;
+
+ TP_ANNOUNCE("returns non-null for all valid error numbers");
+
+ (void) elf_errno(); /* discard stored error */
+
+ result = TET_UNRESOLVED;
+
+ for (n = ELF_E_NONE+1; n < ELF_E_NUM; n++) {
+ if ((msg = elf_errmsg(n)) == NULL) {
+ TP_FAIL("null return from elf_errmsg()");
+ goto done;
+ }
+ }
+
+ result = TET_PASS;
+
+done:
+ tet_result(result);
+
+}
+
+/*
+ * Assertion: with an error pending, elf_errmsg(0) returns a non-NULL
+ * pointer.
+ */
+
+void
+tcNonNullWithErrorPending(void)
+{
+ int result, version;
+ const char *msg;
+
+ result = TET_UNRESOLVED;
+
+ TP_ANNOUNCE("non null error message is returned for a pending error");
+
+ /* Generate an error, e.g., ELF_E_VERSION. */
+ if ((version = elf_version(EV_CURRENT+1)) != EV_NONE) {
+ TP_UNRESOLVED("elf_version() returned %d", version);
+ goto done;
+ }
+
+ if ((msg = elf_errmsg(0)) == NULL) {
+ TP_FAIL("elf_errmsg() returned NULL");
+ goto done;
+ }
+
+ result = TET_PASS;
+
+done:
+ tet_result(result);
+}
diff --git a/test/libelf/tset/elf_errno/Makefile b/test/libelf/tset/elf_errno/Makefile
new file mode 100644
index 0000000000000..23153b464bdb9
--- /dev/null
+++ b/test/libelf/tset/elf_errno/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1343 2011-01-01 10:57:37Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= errno.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_errno/errno.m4 b/test/libelf/tset/elf_errno/errno.m4
new file mode 100644
index 0000000000000..b55ee96f98fab
--- /dev/null
+++ b/test/libelf/tset/elf_errno/errno.m4
@@ -0,0 +1,185 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: errno.m4 2191 2011-11-21 08:34:02Z jkoshy $
+ */
+
+include(`elfts.m4')
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+
+/*
+ * Test the `elf_errno' entry point.
+ *
+ * Specific errors expected from other elf_* APIs are tested in the test
+ * cases for those APIs.
+ *
+ * The tests here only check the behaviour of the elf_errno() API.
+ */
+
+/*
+ * Assertion: The initial value of the libraries error number is zero.
+ */
+
+void
+tcInitialValue(void)
+{
+ int err;
+
+ TP_ANNOUNCE("The initial error value must be zero.");
+ err = elf_errno();
+ tet_result(err == 0 ? TET_PASS : TET_FAIL);
+}
+
+/*
+ * Assertion: an elf_errno() call resets the stored error number.
+ */
+
+void
+tcReset(void)
+{
+ int err;
+
+ TP_ANNOUNCE("A pending error number must be reset by elf_errno().");
+
+ (void) elf_errno(); /* discard stored error */
+ err = elf_errno();
+ tet_result(err == 0 ? TET_PASS : TET_FAIL);
+}
+
+/*
+ * Assertion: elf_begin with cmd == ELF_C_NULL does not reset the
+ * error value.
+ */
+
+void
+tcNonResetWithNull(void)
+{
+ int error, fd, result;
+ Elf *e, *e1;
+
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = e1 = NULL;
+
+ TP_ANNOUNCE("a pending error number is not reset by "
+ "elf_begin(ELF_C_NULL).");
+
+ TP_SET_VERSION();
+
+ /* Force an error. */
+ if ((fd = open(".", O_RDONLY)) < 0) {
+ TP_UNRESOLVED("open(.) failed: %s", strerror(errno));
+ goto done;
+ }
+
+ if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) != NULL) {
+ TP_UNRESOLVED("elf_begin(ELF_C_WRITE) succeeded "
+ "unexpectedly.");
+ goto done;
+ }
+
+ /* Invoke an operation with ELF_C_NULL */
+ if ((e1 = elf_begin(fd, ELF_C_NULL, NULL)) != NULL) {
+ TP_FAIL("elf_begin(ELF_C_NULL) returned non-null (%p)",
+ (void *) e1);
+ goto done;
+ }
+
+ /* Recheck the old error. */
+ if ((error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("unexpected error %d \"%s\"", error,
+ elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+
+ if (e)
+ elf_end(e);
+ if (e1)
+ elf_end(e1);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}
+
+/*
+ * Assertion: elf_errno() retrieves the expected error, when one is pending.
+ */
+
+void
+tcExpectedErrorIsReturned(void)
+{
+ int error, fd, result;
+ Elf *e;
+
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ TP_ANNOUNCE("A pending error number is correctly returned.");
+
+ TP_SET_VERSION();
+
+ /* Force an error. */
+ if ((fd = open(".", O_RDONLY)) < 0) {
+ TP_UNRESOLVED("open(.) failed: %s", strerror(errno));
+ goto done;
+ }
+
+ if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) != NULL) {
+ TP_UNRESOLVED("elf_begin(ELF_C_WRITE) succeeded "
+ "unexpectedly.");
+ goto done;
+ }
+
+ /* Check the current error. */
+ if ((error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("unexpected error %d \"%s\"", error,
+ elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+
+ if (e)
+ elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}
diff --git a/test/libelf/tset/elf_fill/Makefile b/test/libelf/tset/elf_fill/Makefile
new file mode 100644
index 0000000000000..747220f526581
--- /dev/null
+++ b/test/libelf/tset/elf_fill/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1080 2010-08-10 14:52:44Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= fill.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_fill/fill.m4 b/test/libelf/tset/elf_fill/fill.m4
new file mode 100644
index 0000000000000..6d07891b9f081
--- /dev/null
+++ b/test/libelf/tset/elf_fill/fill.m4
@@ -0,0 +1,558 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: fill.m4 1696 2011-08-06 09:12:19Z jkoshy $
+ */
+
+#include <sys/mman.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+
+#include "elfts.h"
+
+IC_REQUIRES_VERSION_INIT();
+
+include(`elfts.m4')
+
+define(`TS_ALIGN', 512)
+define(`TS_FILLCHAR', `0xAB')
+define(`TS_OFFSET_1', 512)
+define(`TS_OFFSET_2', 1024)
+define(`TS_SHDR_OFFSET', 2048)
+
+/*
+ * Test the `elf_fill' entry point.
+ */
+
+static char testdata[] = {
+ 0xAA, 0xBB, 0xCC, 0xDD,
+ 0xEE, 0xFF, 0x99, 0x88
+};
+
+/*
+ * Check that gaps in the file are correctly filled with the
+ * specified fill character.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcDefaultLayout$2$1(void)
+{
+ Elf *e;
+ Elf$1_Ehdr *eh;
+ Elf$1_Shdr *sh;
+ Elf_Scn *scn;
+ Elf_Data *d;
+ int fd, result;
+ size_t fsz;
+ off_t rc;
+ unsigned char *p, *r;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("$2$1: elf_fill()/lib-layout fills gaps.");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+ r = NULL;
+
+ _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;);
+
+ /*
+ * We create an ELF file with a section with a 1K and 2K alignments
+ * and verify that the gaps are filled appropriately.
+ */
+
+ elf_fill(TS_FILLCHAR);
+
+ if ((eh = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ eh->e_ident[EI_DATA] = ELFDATA2$2;
+
+ /*
+ * Create the first section.
+ */
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_scn() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ sh->sh_type = SHT_PROGBITS;
+
+ (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
+
+ if ((d = elf_newdata(scn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ d->d_align = TS_ALIGN;
+ d->d_buf = testdata;
+ d->d_size = sizeof(testdata);
+ d->d_type = ELF_T_BYTE;
+
+ /*
+ * Create the second section.
+ */
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_scn() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ sh->sh_type = SHT_PROGBITS;
+
+ (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
+
+ if ((d = elf_newdata(scn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ d->d_align = TS_ALIGN;
+ d->d_buf = testdata;
+ d->d_size = sizeof(testdata);
+ d->d_type = ELF_T_BYTE;
+
+ if ((rc = elf_update(e, ELF_C_WRITE)) < 0) {
+ TP_UNRESOLVED("elf_update() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ (void) elf_end(e); e = NULL;
+ (void) close(fd); fd = -1;
+
+ /*
+ * Mmap() in the file and check that the contents match.
+ */
+
+ if ((fd = open(TS_NEWFILE, O_RDONLY, 0)) < 0) {
+ TP_UNRESOLVED("open() failed: %s.", strerror(errno));
+ goto done;
+ }
+
+ if ((r = mmap(NULL, (size_t) rc, PROT_READ, MAP_SHARED, fd,
+ (off_t) 0)) == MAP_FAILED) {
+ TP_UNRESOLVED("mmap() failed: %s.", strerror(errno));
+ goto done;
+ }
+
+ /* Check the first gap */
+ if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) {
+ TP_UNRESOLVED("elf$1_fsize(ELF_T_EHDR) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Section data would be placed at the next alignment boundary. */
+ for (p = r + fsz; p < r + TS_ALIGN; p++)
+ if (*p != TS_FILLCHAR) {
+ TP_FAIL("offset 0x%x [%d] != %d", p - r, *p,
+ TS_FILLCHAR);
+ goto done;
+ }
+
+ /* Check whether valid contents exist at first section offset. */
+ if (memcmp(r + TS_ALIGN, testdata, sizeof(testdata)) != 0) {
+ TP_FAIL("memcmp(first) failed.");
+ goto done;
+ }
+
+ /* Check the between sections. */
+ for (p = r + TS_ALIGN + sizeof(testdata); p < r + 2*TS_ALIGN; p++)
+ if (*p != TS_FILLCHAR) {
+ TP_FAIL("offset 0x%x [%d] != %d", p - r, *p,
+ TS_FILLCHAR);
+ goto done;
+ }
+
+ /* Check whether valid contents exist at second section offset. */
+ if (memcmp(r + 2*TS_ALIGN, testdata, sizeof(testdata)) != 0) {
+ TP_FAIL("memcmp(second) failed.");
+ goto done;
+ }
+
+ result = TET_PASS;
+ done:
+ if (r)
+ (void) munmap(r, rc);
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ unlink(TS_NEWFILE);
+ tet_result(result);
+}')
+
+FN(32,LSB)
+FN(32,MSB)
+FN(64,LSB)
+FN(64,MSB)
+
+
+/*
+ * Check that regions are filled correctly, for application specified
+ * layouts.
+ */
+define(`FN',`
+void
+tcAppLayout$2$1(void)
+{
+ Elf *e;
+ Elf$1_Ehdr *eh;
+ Elf$1_Shdr *sh;
+ Elf_Scn *scn;
+ Elf_Data *d;
+ int fd, result;
+ size_t fsz;
+ off_t rc;
+ unsigned char *p, *r;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("$2$1: elf_fill()/app-layout fills gaps.");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+ r = NULL;
+
+ _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;);
+
+ /*
+ * We create an ELF file with a section with a 1K and 2K alignments
+ * and verify that the gaps are filled appropriately.
+ */
+
+ elf_fill(TS_FILLCHAR);
+ if (elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT) != ELF_F_LAYOUT) {
+ TP_UNRESOLVED("elf_flagdata() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((eh = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ eh->e_ident[EI_DATA] = ELFDATA2$2;
+
+ /*
+ * Create the first section.
+ */
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_newscn() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ sh->sh_type = SHT_PROGBITS;
+ sh->sh_offset = TS_OFFSET_2;
+ sh->sh_addralign = 1;
+ sh->sh_size = sizeof(testdata);
+
+ (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
+ if ((d = elf_newdata(scn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ d->d_align = 1;
+ d->d_off = 0;
+ d->d_buf = testdata;
+ d->d_size = sizeof(testdata);
+ d->d_type = ELF_T_BYTE;
+
+ /*
+ * Create the second section, physically located BEFORE the
+ * first section.
+ */
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_scn() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ sh->sh_type = SHT_PROGBITS;
+ sh->sh_offset = TS_OFFSET_1;
+ sh->sh_addralign = 1;
+ sh->sh_size = sizeof(testdata);
+
+ (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
+
+ if ((d = elf_newdata(scn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ d->d_align = 1;
+ d->d_off = 0;
+ d->d_buf = testdata;
+ d->d_size = sizeof(testdata);
+ d->d_type = ELF_T_BYTE;
+
+ /*
+ * Position the section header after section data.
+ */
+ eh->e_shoff = TS_SHDR_OFFSET;
+
+ if ((rc = elf_update(e, ELF_C_WRITE)) < 0) {
+ TP_UNRESOLVED("elf_update() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ (void) elf_end(e); e = NULL;
+ (void) close(fd); fd = -1;
+
+ /*
+ * Mmap() in the file and check that the contents match.
+ */
+
+ if ((fd = open(TS_NEWFILE, O_RDONLY, 0)) < 0) {
+ TP_UNRESOLVED("open() failed: %s.", strerror(errno));
+ goto done;
+ }
+
+ if ((r = mmap(NULL, (size_t) rc, PROT_READ, MAP_SHARED, fd,
+ (off_t) 0)) == MAP_FAILED) {
+ TP_UNRESOLVED("mmap() failed: %s.", strerror(errno));
+ goto done;
+ }
+
+ /* Check the first gap */
+ if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) {
+ TP_UNRESOLVED("elf$1_fsize(ELF_T_EHDR) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ for (p = r + fsz; p < r + TS_OFFSET_1; p++)
+ if (*p != TS_FILLCHAR) {
+ TP_FAIL("offset 0x%x [%d] != %d", p - r, *p,
+ TS_FILLCHAR);
+ goto done;
+ }
+
+ /* Check whether valid contents exist at first section offset. */
+ if (memcmp(r + TS_OFFSET_1, testdata, sizeof(testdata)) != 0) {
+ TP_FAIL("memcmp(first) failed.");
+ goto done;
+ }
+
+ /* Check the second gap. */
+ for (p = r + TS_OFFSET_1 + sizeof(testdata); p < r + TS_OFFSET_2; p++)
+ if (*p != TS_FILLCHAR) {
+ TP_FAIL("offset 0x%x [%d] != %d", p - r, *p,
+ TS_FILLCHAR);
+ goto done;
+ }
+
+ /* Check whether valid contents exist at second section offset. */
+ if (memcmp(r + TS_OFFSET_2, testdata, sizeof(testdata)) != 0) {
+ TP_FAIL("memcmp(second) failed.");
+ goto done;
+ }
+
+ /* Check the gap till the shdr table. */
+ for (p = r + TS_OFFSET_2 + sizeof(testdata);
+ p < r + TS_SHDR_OFFSET;
+ p++)
+ if (*p != TS_FILLCHAR) {
+ TP_FAIL("offset 0x%x [%d] != %d", p - r, *p,
+ TS_FILLCHAR);
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ if (r)
+ (void) munmap(r, rc);
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ unlink(TS_NEWFILE);
+ tet_result(result);
+}')
+
+FN(32,LSB)
+FN(32,MSB)
+FN(64,LSB)
+FN(64,MSB)
+
+/*
+ * Check that the region between the Ehdr and Phdr is filled correctly,
+ * when the application specifies the file layout.
+ */
+define(`FN',`
+void
+tcAppLayoutEhdrPhdrGap$2$1(void)
+{
+ Elf *e;
+ Elf$1_Ehdr *eh;
+ Elf$1_Phdr *ph;
+ int fd, result;
+ size_t fsz;
+ off_t rc;
+ unsigned char *p, *r;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("$2$1: elf_fill()/app-layout fills gaps.");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+ r = NULL;
+
+ _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;);
+
+ /*
+ * We create an ELF file with the PHDR placed an offset away
+ * from the EHDR.
+ */
+ elf_fill(TS_FILLCHAR);
+ if (elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT) != ELF_F_LAYOUT) {
+ TP_UNRESOLVED("elf_flagdata() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((eh = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ eh->e_ident[EI_DATA] = ELFDATA2$2;
+
+ /*
+ * Create the PHDR.
+ */
+ if ((ph = elf$1_newphdr(e, 1)) == NULL) {
+ TP_UNRESOLVED("elf_newphdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /*
+ * Position the PHDR.
+ */
+ eh->e_phoff = TS_OFFSET_1;
+
+ /*
+ * Update the ELF object.
+ */
+ if ((rc = elf_update(e, ELF_C_WRITE)) < 0) {
+ TP_UNRESOLVED("elf_update() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ (void) elf_end(e); e = NULL;
+ (void) close(fd); fd = -1;
+
+ /*
+ * Mmap() in the file and check that the contents match.
+ */
+
+ if ((fd = open(TS_NEWFILE, O_RDONLY, 0)) < 0) {
+ TP_UNRESOLVED("open() failed: %s.", strerror(errno));
+ goto done;
+ }
+
+ if ((r = mmap(NULL, (size_t) rc, PROT_READ, MAP_SHARED, fd,
+ (off_t) 0)) == MAP_FAILED) {
+ TP_UNRESOLVED("mmap() failed: %s.", strerror(errno));
+ goto done;
+ }
+
+ /* Check the gap between the EHDR and the PHDR. */
+ if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) {
+ TP_UNRESOLVED("elf$1_fsize(ELF_T_EHDR) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ for (p = r + fsz; p < r + TS_OFFSET_1; p++)
+ if (*p != TS_FILLCHAR) {
+ TP_FAIL("offset 0x%x [%d] != %d", p - r, *p,
+ TS_FILLCHAR);
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ if (r)
+ (void) munmap(r, rc);
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ unlink(TS_NEWFILE);
+ tet_result(result);
+}')
+
+FN(32,LSB)
+FN(32,MSB)
+FN(64,LSB)
+FN(64,MSB)
diff --git a/test/libelf/tset/elf_flagarhdr/Makefile b/test/libelf/tset/elf_flagarhdr/Makefile
new file mode 100644
index 0000000000000..8e2ba7d1a26c7
--- /dev/null
+++ b/test/libelf/tset/elf_flagarhdr/Makefile
@@ -0,0 +1,16 @@
+# $Id: Makefile 2077 2011-10-27 03:59:40Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= flagarhdr.m4
+
+TS_DATA= a.ar
+CLEANFILES+= a1
+
+a1: .SILENT
+ echo "a1" > ${.TARGET}
+
+a.ar: a1 .SILENT
+ ${AR} crv ${.TARGET} a1 > /dev/null
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_flagarhdr/flagarhdr.m4 b/test/libelf/tset/elf_flagarhdr/flagarhdr.m4
new file mode 100644
index 0000000000000..e35f2b3bc464e
--- /dev/null
+++ b/test/libelf/tset/elf_flagarhdr/flagarhdr.m4
@@ -0,0 +1,98 @@
+/*-
+ * Copyright (c) 2008 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: flagarhdr.m4 2077 2011-10-27 03:59:40Z jkoshy $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+
+#include "tet_api.h"
+
+include(`elfts.m4')
+include(`elf_flag.m4')
+
+/*
+ * Tests for elf_flagarhdr().
+ */
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * The following defines to match that in ./Makefile.
+ */
+define(`TP_ARFILE',`"a.ar"')
+
+
+/*
+ * Boiler plate to get a valid ELF pointer.
+ */
+define(`_TP_DECLARATIONS',`
+ int fd;
+ Elf *ar, *member;
+ Elf_Arhdr *arh;')
+define(`_TP_PROLOGUE',`
+ result = TET_UNRESOLVED;
+ fd = -1;
+ ar = member = NULL;
+
+ TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd);
+
+ if ((member = elf_begin(fd, ELF_C_READ, ar)) == NULL) {
+ TP_UNRESOLVED("retrieval of archive member failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((arh = elf_getarhdr(member)) == NULL) {
+ TP_UNRESOLVED("elf_getarhdr() on member failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+')
+define(`_TP_EPILOGUE',`
+ done:
+ if (member)
+ (void) elf_end(member);
+ if (ar)
+ (void) elf_end(ar);
+ if (fd != -1)
+ (void) close(fd);
+')
+
+TP_FLAG_NULL(`elf_flagarhdr');
+TP_FLAG_ILLEGAL_CMD(`elf_flagarhdr',`arh')
+TP_FLAG_CLR(`elf_flagarhdr',`arh')
+TP_FLAG_SET(`elf_flagarhdr',`arh')
+TP_FLAG_ILLEGAL_FLAG(`elf_flagarhdr',`arh',`ELF_F_DIRTY')
diff --git a/test/libelf/tset/elf_flagdata/Makefile b/test/libelf/tset/elf_flagdata/Makefile
new file mode 100644
index 0000000000000..abad59ad3e56c
--- /dev/null
+++ b/test/libelf/tset/elf_flagdata/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1080 2010-08-10 14:52:44Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= data.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_flagdata/data.m4 b/test/libelf/tset/elf_flagdata/data.m4
new file mode 100644
index 0000000000000..f1ec5bc0d3259
--- /dev/null
+++ b/test/libelf/tset/elf_flagdata/data.m4
@@ -0,0 +1,110 @@
+/*-
+ * Copyright (c) 2006 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: data.m4 223 2008-08-10 15:40:06Z jkoshy $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+
+#include "tet_api.h"
+
+include(`elfts.m4')
+include(`elf_flag.m4')
+
+/*
+ * Tests for elf_flagdata().
+ */
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * A Null argument is allowed.
+ */
+
+TP_FLAG_NULL(`elf_flagdata')
+
+/* Boilerplate for getting hold of a valid Elf_Data structure. */
+
+define(`_TP_DECLARATIONS',`
+ int fd;
+ Elf *e;
+ Elf32_Ehdr *eh;
+ Elf_Scn *scn;
+ Elf_Data *d;')
+define(`_TP_PROLOGUE',`
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd);
+
+ if ((eh = elf32_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf_newehdr() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_newscn() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((d = elf_newdata(scn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }')
+define(`_TP_EPILOGUE',`
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);')
+
+/*
+ * An illegal cmd value is rejected.
+ */
+
+TP_FLAG_ILLEGAL_CMD(`elf_flagdata',`d')
+
+/*
+ * Legal cmd values are allowed.
+ */
+TP_FLAG_CLR(`elf_flagdata',`d')
+TP_FLAG_SET(`elf_flagdata',`d')
+
+/*
+ * Illegal flag values are rejected.
+ */
+TP_FLAG_ILLEGAL_FLAG(`elf_flagdata',`d',`ELF_F_DIRTY')
diff --git a/test/libelf/tset/elf_flagehdr/Makefile b/test/libelf/tset/elf_flagehdr/Makefile
new file mode 100644
index 0000000000000..048c4b3762c1b
--- /dev/null
+++ b/test/libelf/tset/elf_flagehdr/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1080 2010-08-10 14:52:44Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= ehdr.m4
+TS_DATA= ehdr.lsb32
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_flagehdr/ehdr.m4 b/test/libelf/tset/elf_flagehdr/ehdr.m4
new file mode 100644
index 0000000000000..41b7a5bdb0145
--- /dev/null
+++ b/test/libelf/tset/elf_flagehdr/ehdr.m4
@@ -0,0 +1,115 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: ehdr.m4 1408 2011-02-05 08:34:33Z jkoshy $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+
+#include "tet_api.h"
+
+include(`elfts.m4')
+include(`elf_flag.m4')
+
+/*
+ * Tests for elf_flagehdr().
+ */
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * A Null argument is allowed.
+ */
+
+TP_FLAG_NULL(`elf_flagehdr')
+
+/* Boilerplate for getting hold of a valid Ehdr pointer */
+
+define(`_TP_DECLARATIONS',`
+ int fd;
+ Elf *e;
+ Elf32_Ehdr *eh;')
+define(`_TP_PROLOGUE',`
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd);
+
+ if ((eh = elf32_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf_newehdr() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }')
+define(`_TP_EPILOGUE',`
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);')
+
+TP_FLAG_NON_ELF(`elf_flagehdr')
+
+TP_FLAG_ILLEGAL_CMD(`elf_flagehdr',`e')
+
+TP_FLAG_CLR(`elf_flagehdr',`e')
+TP_FLAG_SET(`elf_flagehdr',`e')
+
+TP_FLAG_ILLEGAL_FLAG(`elf_flagehdr',`e',`ELF_F_DIRTY')
+
+/*
+ * An out-of-sequence call is detected.
+ */
+_TP_FLAG_FN(`tcArgsSequence',`
+ int error, fd;
+ unsigned int f;
+ Elf *e;',`
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("Out of sequence use is detected.");
+
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ TS_OPEN_FILE(e, "ehdr.lsb32", ELF_C_READ, fd);
+
+ result = TET_PASS;
+ if ((f = elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY)) != 0 ||
+ (error = elf_errno()) != ELF_E_SEQUENCE) {
+ TP_FAIL("flag=0x%x, error=%d \"%s\".", f, error,
+ elf_errmsg(error));
+ goto done;
+ }',`_TP_EPILOGUE')
diff --git a/test/libelf/tset/elf_flagelf/Makefile b/test/libelf/tset/elf_flagelf/Makefile
new file mode 100644
index 0000000000000..4f884a7e31190
--- /dev/null
+++ b/test/libelf/tset/elf_flagelf/Makefile
@@ -0,0 +1,17 @@
+# $Id: Makefile 1711 2011-08-09 12:53:16Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= elf.m4
+TS_DATA= a.ar
+
+CLEANFILES= zero
+
+zero:
+ touch ${.TARGET}
+
+a.ar: zero
+ rm -f ${.TARGET}
+ ar crv ${.TARGET} ${.ALLSRC}
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_flagelf/elf.m4 b/test/libelf/tset/elf_flagelf/elf.m4
new file mode 100644
index 0000000000000..e5006f798c953
--- /dev/null
+++ b/test/libelf/tset/elf_flagelf/elf.m4
@@ -0,0 +1,133 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: elf.m4 1599 2011-07-04 03:18:52Z jkoshy $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+
+#include "tet_api.h"
+
+include(`elfts.m4')
+include(`elf_flag.m4')
+
+/*
+ * Tests for elf_flagelf().
+ */
+
+IC_REQUIRES_VERSION_INIT();
+
+TP_FLAG_NULL(`elf_flagelf')
+
+/*
+ * Boiler plate to get a valid ELF pointer.
+ */
+define(`_TP_DECLARATIONS',`
+ int fd;
+ Elf *e;')
+define(`_TP_PROLOGUE',`
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd);')
+define(`_TP_EPILOGUE',`
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);')
+
+TP_FLAG_NON_ELF(`elf_flagelf')
+
+TP_FLAG_ILLEGAL_CMD(`elf_flagelf',`e')
+
+TP_FLAG_CLR(`elf_flagelf',`e')
+TP_FLAG_SET(`elf_flagelf',`e')
+
+TP_FLAG_ILLEGAL_FLAG(`elf_flagelf',`e',
+ `ELF_F_DIRTY|ELF_F_LAYOUT|ELF_F_ARCHIVE|ELF_F_ARCHIVE_SYSV')
+
+
+define(`TS_ARFILE',`"a.ar"')
+
+dnl Helper function.
+
+define(`_FN',`
+void
+$1(void)
+{
+ int error, fd, result, ret;
+ Elf *e;
+
+ TP_ANNOUNCE($2);
+
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ TS_OPEN_FILE(e, $3, $4, fd);
+
+ result = TET_PASS;
+ if ((ret = elf_flagelf(e, ELF_C_SET, $5)) != 0 ||
+ (error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("ret=%d,error=%d \"%s\".", ret, error,
+ elf_errmsg(error));
+ goto done;
+ }
+
+ _TP_EPILOGUE()
+
+ tet_result(result);
+}')
+
+/*
+ * Attempting to set ELF_F_ARCHIVE on an object opened with ELF_C_READ
+ * should fail.
+ */
+_FN(`tcArgsArchiveFlagOnReadFD',
+ `"Setting ELF_F_ARCHIVE on an object opened with "
+ "ELF_C_READ should fail."',
+ TS_ARFILE, ELF_C_READ,
+ ELF_F_ARCHIVE)
+
+/*
+ * Attempting to set ELF_F_ARCHIVE_SYSV without ELF_F_ARCHIVE should fail.
+ */
+_FN(`tcArgsArchiveFlagSysV',
+ `"Setting ELF_F_ARCHIVE_SYSV without ELF_F_ARCHIVE should fail."',
+ TS_NEWFILE, ELF_C_WRITE,
+ ELF_F_ARCHIVE_SYSV)
diff --git a/test/libelf/tset/elf_flagphdr/Makefile b/test/libelf/tset/elf_flagphdr/Makefile
new file mode 100644
index 0000000000000..6797650fda531
--- /dev/null
+++ b/test/libelf/tset/elf_flagphdr/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1080 2010-08-10 14:52:44Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= phdr.m4
+TS_DATA= phdr.lsb32
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_flagphdr/phdr.m4 b/test/libelf/tset/elf_flagphdr/phdr.m4
new file mode 100644
index 0000000000000..753938f89587c
--- /dev/null
+++ b/test/libelf/tset/elf_flagphdr/phdr.m4
@@ -0,0 +1,117 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: phdr.m4 1413 2011-02-05 10:26:18Z jkoshy $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+
+#include "tet_api.h"
+
+include(`elfts.m4')
+include(`elf_flag.m4')
+
+/*
+ * Tests for elf_flagdata().
+ */
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * A Null argument is allowed.
+ */
+
+TP_FLAG_NULL(`elf_flagphdr')
+
+define(`_TP_DECLARATIONS',`
+ int fd;
+ Elf *e;
+ Elf32_Ehdr *eh;
+ Elf32_Phdr *ph;')
+define(`_TP_PROLOGUE',`
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd);
+
+ if ((eh = elf32_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf_newehdr() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((ph = elf32_newphdr(e, 1)) == NULL) {
+ TP_UNRESOLVED("elf_newphdr() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }')
+define(`_TP_EPILOGUE',`
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);')
+
+TP_FLAG_ILLEGAL_CMD(`elf_flagphdr',`e')
+
+TP_FLAG_CLR(`elf_flagphdr',`e')
+TP_FLAG_SET(`elf_flagphdr',`e')
+
+TP_FLAG_ILLEGAL_FLAG(`elf_flagphdr',`e',`ELF_F_DIRTY')
+
+/*
+ * An out-of-sequence call is detected.
+ */
+_TP_FLAG_FN(`tcArgsSequence',`
+ int error, fd;
+ unsigned int f;
+ Elf *e;',`
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("Out of sequence use is detected.");
+
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ TS_OPEN_FILE(e, "phdr.lsb32", ELF_C_READ, fd);
+
+ result = TET_PASS;
+ if ((f = elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY)) != 0 ||
+ (error = elf_errno()) != ELF_E_SEQUENCE) {
+ TP_FAIL("flag=0x%x, error=%d \"%s\".", f, error,
+ elf_errmsg(error));
+ goto done;
+ }',`_TP_EPILOGUE')
diff --git a/test/libelf/tset/elf_flagscn/Makefile b/test/libelf/tset/elf_flagscn/Makefile
new file mode 100644
index 0000000000000..04ec8a3fc2392
--- /dev/null
+++ b/test/libelf/tset/elf_flagscn/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1080 2010-08-10 14:52:44Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= scn.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_flagscn/scn.m4 b/test/libelf/tset/elf_flagscn/scn.m4
new file mode 100644
index 0000000000000..6d6b0c66bc9c1
--- /dev/null
+++ b/test/libelf/tset/elf_flagscn/scn.m4
@@ -0,0 +1,91 @@
+/*-
+ * Copyright (c) 2006 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: scn.m4 223 2008-08-10 15:40:06Z jkoshy $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+
+#include "tet_api.h"
+
+include(`elfts.m4')
+include(`elf_flag.m4')
+
+/*
+ * Tests for elf_flagdata().
+ */
+
+IC_REQUIRES_VERSION_INIT();
+
+TP_FLAG_NULL(`elf_flagscn')
+
+/* Boilerplate for getting hold of a valid Elf_Scn pointer */
+define(`_TP_DECLARATIONS',`
+ int fd;
+ Elf *e;
+ Elf32_Ehdr *eh;
+ Elf_Scn *scn;')
+define(`_TP_PROLOGUE',`
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd);
+
+ if ((eh = elf32_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf_newehdr() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_newscn() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }')
+define(`_TP_EPILOGUE',`
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);')
+
+TP_FLAG_ILLEGAL_CMD(`elf_flagscn',`scn')
+
+TP_FLAG_CLR(`elf_flagscn',`scn')
+TP_FLAG_SET(`elf_flagscn',`scn')
+
+TP_FLAG_ILLEGAL_FLAG(`elf_flagscn',`scn',`ELF_F_DIRTY')
+
+
diff --git a/test/libelf/tset/elf_flagshdr/Makefile b/test/libelf/tset/elf_flagshdr/Makefile
new file mode 100644
index 0000000000000..a0a771ed8b359
--- /dev/null
+++ b/test/libelf/tset/elf_flagshdr/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1080 2010-08-10 14:52:44Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= shdr.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_flagshdr/shdr.m4 b/test/libelf/tset/elf_flagshdr/shdr.m4
new file mode 100644
index 0000000000000..e0d89588699a6
--- /dev/null
+++ b/test/libelf/tset/elf_flagshdr/shdr.m4
@@ -0,0 +1,91 @@
+/*-
+ * Copyright (c) 2006 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: shdr.m4 223 2008-08-10 15:40:06Z jkoshy $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+
+#include "tet_api.h"
+
+include(`elfts.m4')
+include(`elf_flag.m4')
+
+/*
+ * Tests for elf_flagdata().
+ */
+
+IC_REQUIRES_VERSION_INIT();
+
+TP_FLAG_NULL(`elf_flagshdr')
+
+/* Boilerplate for getting hold of a valid Elf_Scn pointer */
+define(`_TP_DECLARATIONS',`
+ int fd;
+ Elf *e;
+ Elf32_Ehdr *eh;
+ Elf_Scn *scn;')
+define(`_TP_PROLOGUE',`
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd);
+
+ if ((eh = elf32_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf_newehdr() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_newscn() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }')
+define(`_TP_EPILOGUE',`
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);')
+
+TP_FLAG_ILLEGAL_CMD(`elf_flagshdr',`scn')
+
+TP_FLAG_CLR(`elf_flagshdr',`scn')
+TP_FLAG_SET(`elf_flagshdr',`scn')
+
+TP_FLAG_ILLEGAL_FLAG(`elf_flagshdr',`scn',`ELF_F_DIRTY')
+
+
diff --git a/test/libelf/tset/elf_fsize/Makefile b/test/libelf/tset/elf_fsize/Makefile
new file mode 100644
index 0000000000000..0aaa8a8d61fe2
--- /dev/null
+++ b/test/libelf/tset/elf_fsize/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1346 2011-01-01 15:03:31Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= fsize.m4
+TS_DATA= fsize.msb32 fsize.msb64
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_fsize/fsize.m4 b/test/libelf/tset/elf_fsize/fsize.m4
new file mode 100644
index 0000000000000..4a43e4d442ac9
--- /dev/null
+++ b/test/libelf/tset/elf_fsize/fsize.m4
@@ -0,0 +1,273 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: fsize.m4 1722 2011-08-13 05:34:38Z jkoshy $
+ */
+
+include(`elfts.m4')
+
+#include <sys/param.h>
+
+#include <fcntl.h>
+#include <gelf.h>
+#include <libelf.h>
+#include <unistd.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * Test the `elf[32,64]_fsize' and `gelf_fsize' entry points.
+ */
+
+void
+tcArgumentGelfNull(void)
+{
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("gelf_fsize(NULL,...) fails with error ELF_E_ARGUMENT.");
+
+ if (gelf_fsize(NULL, ELF_T_ADDR, 1, EV_CURRENT) != 0 ||
+ elf_errno() != ELF_E_ARGUMENT)
+ tet_result(TET_FAIL);
+ else
+ tet_result(TET_PASS);
+}
+
+void
+tcArgumentBadVersion(void)
+{
+ Elf *e;
+ int bad_version, fd, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("using an unsupported version number fails with "
+ "ELF_E_VERSION.");
+
+ TS_OPEN_FILE(e,"fsize.msb32",ELF_C_READ,fd);
+
+ bad_version = EV_CURRENT+1;
+
+ result = TET_PASS;
+
+ if (elf32_fsize(ELF_T_ADDR, 1, bad_version) != 0 ||
+ elf_errno() != ELF_E_VERSION)
+ result = TET_FAIL;
+ else if (elf64_fsize(ELF_T_ADDR, 1, bad_version) != 0 ||
+ elf_errno() != ELF_E_VERSION)
+ result = TET_FAIL;
+ else if (gelf_fsize(e, ELF_T_ADDR, 1, bad_version) != 0 ||
+ elf_errno() != ELF_E_VERSION)
+ result = TET_FAIL;
+
+ tet_result(result);
+
+ (void) elf_end(e);
+ (void) close(fd);
+}
+
+void
+tcArgumentBadTypeTooSmall(void)
+{
+ Elf *e;
+ int fd, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("a type parameter less than 0 fails with "
+ "ELF_E_ARGUMENT.");
+
+ TS_OPEN_FILE(e,"fsize.msb32",ELF_C_READ,fd);
+
+ result = TET_PASS;
+ if (elf32_fsize(-1, 1, EV_CURRENT) != 0 ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+ else if (elf64_fsize(-1, 1, EV_CURRENT) != 0 ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+ else if (gelf_fsize(e, -1, 1, EV_CURRENT) != 0 ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ tet_result(result);
+ (void) elf_end(e);
+ (void) close(fd);
+}
+
+void
+tcArgumentBadTypeTooLarge(void)
+{
+ Elf *e;
+ int fd, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("a type parameter >= ELF_T_NUM is fails with "
+ "ELF_E_ARGUMENT.");
+
+ TS_OPEN_FILE(e,"fsize.msb32",ELF_C_READ,fd);
+
+ result = TET_PASS;
+ if (elf32_fsize(ELF_T_NUM, 1, EV_CURRENT) != 0 ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+ else if (elf64_fsize(ELF_T_NUM, 1, EV_CURRENT) != 0 ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+ else if (gelf_fsize(e, ELF_T_NUM, 1, EV_CURRENT) != 0 ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ tet_result(result);
+ (void) elf_end(e);
+ (void) close(fd);
+}
+
+static size_t sizes32[ELF_T_NUM] = {
+#define DEFINE_SIZE(N,SZ) [ELF_T_##N] = (SZ)
+ DEFINE_SIZE(ADDR, 4),
+ DEFINE_SIZE(BYTE, 1),
+ DEFINE_SIZE(CAP, 8),
+ DEFINE_SIZE(DYN, 4+4),
+ DEFINE_SIZE(EHDR, 16+2+2+4+4+4+4+4+2+2+2+2+2+2),
+ DEFINE_SIZE(HALF, 2),
+ DEFINE_SIZE(LWORD, 8),
+ DEFINE_SIZE(MOVE, 20),
+ DEFINE_SIZE(MOVEP, 0),
+ DEFINE_SIZE(NOTE, 1),
+ DEFINE_SIZE(OFF, 4),
+ DEFINE_SIZE(PHDR, 4+4+4+4+4+4+4+4),
+ DEFINE_SIZE(REL, 4+4),
+ DEFINE_SIZE(RELA, 4+4+4),
+ DEFINE_SIZE(SHDR, 4+4+4+4+4+4+4+4+4+4),
+ DEFINE_SIZE(SWORD, 4),
+ DEFINE_SIZE(SXWORD, 0),
+ DEFINE_SIZE(SYM, 4+4+4+1+1+2),
+ DEFINE_SIZE(SYMINFO, 4),
+ DEFINE_SIZE(VDEF, 1),
+ DEFINE_SIZE(VNEED, 1),
+ DEFINE_SIZE(WORD, 4),
+ DEFINE_SIZE(XWORD, 0),
+ DEFINE_SIZE(GNUHASH, 1)
+#undef DEFINE_SIZE
+};
+
+void
+tcSizesSize32(void)
+{
+ Elf *e;
+ int fd, i;
+ size_t size;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("check 32 bit sizes of ELF types");
+
+ TS_OPEN_FILE(e,"fsize.msb32",ELF_C_READ,fd);
+
+ for (i = ELF_T_ADDR; i < ELF_T_NUM; i++) {
+ if ((size = elf32_fsize(i, 1, EV_CURRENT)) != sizes32[i]) {
+ tet_printf("fail: elf32_fsize(%d): %d != %d",
+ i, size, sizes32[i]);
+ tet_result(TET_FAIL);
+ return;
+ }
+ if ((size = gelf_fsize(e, i, 1, EV_CURRENT)) != sizes32[i]) {
+ tet_printf("fail: gelf_fsize(%d): %d != %d",
+ i, size, sizes32[i]);
+ tet_result(TET_FAIL);
+ return;
+ }
+ }
+ tet_result(TET_PASS);
+ (void) elf_end(e);
+ (void) close(fd);
+}
+
+static size_t sizes64[ELF_T_NUM] = {
+#define DEFINE_SIZE(N,SZ) [ELF_T_##N] = (SZ)
+ DEFINE_SIZE(ADDR, 8),
+ DEFINE_SIZE(BYTE, 1),
+ DEFINE_SIZE(CAP, 16),
+ DEFINE_SIZE(DYN, 8+8),
+ DEFINE_SIZE(EHDR, 16+2+2+4+8+8+8+4+2+2+2+2+2+2),
+ DEFINE_SIZE(HALF, 2),
+ DEFINE_SIZE(LWORD, 8),
+ DEFINE_SIZE(MOVE, 28),
+ DEFINE_SIZE(MOVEP, 0),
+ DEFINE_SIZE(NOTE, 1),
+ DEFINE_SIZE(OFF, 8),
+ DEFINE_SIZE(PHDR, 4+4+8+8+8+8+8+8),
+ DEFINE_SIZE(REL, 8+8),
+ DEFINE_SIZE(RELA, 8+8+8),
+ DEFINE_SIZE(SHDR, 4+4+8+8+8+8+4+4+8+8),
+ DEFINE_SIZE(SWORD, 4),
+ DEFINE_SIZE(SXWORD, 8),
+ DEFINE_SIZE(SYM, 4+1+1+2+8+8),
+ DEFINE_SIZE(SYMINFO, 4),
+ DEFINE_SIZE(VDEF, 1),
+ DEFINE_SIZE(VNEED, 1),
+ DEFINE_SIZE(WORD, 4),
+ DEFINE_SIZE(XWORD, 8),
+ DEFINE_SIZE(GNUHASH, 1)
+#undef DEFINE_SIZE
+};
+
+void
+tcSizesSize64(void)
+{
+ Elf *e;
+ int fd, i;
+ size_t size;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("check 64 bit sizes of ELF types");
+
+ TS_OPEN_FILE(e,"fsize.msb64",ELF_C_READ,fd);
+
+ for (i = ELF_T_ADDR; i < ELF_T_NUM; i++) {
+ if ((size = elf64_fsize(i, 1, EV_CURRENT)) != sizes64[i]) {
+ tet_printf("fail: elf64_fsize(%d): %d != %d",
+ i, size, sizes64[i]);
+ tet_result(TET_FAIL);
+ return;
+ }
+ if ((size = gelf_fsize(e, i, 1, EV_CURRENT)) != sizes64[i]) {
+ tet_printf("fail: gelf_fsize(%d): %d != %d",
+ i, size, sizes64[i]);
+ tet_result(TET_FAIL);
+ return;
+ }
+ }
+ tet_result(TET_PASS);
+ (void) elf_end(e);
+ (void) close(fd);
+
+}
diff --git a/test/libelf/tset/elf_getarhdr/Makefile b/test/libelf/tset/elf_getarhdr/Makefile
new file mode 100644
index 0000000000000..9a8245f6f53ee
--- /dev/null
+++ b/test/libelf/tset/elf_getarhdr/Makefile
@@ -0,0 +1,29 @@
+# $Id: Makefile 1329 2010-12-26 19:23:13Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= getarhdr.m4
+
+# These names must match those in the test case code.
+TS_DATA= a.ar a-bsd.ar a1.o a2.o
+TS_LONGNAME= "s------------------------2"
+CLEANFILES+= a1.c a2.c s1 ${TS_LONGNAME} "s 3"
+
+a1.c: .SILENT
+ echo "int a1;" > ${.TARGET}
+a2.c: .SILENT
+ echo "int a2;" > ${.TARGET}
+
+a.ar: a1.o a2.o .SILENT
+ rm -f ${.TARGET}
+ echo 'This is s1.' > s1
+ echo 's2.' > ${TS_LONGNAME}
+ echo 's-3.' > "s 3"
+ ${AR} crv ${.TARGET} s1 a1.o ${TS_LONGNAME} a2.o "s 3" > /dev/null
+
+a-bsd.ar: a.ar .SILENT
+ rm -f ${.TARGET}
+ ${ELFTOOLCHAIN_AR} -F bsd -crv ${.TARGET} s1 a1.o ${TS_LONGNAME} \
+ a2.o "s 3" > /dev/null
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_getarhdr/getarhdr.m4 b/test/libelf/tset/elf_getarhdr/getarhdr.m4
new file mode 100644
index 0000000000000..98325eb212e2e
--- /dev/null
+++ b/test/libelf/tset/elf_getarhdr/getarhdr.m4
@@ -0,0 +1,471 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: getarhdr.m4 1388 2011-01-26 02:29:24Z jkoshy $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ar.h>
+#include <errno.h>
+#include <libelf.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+IC_REQUIRES_VERSION_INIT();
+
+include(`elfts.m4')
+/*
+ * The following defines should match that in `./Makefile'.
+ */
+define(`TP_ELFFILE',`"a1.o"')
+define(`TP_ARFILE_SVR4', `"a.ar"')
+define(`TP_ARFILE_BSD', `"a-bsd.ar"')
+
+/*
+ * A NULL `Elf' argument fails.
+ */
+void
+tcArgsNull(void)
+{
+ int error, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getarhdr(NULL) fails.");
+
+ result = TET_PASS;
+ if (elf_getarhdr(NULL) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error));
+ result = TET_FAIL;
+ }
+
+ tet_result(result);
+}
+
+/*
+ * elf_getarhdr() on a non-Ar file fails.
+ */
+static char *nonar = "This is not an AR file.";
+
+void
+tcArgsNonAr(void)
+{
+ Elf *e;
+ int error, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getarhdr(non-ar) fails.");
+
+ TS_OPEN_MEMORY(e, nonar);
+
+ result = TET_PASS;
+
+ if (elf_getarhdr(e) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error));
+ result = TET_FAIL;
+ }
+
+ (void) elf_end(e);
+
+ tet_result(result);
+}
+
+/*
+ * elf_getarhdr() on a top-level ELF file fails.
+ */
+
+void
+tcArgsElf(void)
+{
+ Elf *e;
+ int error, fd, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getarhdr(elf) fails.");
+
+ TS_OPEN_FILE(e, TP_ELFFILE, ELF_C_READ, fd);
+
+ result = TET_PASS;
+
+ if (elf_getarhdr(e) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error));
+ result = TET_FAIL;
+ }
+
+ (void) elf_end(e);
+
+ tet_result(result);
+}
+
+
+
+/*
+ * elf_getarhdr() on ar archive members succeed.
+ */
+
+/* This list of files must match the order of the files in test archive. */
+static char *rfn[] = {
+ "s1",
+ "a1.o",
+ "s------------------------2", /* long file name */
+ "a2.o",
+ "s 3" /* file name with blanks */
+};
+
+#define RAWNAME_SIZE 16 /* See <ar.h> */
+
+struct arnames {
+ char *name;
+ char rawname[RAWNAME_SIZE];
+};
+
+/* These lists of names and raw names must match those in the test archives. */
+static struct arnames rn_BSD[] = {
+ {
+ .name = "__.SYMDEF", /* Symbol table. */
+ .rawname = { '_', '_', '.', 'S', 'Y', 'M', 'D', 'E',
+ 'F', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
+ },
+ {
+ .name = "s1", /* Ordinary, non object member (short name). */
+ .rawname = { 's', '1', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
+ },
+ {
+ .name = "a1.o", /* Ordinary, object file (short name). */
+ .rawname = { 'a', '1', '.', 'o', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
+ },
+ {
+ .name = "s------------------------2", /* Long file name. */
+ .rawname = { '#', '1', '/', '2', '6', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
+ },
+ {
+ .name = "a2.o", /* Ordinary, object file (short name). */
+ .rawname = { 'a', '2', '.', 'o', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
+
+ },
+ {
+ .name = "s 3", /* file name with blanks */
+ .rawname = { '#', '1', '/', '3', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
+ }
+};
+
+static struct arnames rn_SVR4[] = {
+ {
+ .name = "/",
+ .rawname = { '/', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
+ },
+ {
+ .name = "//",
+ .rawname = { '/', '/', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
+ },
+ {
+ .name = "s1",
+ .rawname = { 's', '1', '/', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
+ },
+ {
+ .name = "a1.o",
+ .rawname = { 'a', '1', '.', 'o', '/', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
+ },
+ {
+ .name = "s------------------------2", /* long file name */
+ .rawname = { '/', '0', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
+ },
+ {
+ .name = "a2.o",
+ .rawname = { 'a', '2', '.', 'o', '/', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
+
+ },
+ {
+ .name = "s 3", /* file name with blanks */
+ .rawname = { 's', ' ', '3', '/', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
+ }
+};
+
+define(`ARCHIVE_TESTS',`
+/*
+ * elf_getarhdr() on an ar archive (not a member) fails.
+ */
+
+void
+tcArArchive$1(void)
+{
+ Elf *e;
+ int error, fd, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getarhdr(ar-descriptor)/$1 fails.");
+
+ TS_OPEN_FILE(e, TP_ARFILE_$1, ELF_C_READ, fd);
+
+ result = TET_PASS;
+
+ if (elf_getarhdr(e) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error));
+ }
+
+ (void) elf_end(e);
+
+ tet_result(result);
+}
+
+void
+tcArMember$1(void)
+{
+ Elf_Arhdr *arh;
+ Elf *ar_e, *e;
+ Elf_Cmd c;
+ int error, fd, result;
+ char **fn;
+ struct stat sb;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getarhdr()/$1 succeeds for all members of an archive.");
+
+ ar_e = e = NULL;
+ c = ELF_C_READ;
+
+ TS_OPEN_FILE(ar_e, TP_ARFILE_$1, c, fd);
+
+ result = TET_FAIL;
+
+ fn = rfn;
+ while ((e = elf_begin(fd, c, ar_e)) != NULL) {
+
+ if ((arh = elf_getarhdr(e)) == NULL) {
+ TP_FAIL("elf_getarhdr(\"%s\") failed: \"%s\".", *fn,
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (stat(*fn, &sb) < 0) {
+ TP_UNRESOLVED("stat \"%s\" failed: %s.", *fn,
+ strerror(errno));
+ goto done;
+ }
+
+ if (strcmp(arh->ar_name, *fn) != 0) {
+ TP_FAIL("name: \"%s\" != \"%s\".", *fn,
+ arh->ar_name);
+ goto done;
+ }
+
+ if (arh->ar_mode != sb.st_mode) {
+ TP_FAIL("\%s\" mode: 0%x != 0%o.", *fn,
+ arh->ar_mode, sb.st_mode);
+ goto done;
+ }
+
+ if (arh->ar_size != sb.st_size) {
+ TP_FAIL("\"%s\" size: %d != %d.", *fn,
+ arh->ar_size, sb.st_size);
+ goto done;
+ }
+
+ if (arh->ar_uid != sb.st_uid) {
+ TP_FAIL("\"%s\" uid: %d != %d.", *fn,
+ arh->ar_uid, sb.st_uid);
+ goto done;
+ }
+
+ if (arh->ar_gid != sb.st_gid) {
+ TP_FAIL("\"%s\" gid: %d != %d.", *fn,
+ arh->ar_gid, sb.st_gid);
+ goto done;
+ }
+
+ c = elf_next(e);
+ (void) elf_end(e); e = NULL;
+ fn++;
+ }
+
+ if ((error = elf_errno()) != ELF_E_NONE) {
+ TP_UNRESOLVED("elf_begin() failed: \"%s\".", elf_errmsg(error));
+ result = TET_UNRESOLVED;
+ } else
+ result = TET_PASS;
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (ar_e)
+ (void) elf_end(ar_e);
+
+ tet_result(result);
+
+}
+
+undefine(`CHECK_SPECIAL')dnl
+undefine(`CHECK_NAMES')dnl
+define(`CHECK_SPECIAL',`
+ if ((e = elf_begin(fd, c, ar_e)) == NULL) {
+ TP_FAIL("elf_begin($1) failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ CHECK_NAMES();
+')
+
+define(`CHECK_NAMES',`
+ if ((arh = elf_getarhdr(e)) == NULL) {
+ TP_FAIL("elf_getarhdr(\"%s\") failed: \"%s\".", fn->name,
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (strcmp(arh->ar_name, fn->name) != 0) {
+ TP_FAIL("name: \"%s\" != \"%s\".", fn->name,
+ arh->ar_name);
+ goto done;
+ }
+
+
+ if (memcmp(arh->ar_rawname, fn->rawname, RAWNAME_SIZE) != 0) {
+ TP_FAIL("rawname: \"%s\" != \"%s\".", fn->rawname,
+ arh->ar_rawname);
+ goto done;
+ }
+')
+
+void
+tcArSpecial$1(void)
+{
+
+ Elf_Arhdr *arh;
+ Elf *ar_e, *e;
+ Elf_Cmd c;
+ int fd, result;
+ struct arnames *fn;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getarhdr() after an elf_rand(SARMAG) retrieves special members.");
+
+ ar_e = e = NULL;
+ c = ELF_C_READ;
+ fn = rn_$1;
+
+ TS_OPEN_FILE(ar_e, TP_ARFILE_$1, c, fd);
+
+ result = TET_PASS;
+
+ if (elf_rand(ar_e, (off_t) SARMAG) != (off_t)SARMAG) {
+ TP_UNRESOLVED("elf_rand(SARMAG) failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+
+ }
+
+ ifelse($1,`SVR4',`dnl # SVR4
+ CHECK_SPECIAL(`/');
+ CHECK_SPECIAL(`//');',`dnl # BSD
+ CHECK_SPECIAL(`__.SYMDEF');')
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (ar_e)
+ (void) elf_end(ar_e);
+
+ tet_result(result);
+}
+
+void
+tcArRawnames$1(void)
+{
+ Elf_Arhdr *arh;
+ Elf *ar_e, *e;
+ Elf_Cmd c;
+ int fd, result;
+ struct arnames *fn;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getarhdr() returns the correct rawnames.");
+
+ ar_e = e = NULL;
+ c = ELF_C_READ;
+ fn = rn_$1;
+
+ TS_OPEN_FILE(ar_e, TP_ARFILE_$1, c, fd);
+
+ result = TET_PASS;
+
+ if (elf_rand(ar_e, (off_t) SARMAG) != (off_t)SARMAG) {
+ TP_UNRESOLVED("elf_rand(SARMAG) failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+
+ }
+
+ ifelse($1,`SVR4',`dnl # SVR4
+ CHECK_SPECIAL(`/');
+ CHECK_SPECIAL(`//');',`dnl # BSD
+ CHECK_SPECIAL(`__.SYMDEF');')
+
+ /* Check the rest of the archive members. */
+
+ while ((e = elf_begin(fd, c, ar_e)) != NULL) {
+ CHECK_NAMES();
+
+ c = elf_next(e);
+ (void) elf_end(e); e = NULL;
+ fn ++;
+ }
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (ar_e)
+ (void) elf_end(ar_e);
+
+ tet_result(result);
+}
+')
+
+ARCHIVE_TESTS(`SVR4')
+ARCHIVE_TESTS(`BSD')
diff --git a/test/libelf/tset/elf_getarsym/Makefile b/test/libelf/tset/elf_getarsym/Makefile
new file mode 100644
index 0000000000000..714730621c054
--- /dev/null
+++ b/test/libelf/tset/elf_getarsym/Makefile
@@ -0,0 +1,40 @@
+# $Id: Makefile 1323 2010-12-26 05:50:57Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= getarsym.m4
+
+# These names must match those in the test case code.
+TS_DATA= a.ar a-bsd.ar a2.ar a2-bsd.ar a1.o a2.o
+TS_LONGNAME= "s------------------------2"
+CLEANFILES+= a1.c a2.c s1 ${TS_LONGNAME} "s 3"
+
+a1.c: .SILENT
+ echo "int a1;" > ${.TARGET}
+a2.c: .SILENT
+ echo "int a2;" > ${.TARGET}
+
+s1: .SILENT
+ echo 'This is s1.' > ${.TARGET}
+${TS_LONGNAME}: .SILENT
+ echo 's2.' > ${.TARGET}
+
+a.ar: a1.o a2.o ${TS_LONGNAME} s1 .SILENT
+ rm -f ${.TARGET}
+ echo 's-3.' > "s 3"
+ ${AR} crv ${.TARGET} s1 a1.o ${TS_LONGNAME} a2.o "s 3" > /dev/null
+
+a2.ar: s1 ${TS_LONGNAME} .SILENT
+ rm -f ${.TARGET}
+ ${AR} crv ${.TARGET} ${.ALLSRC} > /dev/null
+
+a-bsd.ar: a.ar .SILENT
+ rm -f ${.TARGET}
+ ${ELFTOOLCHAIN_AR} -F bsd -crv ${.TARGET} s1 a1.o ${TS_LONGNAME} \
+ a2.o "s 3" > /dev/null
+
+a2-bsd.ar: a2.ar .SILENT
+ rm -f ${.TARGET}
+ ${ELFTOOLCHAIN_AR} -F bsd -crv ${.TARGET} ${.ALLSRC} > /dev/null
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_getarsym/getarsym.m4 b/test/libelf/tset/elf_getarsym/getarsym.m4
new file mode 100644
index 0000000000000..8b8d4a1a2bd59
--- /dev/null
+++ b/test/libelf/tset/elf_getarsym/getarsym.m4
@@ -0,0 +1,363 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: getarsym.m4 1407 2011-02-05 08:31:07Z jkoshy $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ar.h>
+#include <errno.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+IC_REQUIRES_VERSION_INIT();
+
+include(`elfts.m4')
+/*
+ * The following defines should match that in `./Makefile'.
+ */
+define(`TP_ELFFILE',`"a1.o"')
+define(`TP_ARFILE_BSD', `"a-bsd.ar"')
+define(`TP_ARFILE_NOSYMTAB_BSD',`"a2-bsd.ar"')
+define(`TP_ARFILE_SVR4', `"a.ar"')
+define(`TP_ARFILE_NOSYMTAB_SVR4',`"a2.ar"')
+define(`TP_NSYMBOLS',`3')
+
+/*
+ * A NULL `Elf' argument fails.
+ */
+void
+tcArgsNull(void)
+{
+ int error, result;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getarhdr(NULL) fails.");
+
+ result = TET_PASS;
+ n = ~(size_t) 0;
+ if (elf_getarsym(NULL, &n) != NULL ||
+ (n != (size_t) 0) || (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("n=%d error=%d \"%s\".", n, error, elf_errmsg(error));
+
+ tet_result(result);
+}
+
+/*
+ * elf_getarsym() on a non-Ar file fails.
+ */
+static char *nonar = "This is not an AR file.";
+
+void
+tcArgsNonAr(void)
+{
+ Elf *e;
+ int error, result;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getarsym(non-ar) fails.");
+
+ TS_OPEN_MEMORY(e, nonar);
+
+ result = TET_PASS;
+
+ n = ~ (size_t) 0;
+ if (elf_getarsym(e, &n) != NULL || (n != (size_t) 0) ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error));
+
+ (void) elf_end(e);
+
+ tet_result(result);
+}
+
+/*
+ * elf_getarsym() on a top-level ELF file fails.
+ */
+
+void
+tcArgsElf(void)
+{
+ Elf *e;
+ int error, fd, result;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getarsym(elf) fails.");
+
+ TS_OPEN_FILE(e, TP_ELFFILE, ELF_C_READ, fd);
+
+ result = TET_PASS;
+
+ n = ~ (size_t) 0;
+ if (elf_getarsym(e, &n) != NULL || (n != (size_t) 0) ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error));
+
+ (void) elf_end(e);
+
+ tet_result(result);
+}
+
+/* This list of symbols must match the order of the files in test archive. */
+struct refsym {
+ char *as_name;
+ unsigned long as_hash;
+ char *as_object;
+ int as_found;
+};
+
+struct refsym refsym[] = {
+ { .as_name = "a1", .as_hash = 0x641, .as_object = "a1.o" },
+ { .as_name = "a2", .as_hash = 0x642, .as_object = "a2.o" },
+ { .as_name = NULL }
+};
+
+
+define(`ARCHIVE_TESTS',`
+/*
+ * elf_getarsym() on an ar archive succeeds.
+ */
+
+void
+tcArAr$1(void)
+{
+ Elf *e;
+ Elf_Arsym *arsym;
+ int fd, result;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getarsym(ar-descriptor)/$1 succeeds.");
+
+ TS_OPEN_FILE(e, TP_ARFILE_$1, ELF_C_READ, fd);
+
+ result = TET_PASS;
+ n = ~ (size_t) 0;
+ if ((arsym = elf_getarsym(e, &n)) == NULL ||
+ n != TP_NSYMBOLS)
+ TP_FAIL("error=\"%s\".", elf_errmsg(-1));
+
+ (void) elf_end(e);
+ (void) close(fd);
+
+ tet_result(result);
+}
+
+/*
+ * Two elf_getarsym invocations return the same value.
+ */
+
+void
+tcArDup$1(void)
+{
+ Elf *e;
+ Elf_Arsym *arsym, *t;
+ int fd, result;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("duplicate elf_getarsym()/$1 calls return the "
+ "same value.");
+
+ TS_OPEN_FILE(e, TP_ARFILE_$1, ELF_C_READ, fd);
+
+ result = TET_PASS;
+ n = ~ (size_t) 0;
+ if ((arsym = elf_getarsym(e, &n)) == NULL ||
+ n != TP_NSYMBOLS) {
+ TP_FAIL("error=\"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((t = elf_getarsym(e, &n)) == NULL ||
+ n != TP_NSYMBOLS) {
+ TP_FAIL("error=\"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if (t != arsym)
+ TP_FAIL("return values differ.");
+
+done:
+ (void) elf_end(e);
+ (void) close(fd);
+
+ tet_result(result);
+}
+
+/*
+ * elf_getarsym() on an ar archive without a symbol table fails.
+ */
+
+void
+tcArNoSymtab$1(void)
+{
+ Elf *e;
+ size_t n;
+ Elf_Arsym *arsym;
+ int fd, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getarsym(ar-with-no-symtab)/$1 fails.");
+
+ TS_OPEN_FILE(e, TP_ARFILE_NOSYMTAB_$1, ELF_C_READ, fd);
+
+ result = TET_PASS;
+ n = ~ (size_t) 0;
+ if ((arsym = elf_getarsym(e, &n)) != NULL ||
+ n != 0)
+ TP_FAIL("arsym=%p n=%d.", (void *) arsym, n);
+
+ (void) elf_end(e);
+ (void) close(fd);
+
+ tet_result(result);
+}
+
+/*
+ * elf_getarsym() on ar archive members succeed.
+ */
+
+void
+tcArArSym$1(void)
+{
+ Elf_Arhdr *arh;
+ Elf *ar_e, *e;
+ Elf_Arsym *arsym;
+ off_t offset;
+ int c, fd, result;
+ struct refsym *r;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getarsym()/$1 returns a correct list of symbols.");
+
+ ar_e = e = NULL;
+ c = ELF_C_READ;
+ fd = -1;
+
+ TS_OPEN_FILE(ar_e, TP_ARFILE_$1, c, fd);
+
+ result = TET_PASS;
+
+ if ((arsym = elf_getarsym(ar_e, &n)) == NULL ||
+ (n != TP_NSYMBOLS)) {
+ TP_FAIL("elf_getarsym() failed: n=%d error=\"%s\".", n,
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ for (; arsym->as_name; arsym++) {
+
+ /* Lookup this symbol in the reference table */
+ c = 0;
+ for (r = refsym; r->as_name; r++) {
+ if (strcmp(r->as_name, arsym->as_name) == 0 &&
+ r->as_hash == arsym->as_hash) {
+ r->as_found = c = 1;
+ break;
+ }
+ }
+
+ if (c == 0) {
+ TP_FAIL("extra symbol \"%s\".", arsym->as_name);
+ goto done;
+ }
+
+ if ((offset = elf_rand(ar_e, arsym->as_off)) != arsym->as_off) {
+ TP_FAIL("elf_rand(%jd) failed: \"%s\".",
+ (intmax_t) arsym->as_off, elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((e = elf_begin(fd, ELF_C_READ, ar_e)) == NULL) {
+ TP_UNRESOLVED("elf_begin() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((arh = elf_getarhdr(e)) == NULL) {
+ TP_UNRESOLVED("elf_getarhdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (strcmp(arh->ar_name, r->as_object) != 0) {
+ TP_FAIL("object-name \"%s\" != ref \"%s\".",
+ arh->ar_name, r->as_name);
+ goto done;
+ }
+
+ (void) elf_end (e);
+ e = NULL;
+ }
+
+ /* Check the last entry */
+ if (arsym->as_name != NULL || arsym->as_hash != ~0UL ||
+ arsym->as_off != (off_t) 0) {
+ TP_FAIL("last entry mangled.");
+ goto done;
+ }
+
+ /* Check that all names have been retrieved. */
+ for (r = refsym; r->as_name; r++) {
+ if (r->as_found == 0) {
+ TP_FAIL("symbol \"%s\" was not present.", r->as_name);
+ break;
+ }
+ }
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (ar_e)
+ (void) elf_end(ar_e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+
+}
+')
+
+ARCHIVE_TESTS(`SVR4')
+ARCHIVE_TESTS(`BSD')
diff --git a/test/libelf/tset/elf_getbase/Makefile b/test/libelf/tset/elf_getbase/Makefile
new file mode 100644
index 0000000000000..eb94fb8de105e
--- /dev/null
+++ b/test/libelf/tset/elf_getbase/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= getbase.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_getbase/getbase.m4 b/test/libelf/tset/elf_getbase/getbase.m4
new file mode 100644
index 0000000000000..3a9c0e85bd212
--- /dev/null
+++ b/test/libelf/tset/elf_getbase/getbase.m4
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: getbase.m4 1694 2011-08-02 04:34:35Z jkoshy $
+ */
+
+#include <libelf.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+include(`elfts.m4')
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * Test the `elf_getbase' entry point.
+ */
+
+static char elf_file[] = "\177ELF\001\001\001 \001\000\000\000\000"
+ "\000\000\000\001\000\003\000\001\000\000\000\357\276\255\336"
+ "\000\000\000\000\000\000\000\000\003\000\000\0004\000 \000"
+ "\000\000(\000\000\000\000\000";
+
+void
+tcNonMemberElf(void)
+{
+ int result;
+ off_t off;
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getbase() on an ELF file returns 0");
+
+ TS_OPEN_MEMORY(e, elf_file);
+
+ result = TET_PASS;
+ if ((off = elf_getbase(e)) != (off_t) 0)
+ result = TET_FAIL;
+
+ tet_result(result);
+ (void) elf_end(e);
+}
+
+changequote({,})
+static char ar_file[] = "!<arch>\n"
+ "t/ 1151656346 1001 0 100644 5 `\n"
+ "Test\n";
+changequote
+
+void
+tcNonMemberAr(void)
+{
+ int result;
+ off_t off;
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getbase on an AR file returns 0");
+
+ TS_OPEN_MEMORY(e, ar_file);
+
+ result = TET_PASS;
+
+ if ((off = elf_getbase(e)) != (off_t) 0)
+ result = TET_FAIL;
+
+ tet_result(result);
+ (void) elf_end(e);
+}
+
+/*
+ * Todo:
+ * - test an ar archive with an embedded ELF file.
+ * - test an ar archive with an embedded non-elf file.
+ */
diff --git a/test/libelf/tset/elf_getdata/Makefile b/test/libelf/tset/elf_getdata/Makefile
new file mode 100644
index 0000000000000..f7c14d116f8b4
--- /dev/null
+++ b/test/libelf/tset/elf_getdata/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 2077 2011-10-27 03:59:40Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= getdata.m4
+TS_YAML= zerosection
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_getdata/getdata.m4 b/test/libelf/tset/elf_getdata/getdata.m4
new file mode 100644
index 0000000000000..40afc8a4ec300
--- /dev/null
+++ b/test/libelf/tset/elf_getdata/getdata.m4
@@ -0,0 +1,203 @@
+/*-
+ * Copyright (c) 2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: getdata.m4 2090 2011-10-27 08:07:39Z jkoshy $
+ */
+
+#include <libelf.h>
+#include <gelf.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+include(`elfts.m4')
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * Find an ELF section with the given name.
+ */
+static Elf_Scn *
+findscn(Elf *e, const char *name)
+{
+ size_t shstrndx;
+ const char *scn_name;
+ Elf_Scn *scn;
+ GElf_Shdr shdr;
+
+ /* Locate the string table. */
+ if (elf_getshdrstrndx(e, &shstrndx) != 0)
+ return (NULL);
+
+ /* Find a section with a matching name. */
+ scn = NULL;
+ while ((scn = elf_nextscn(e, scn)) != NULL) {
+ if (gelf_getshdr(scn, &shdr) == NULL)
+ return (NULL);
+ if ((scn_name = elf_strptr(e, shstrndx,
+ (size_t) shdr.sh_name)) == NULL)
+ return (NULL);
+ if (strcmp(scn_name, name) == 0)
+ return (scn);
+ }
+
+ return (NULL);
+}
+
+define(`ZEROSECTION',".zerosection")
+undefine(`FN')
+define(`FN',`
+void
+tcZeroSection$1$2(void)
+{
+ Elf *e;
+ int error, fd, result;
+ Elf_Scn *scn;
+ Elf_Data *ed;
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ TP_ANNOUNCE("a data descriptor for a zero sized section is correctly retrieved");
+
+ _TS_OPEN_FILE(e, "zerosection.$1$2", ELF_C_READ, fd, goto done;);
+
+ if ((scn = findscn(e, ZEROSECTION)) == NULL) {
+ TP_UNRESOLVED("Cannot find section \""ZEROSECTION"\"");
+ goto done;
+ }
+
+ ed = NULL;
+ if ((ed = elf_getdata(scn, ed)) == NULL) {
+ error = elf_errno();
+ TP_FAIL("elf_getdata failed %d \"%s\"", error,
+ elf_errmsg(error));
+ goto done;
+ }
+
+ if (ed->d_size != 0 || ed->d_buf != NULL) {
+ TP_FAIL("Illegal values returned: size %d buf %p",
+ (int) ed->d_size, (void *) ed->d_buf);
+ goto done;
+ }
+
+ result = TET_PASS;
+
+done:
+ if (e)
+ elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ tet_result(result);
+}
+')
+
+FN(lsb,32)
+FN(lsb,64)
+FN(msb,32)
+FN(msb,64)
+
+/*
+ * Verify that a non-zero section is correctly read.
+ */
+
+static const char stringsection[] = {
+changequote({,})
+ '\0',
+ '.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', '\0',
+ '.', 'z', 'e', 'r', 'o', 's', 'e', 'c', 't', 'i', 'o', 'n', '\0'
+changequote
+ };
+
+undefine(`_FN')
+define(`_FN',`
+void
+tcNonZeroSection$1$2(void)
+{
+ Elf *e;
+ int error, fd, result;
+ const size_t strsectionsize = sizeof stringsection;
+ size_t n, shstrndx;
+ const char *buf;
+ Elf_Scn *scn;
+ Elf_Data *ed;
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ TP_ANNOUNCE("a data descriptor for a non-zero sized section "
+ "is correctly retrieved");
+
+ _TS_OPEN_FILE(e, "zerosection.$1$2", ELF_C_READ, fd, goto done;);
+
+ if (elf_getshdrstrndx(e, &shstrndx) != 0 ||
+ (scn = elf_getscn(e, shstrndx)) == NULL) {
+ TP_UNRESOLVED("Cannot find string table section");
+ goto done;
+ }
+
+ ed = NULL;
+ if ((ed = elf_getdata(scn, ed)) == NULL) {
+ error = elf_errno();
+ TP_FAIL("elf_getdata failed %d \"%s\"", error,
+ elf_errmsg(error));
+ goto done;
+ }
+
+ if (ed->d_size != strsectionsize) {
+ TP_FAIL("Illegal values returned: d_size %d != expected %d",
+ (int) ed->d_size, strsectionsize);
+ goto done;
+ }
+
+ if (memcmp(stringsection, ed->d_buf, strsectionsize) != 0) {
+ buf = (const char *) ed->d_buf;
+ for (n = 0; n < strsectionsize; n++)
+ if (buf[n] != stringsection[n])
+ break;
+ TP_FAIL("String mismatch: buf[%d] \"%c\" != \"%c\"",
+ n, buf[n], stringsection[n]);
+ goto done;
+ }
+
+ result = TET_PASS;
+
+done:
+ if (e)
+ elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ tet_result(result);
+}
+')
+
+_FN(lsb,32)
+_FN(lsb,64)
+_FN(msb,32)
+_FN(msb,64)
diff --git a/test/libelf/tset/elf_getident/Makefile b/test/libelf/tset/elf_getident/Makefile
new file mode 100644
index 0000000000000..a6dac630bea72
--- /dev/null
+++ b/test/libelf/tset/elf_getident/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= getident.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_getident/getident.m4 b/test/libelf/tset/elf_getident/getident.m4
new file mode 100644
index 0000000000000..b2f9e9449e652
--- /dev/null
+++ b/test/libelf/tset/elf_getident/getident.m4
@@ -0,0 +1,168 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: getident.m4 1694 2011-08-02 04:34:35Z jkoshy $
+ */
+
+#include <ar.h>
+#include <libelf.h>
+#include <string.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+include(`elfts.m4')
+
+IC_REQUIRES_VERSION_INIT();
+
+void
+tcNullNull(void)
+{
+ int result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getident(NULL,...) fails with error ELF_E_ARGUMENT.");
+
+ result = TET_PASS;
+ if (elf_getident(NULL, NULL) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+ tet_result(result);
+}
+
+void
+tcNullSize(void)
+{
+ size_t dummy;
+ int result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getident(NULL,&foo) fails, and sets"
+ " `foo' to zero.");
+
+ dummy = (size_t) 0xdeadc0de;
+
+ result = TET_PASS;
+ if (elf_getident(NULL, &dummy) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT ||
+ dummy != 0)
+ result = TET_FAIL;
+ tet_result(result);
+
+}
+
+changequote({,})
+static char ar_file[] = "!<arch>\n"
+ "t/ 1151656346 1001 0 100644 5 `\n"
+ "Test\n";
+changequote
+
+void
+tcMainArIdent(void)
+{
+ Elf *e;
+ char *p;
+ size_t sz;
+ int result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("an ar(1) archive's ident is correctly returned.");
+
+ TS_OPEN_MEMORY(e, ar_file);
+
+ result = TET_PASS;
+ sz = (size_t) 0xdeadc0de;
+ if ((p = elf_getident(e, &sz)) == NULL ||
+ sz != SARMAG || strncmp(p, ARMAG, SARMAG))
+ result = TET_FAIL;
+ tet_result(result);
+}
+
+static char elf_file[] = "\177ELF\001\001\001 \001\000\000\000\000"
+ "\000\000\000\001\000\003\000\001\000\000\000\357\276\255\336"
+ "\000\000\000\000\000\000\000\000\003\000\000\0004\000 \000"
+ "\000\000(\000\000\000\000\000";
+
+void
+tcMainElfIdent(void)
+{
+ Elf *e;
+ char *p;
+ size_t sz;
+ int result;
+
+ TP_CHECK_INITIALIZATION();
+
+ tet_infoline("assertion: an ELF object's ident is correctly"
+ " returned.");
+
+ TS_OPEN_MEMORY(e, elf_file);
+
+ result = TET_PASS;
+ sz = (size_t) 0xdeadc0de;
+ if ((p = elf_getident(e, &sz)) == NULL ||
+ sz != EI_NIDENT ||
+ memcmp(elf_file, p, sz))
+ result = TET_FAIL;
+ tet_result(result);
+}
+
+
+static char unknown_data[] = "Revenge! Revenge!";
+
+void
+tcMainUnknownData(void)
+{
+ Elf *e;
+ char *p;
+ size_t sz;
+ int result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getident() returns the initial bytes of"
+ " an unknown data object.");
+
+ TS_OPEN_MEMORY(e, unknown_data);
+
+ result = TET_PASS;
+ sz = (size_t) 0xdeadc0de;
+ if ((p = elf_getident(e, &sz)) == NULL ||
+ sz != sizeof(unknown_data) ||
+ memcmp(p, unknown_data, sizeof(unknown_data)))
+ result = TET_FAIL;
+ tet_result(result);
+}
+
+/*
+ * TODO:
+ *
+ * - getident on an elf descriptor opened for WRITE should fail until
+ * an elf_update() is done.
+ *
+ */
diff --git a/test/libelf/tset/elf_getscn/Makefile b/test/libelf/tset/elf_getscn/Makefile
new file mode 100644
index 0000000000000..c32b552ddfce6
--- /dev/null
+++ b/test/libelf/tset/elf_getscn/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1189 2010-09-11 16:04:59Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= getscn.m4
+TS_YAML= newscn xscn-1 xscn-2
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_getscn/getscn.m4 b/test/libelf/tset/elf_getscn/getscn.m4
new file mode 100644
index 0000000000000..98b37e47924c0
--- /dev/null
+++ b/test/libelf/tset/elf_getscn/getscn.m4
@@ -0,0 +1,313 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: getscn.m4 1405 2011-02-05 07:53:03Z jkoshy $
+ */
+
+#include <ar.h>
+#include <libelf.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+IC_REQUIRES_VERSION_INIT();
+
+include(`elfts.m4')
+
+/*
+ * A NULL argument is handled correctly.
+ */
+void
+tcArgsNull(void)
+{
+ int error, result;
+ Elf_Scn *scn;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getscn(NULL,*) fails.");
+
+ result = TET_PASS;
+ if ((scn = elf_getscn(NULL, (size_t) 0)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn,
+ error, elf_errmsg(error));
+
+ tet_result(result);
+}
+
+/*
+ * elf_getscn(non-elf) fails.
+ */
+
+static char *nonelf = "This is not an ELF file.";
+
+void
+tcArgsNonElf(void)
+{
+ Elf *e;
+ Elf_Scn *scn;
+ int error, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getscn(non-elf) fails.");
+
+ TS_OPEN_MEMORY(e, nonelf);
+
+ result = TET_PASS;
+
+ if ((scn = elf_getscn(e, (size_t) 0)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn,
+ error, elf_errmsg(error));
+
+ (void) elf_end(e);
+
+ tet_result(result);
+}
+
+/*
+ * elf_getscn works for all sections in a file.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcElfAll$1$2(void)
+{
+ Elf *e;
+ Elf_Scn *scn;
+ int error, fd, result;
+ size_t nsections, n, r;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: elf_getscn() can retrieve all sections.");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;);
+
+ if (elf_getshnum(e, &nsections) == 0) {
+ TP_UNRESOLVED("elf_getshnum() failed.");
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ for (n = 0; n < nsections; n++) {
+ /* Retrieve the section ... */
+ if ((scn = elf_getscn(e, n)) == NULL) {
+ TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn,
+ error, elf_errmsg(error));
+ break;
+ }
+
+ /* ... and verify that the section has the correct index. */
+ if ((r = elf_ndxscn(scn)) != n) {
+ TP_FAIL("scn=%p ndx %d != %d.", (void *) scn, r, n);
+ break;
+ }
+ }
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+/*
+ * elf_getscn(e,nsections+1) returns NULL.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcElfRange$1$2(void)
+{
+ Elf *e;
+ Elf_Scn *scn;
+ int error, fd, result;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: elf_getscn(elf,nsections+1) fails.");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;);
+
+ if (elf_getshnum(e, &n) == 0) {
+ TP_UNRESOLVED("elf_getshnum() failed.");
+ goto done;
+ }
+
+ result = TET_PASS;
+ if ((scn = elf_getscn(e, n)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("scn=%p error=\"%s\".", (void *) scn,
+ elf_errmsg(error));
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+/*
+ * elf_getscn(e,*) fails with ELF_E_SECTION on malformed extended numbering.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcExSecNumError$1$2(void)
+{
+ Elf *e;
+ Elf_Scn *scn;
+ int error, fd, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: elf_getscn() fails on a malformed file.");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, "xscn-1.$2$1", ELF_C_READ, fd, goto done;);
+
+ result = TET_PASS;
+ if ((scn = elf_getscn(e, 0)) != NULL ||
+ (error = elf_errno()) != ELF_E_SECTION)
+ TP_FAIL("scn=%p, error=%d \"%s\".", (void *) scn,
+ error, elf_errmsg(error));
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+/*
+ * elf_getscn works correctly for a file with > SHN_XINDEX sections.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcExSecNumLast$1$2(void)
+{
+ Elf *e;
+ Elf_Scn *scn;
+ Elf$1_Shdr *sh;
+ int error, fd, result;
+ size_t n, r;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: elf_getscn() retrieves the last extended "
+ "section.");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, "xscn-2.$2$1", ELF_C_READ, fd, goto done;);
+
+ if (elf_getshnum(e, &n) == 0) {
+ TP_UNRESOLVED("elf_getshnum() failed.");
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ n--;
+
+ /* Retrieve the section ... */
+ if ((scn = elf_getscn(e, n)) == NULL) {
+ TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn,
+ error, elf_errmsg(error));
+ goto done;
+ }
+
+ /* ... and verify that the section has the correct index. */
+ if ((r = elf_ndxscn(scn)) != n) {
+ TP_FAIL("scn=%p ndx %d != %d.", (void *) scn, r, n);
+ goto done;
+ }
+
+ /* ... and check the type of the section too. */
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (sh->sh_type != SHT_STRTAB)
+ TP_FAIL("section[%d] has wrong type %d.", n, sh->sh_type);
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
diff --git a/test/libelf/tset/elf_getshnum/Makefile b/test/libelf/tset/elf_getshnum/Makefile
new file mode 100644
index 0000000000000..c356c49e32ad9
--- /dev/null
+++ b/test/libelf/tset/elf_getshnum/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1189 2010-09-11 16:04:59Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= getshnum.m4
+TS_YAML= newscn xscn-1 xscn-2
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_getshnum/getshnum.m4 b/test/libelf/tset/elf_getshnum/getshnum.m4
new file mode 100644
index 0000000000000..29e1e290bf093
--- /dev/null
+++ b/test/libelf/tset/elf_getshnum/getshnum.m4
@@ -0,0 +1,177 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: getshnum.m4 1416 2011-02-05 12:46:59Z jkoshy $
+ */
+
+#include <ar.h>
+#include <libelf.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+include(`elfts.m4')
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * A NULL `Elf' argument fails.
+ */
+void
+tcArgsNull(void)
+{
+ int error, result;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getshnum(NULL,*) fails.");
+
+ result = TET_PASS;
+ if (elf_getshnum(NULL, &n) != 0 ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("n=%d error=%d \"%s\".", n, error,
+ elf_errmsg(error));
+
+ tet_result(result);
+}
+
+/*
+ * elf_getshnum() on a non-ELF file fails.
+ */
+static char *nonelf = "This is not an ELF file.";
+
+void
+tcArgsNonElf(void)
+{
+ Elf *e;
+ size_t n;
+ int error, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getshnum(non-elf) fails.");
+
+ TS_OPEN_MEMORY(e, nonelf);
+
+ result = TET_PASS;
+ if (elf_getshnum(e, &n) != 0 ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("n=%d error=%d \"%s\".", n, error,
+ elf_errmsg(error));
+
+ (void) elf_end(e);
+
+ tet_result(result);
+}
+
+
+/*
+ * elf_getshnum() on a well-formed file succeeds.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcNormal$1$3`'TOUPPER($4)(void)
+{
+ Elf *e;
+ int fd, result;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($4)$1$3: elf_getshnum(elf) succeeds.");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, "$2.$4$3", ELF_C_READ, fd, goto done;);
+
+ result = TET_PASS;
+ if (elf_getshnum(e, &n) == 0 || n != $5)
+ TP_FAIL("n=%d, expected $5: error=\"%s\".", n,
+ elf_errmsg(-1));
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(N,newscn,32,lsb,3)
+FN(N,newscn,32,msb,3)
+FN(N,newscn,64,lsb,3)
+FN(N,newscn,64,msb,3)
+FN(X,`xscn-2',32,lsb,65538)
+FN(X,`xscn-2',32,msb,65538)
+FN(X,`xscn-2',64,lsb,65538)
+FN(X,`xscn-2',64,msb,65538)
+
+/*
+ * elf_getshnum() on a file with a malformed section number 0 fails.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcMalformedXscn$1$2(void)
+{
+ Elf *e;
+ int error, fd, result;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: elf_getshnum(elf) returns ELF_E_SECTION.");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, "xscn-1.$2$1", ELF_C_READ, fd, goto done;);
+
+ result = TET_PASS;
+ if ((elf_getshnum(e, &n) != 0 ||
+ (error = elf_errno()) != ELF_E_SECTION))
+ TP_FAIL("n=%d error=%d \"%s\".", n, error, elf_errmsg(error));
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
diff --git a/test/libelf/tset/elf_getshstrndx/Makefile b/test/libelf/tset/elf_getshstrndx/Makefile
new file mode 100644
index 0000000000000..617140429146e
--- /dev/null
+++ b/test/libelf/tset/elf_getshstrndx/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1189 2010-09-11 16:04:59Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= getshstrndx.m4
+TS_YAML= newscn xscn-1 xscn-2 xscn-3
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_getshstrndx/getshstrndx.m4 b/test/libelf/tset/elf_getshstrndx/getshstrndx.m4
new file mode 100644
index 0000000000000..6b2a40d32c132
--- /dev/null
+++ b/test/libelf/tset/elf_getshstrndx/getshstrndx.m4
@@ -0,0 +1,180 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: getshstrndx.m4 1404 2011-02-05 07:51:28Z jkoshy $
+ */
+
+#include <ar.h>
+#include <libelf.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+IC_REQUIRES_VERSION_INIT();
+
+include(`elfts.m4')
+
+/*
+ * A NULL `Elf' argument fails.
+ */
+void
+tcArgsNull(void)
+{
+ int error, result;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getshstrndx(NULL,*) fails.");
+
+ result = TET_PASS;
+ if (elf_getshstrndx(NULL, &n) != 0 ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("n=%d error=%d \"%s\".", n, error,
+ elf_errmsg(error));
+
+ tet_result(result);
+}
+
+/*
+ * elf_getshstrndx() on a non-ELF file fails.
+ */
+static char *nonelf = "This is not an ELF file.";
+
+void
+tcArgsNonElf(void)
+{
+ Elf *e;
+ size_t n;
+ int error, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_getshstrndx(non-elf) fails.");
+
+ TS_OPEN_MEMORY(e, nonelf);
+
+ result = TET_PASS;
+ if (elf_getshstrndx(e, &n) != 0 ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("n=%d error=%d \"%s\".", n, error,
+ elf_errmsg(error));
+
+ (void) elf_end(e);
+
+ tet_result(result);
+}
+
+
+/*
+ * elf_getshstrndx() on a well-formed file succeeds.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcNormal_$1$3`'TOUPPER($4)(void)
+{
+ Elf *e;
+ int fd, result;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($4)$1$3: elf_getshstrndx(elf) succeeds.");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, "$2.$4$3", ELF_C_READ, fd, goto done;);
+
+ n = ~ (size_t) 0;
+
+ result = TET_PASS;
+ if (elf_getshstrndx(e, &n) == 0 || n != $5)
+ TP_FAIL("n=%d, expected $5: error=\"%s\".", n,
+ elf_errmsg(-1));
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(N,newscn,32,lsb,1)
+FN(N,newscn,32,msb,1)
+FN(N,newscn,64,lsb,1)
+FN(N,newscn,64,msb,1)
+FN(X,`xscn-2',32,lsb,65537)
+FN(X,`xscn-2',32,msb,65537)
+FN(X,`xscn-2',64,lsb,65537)
+FN(X,`xscn-2',64,msb,65537)
+
+/*
+ * elf_getshstrndx() on a file with a malformed section #0 fails.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcMalformed_Xscn$1$2(void)
+{
+ Elf *e;
+ int error, fd, result;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: elf_getshstrndx(elf) returns ELF_E_SECTION.");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, "xscn-3.$2$1", ELF_C_READ, fd, goto done;);
+
+ n = ~(size_t) 0;
+ result = TET_PASS;
+ if ((elf_getshstrndx(e, &n) != 0 ||
+ (error = elf_errno()) != ELF_E_SECTION))
+ TP_FAIL("n=%d error=%d \"%s\".", n, error, elf_errmsg(error));
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
diff --git a/test/libelf/tset/elf_hash/Makefile b/test/libelf/tset/elf_hash/Makefile
new file mode 100644
index 0000000000000..22c506b194c13
--- /dev/null
+++ b/test/libelf/tset/elf_hash/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= hash.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_hash/hash.m4 b/test/libelf/tset/elf_hash/hash.m4
new file mode 100644
index 0000000000000..5a64f1da2e9cd
--- /dev/null
+++ b/test/libelf/tset/elf_hash/hash.m4
@@ -0,0 +1,101 @@
+/*-
+ * Copyright (c) 2006 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: hash.m4 2191 2011-11-21 08:34:02Z jkoshy $
+ */
+
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <libelf.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "tet_api.h"
+
+/*
+ * Test the `elf_hash' API.
+ */
+
+/*
+ * A motley collection of test strings.
+ */
+static struct htab {
+ const char *s;
+ unsigned long h;
+} htab[] = {
+#undef H
+#define H(S,V) { .s = (S), .h = (V) }
+ H("", 0),
+ H("\377\377\377\377", 0x10FFEfL),
+ H("\030\2265Q\023_;\312\214\212#f\001\220\224|",
+ 0xe07d55c),
+ H("elf-hash", 0x293ee58),
+ H(NULL, 0)
+};
+
+static void
+to_printable_string(char *dst, const char *src)
+{
+ int c;
+ char *s;
+
+ s = dst;
+ while (c = *src++) {
+ if (isprint(c))
+ *s++ = c;
+ else
+ s += sprintf(s, "\\%3.3o", (c & 0xFF));
+ }
+ *s = '\0';
+}
+
+void
+tpCheckHash(void)
+{
+ unsigned long h;
+ struct htab *ht;
+ int result;
+ char *tmp;
+
+ tet_infoline("assertion: check elf_hash() against several constant "
+ "strings.");
+
+ result = TET_PASS;
+ for (ht = htab; ht->s; ht++) {
+ if ((h = elf_hash(ht->s)) != ht->h) {
+ if ((tmp = malloc(4 * strlen(ht->s) + 1)) != NULL) {
+ to_printable_string(tmp, ht->s);
+ tet_printf("fail: elf_hash(\"%s\") = 0x%x != "
+ "expected 0x%x.", tmp, h, ht->h);
+ free(tmp);
+ }
+ result = TET_FAIL;
+ }
+ }
+ tet_result(result);
+}
diff --git a/test/libelf/tset/elf_kind/Makefile b/test/libelf/tset/elf_kind/Makefile
new file mode 100644
index 0000000000000..ba2aad90af92c
--- /dev/null
+++ b/test/libelf/tset/elf_kind/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= kind.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_kind/kind.m4 b/test/libelf/tset/elf_kind/kind.m4
new file mode 100644
index 0000000000000..ada6095ac3c9e
--- /dev/null
+++ b/test/libelf/tset/elf_kind/kind.m4
@@ -0,0 +1,122 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: kind.m4 1694 2011-08-02 04:34:35Z jkoshy $
+ */
+
+#include <libelf.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+include(`elfts.m4')
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * Test the `elf_kind' entry point.
+ */
+
+void
+tcNullParameter(void)
+{
+ TP_ANNOUNCE("NULL elf returns null.");
+
+ TP_CHECK_INITIALIZATION();
+
+ tet_result(elf_kind(NULL) == ELF_K_NONE ? TET_PASS : TET_FAIL);
+}
+
+static char elf_file[] = "\177ELF\001\001\001 \001\000\000\000\000"
+ "\000\000\000\001\000\003\000\001\000\000\000\357\276\255\336"
+ "\000\000\000\000\000\000\000\000\003\000\000\0004\000 \000"
+ "\000\000(\000\000\000\000\000";
+
+void
+tcValidElf(void)
+{
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("valid ELF file returns ELF_K_ELF.");
+
+ if ((e = elf_memory(elf_file, sizeof(elf_file))) == NULL) {
+ tet_printf("elf_memory: %s", elf_errmsg(-1));
+ tet_result(TET_UNRESOLVED);
+ return;
+ }
+
+ tet_result(elf_kind(e) == ELF_K_ELF ? TET_PASS : TET_FAIL);
+
+ (void) elf_end(e);
+}
+
+changequote({,})
+static char ar_file[] = "!<arch>\n"
+ "t/ 1151656346 1001 0 100644 5 `\n"
+ "Test\n";
+changequote
+
+void
+tcValidAr(void)
+{
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("valid ar archive returns ELF_K_AR.");
+
+ if ((e = elf_memory(ar_file, sizeof(ar_file))) == NULL) {
+ tet_printf("elf_memory: %s", elf_errmsg(-1));
+ tet_result(TET_UNRESOLVED);
+ return;
+ }
+
+ tet_result(elf_kind(e) == ELF_K_AR ? TET_PASS : TET_FAIL);
+
+ (void) elf_end(e);
+}
+
+static char unknown_file[] = "0xdeadc0de";
+
+void
+tcUnknownKind(void)
+{
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("unknown file type returns ELF_K_NONE.");
+
+ if ((e = elf_memory(unknown_file, sizeof(unknown_file))) == NULL) {
+ tet_printf("elf_memory: %s", elf_errmsg(-1));
+ tet_result(TET_UNRESOLVED);
+ }
+
+ tet_result(elf_kind(e) == ELF_K_NONE ? TET_PASS : TET_FAIL);
+
+ (void) elf_end(e);
+}
diff --git a/test/libelf/tset/elf_memory/Makefile b/test/libelf/tset/elf_memory/Makefile
new file mode 100644
index 0000000000000..3c67edf1e71a6
--- /dev/null
+++ b/test/libelf/tset/elf_memory/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= memory.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_memory/memory.m4 b/test/libelf/tset/elf_memory/memory.m4
new file mode 100644
index 0000000000000..da7ac7bc6d563
--- /dev/null
+++ b/test/libelf/tset/elf_memory/memory.m4
@@ -0,0 +1,240 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: memory.m4 1694 2011-08-02 04:34:35Z jkoshy $
+ */
+
+#include <ar.h>
+#include <libelf.h>
+#include <string.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+include(`elfts.m4')
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * Test the `elf_memory' entry point.
+ *
+ * See also: elf_memory() sequence tests in the test cases for elf_version().
+ */
+
+/*
+ * Check that a NULL memory pointer and a zero size arena size are
+ * rejected.
+ */
+
+void
+tcInvalidArgNullPtrs(void)
+{
+ Elf *e;
+
+ TP_ANNOUNCE("elf_memory(NULL,0) results in a NULL return"
+ " and an error return of ELF_E_ARGUMENT.");
+
+ TP_CHECK_INITIALIZATION();
+
+ if ((e = elf_memory(NULL, ~0)) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT) {
+ tet_result(TET_FAIL);
+ return;
+ }
+
+ if ((e = elf_memory((char *) &e, 0)) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT) {
+ tet_result(TET_FAIL);
+ return;
+ }
+
+ tet_result(TET_PASS);
+}
+
+static char elf_file[] = "\177ELF\001\001\001 \001\000\000\000\000"
+ "\000\000\000\001\000\003\000\001\000\000\000\357\276\255\336"
+ "\000\000\000\000\000\000\000\000\003\000\000\0004\000 \000"
+ "\000\000(\000\000\000\000\000";
+
+/*
+ * The next two test cases check a pointer to valid ELF content, but
+ * with (a) a valid object size and (b) a too-small object size.
+ */
+
+void
+tcValidElfValidSize(void)
+{
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("valid ELF contents and size are correctly"
+ " recognized as an ELF file.");
+
+ if ((e = elf_memory(elf_file, sizeof(elf_file))) == NULL ||
+ elf_kind(e) != ELF_K_ELF) {
+ tet_result(TET_FAIL);
+ return;
+ }
+
+ (void) elf_end(e);
+ tet_result(TET_PASS);
+}
+
+void
+tcValidElfInvalidSize(void)
+{
+ Elf *e;
+
+ TP_ANNOUNCE("a valid ELF prelude with a too-small size is"
+ " to be recognized as 'DATA'.");
+
+ TP_CHECK_INITIALIZATION();
+
+ /* Check size > SARMAG, but < EI_NIDENT */
+ if ((e = elf_memory(elf_file, EI_NIDENT-1)) == NULL ||
+ elf_kind(e) != ELF_K_NONE)
+ tet_result(TET_FAIL);
+
+ (void) elf_end(e);
+ tet_result(TET_PASS);
+}
+
+
+void
+tcInvalidElfSignature(void)
+{
+ Elf *e;
+ char newelf[sizeof(elf_file)];
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("an ELF-like object with an invalid signature"
+ " should be recognized as 'DATA'.");
+
+ memcpy(newelf, elf_file, sizeof(elf_file));
+ newelf[EI_MAG0] = '\1';
+
+ if ((e = elf_memory(newelf, sizeof(newelf))) == NULL ||
+ elf_kind(e) != ELF_K_NONE)
+ tet_result(TET_FAIL);
+
+ (void) elf_end(e);
+ tet_result(TET_PASS);
+}
+
+void
+tcInvalidElfVersionMismatch(void)
+{
+ Elf *e;
+ char newelf[sizeof(elf_file)];
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("an ELF blob with an invalid version number is"
+ " to be rejected, with error ELF_E_VERSION.");
+
+ memcpy(newelf, elf_file, sizeof(elf_file));
+ newelf[EI_VERSION] = EV_CURRENT+1; /* change version */
+
+ if ((e = elf_memory(newelf, sizeof(newelf))) != NULL ||
+ elf_errno() != ELF_E_VERSION)
+ tet_result(TET_FAIL);
+
+ (void) elf_end(e);
+ tet_result(TET_PASS);
+}
+
+/*
+ * `ar' archives.
+ */
+
+changequote({,})
+static char ar_file[] = "!<arch>\n"
+ "t/ 1151656346 1001 0 100644 5 `\n"
+ "Test\n";
+changequote
+
+void
+tcValidArValid(void)
+{
+ Elf *e;
+ TP_ANNOUNCE("an valid AR archive is accepted as type"
+ " ELF_K_AR.");
+
+ TP_CHECK_INITIALIZATION();
+
+ if ((e = elf_memory(ar_file, sizeof(ar_file))) == NULL ||
+ elf_kind(e) != ELF_K_AR)
+ tet_result(TET_FAIL);
+
+ (void) elf_end(e);
+ tet_result(TET_PASS);
+
+}
+
+void
+tcInvalidArInvalidSize(void)
+{
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("a too-small AR archive size is classified"
+ " as 'DATA'.");
+
+ if ((e = elf_memory(ar_file, SARMAG-1)) == NULL ||
+ elf_kind(e) != ELF_K_NONE)
+ tet_result(TET_FAIL);
+
+ (void) elf_end(e);
+ tet_result(TET_PASS);
+}
+
+void
+tcInvalidArSignature(void)
+{
+ Elf *e;
+ char not_an_archive[sizeof(ar_file)];
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("invalid signature for an archive -> unrecognized");
+
+ (void) memcpy(not_an_archive, ar_file, sizeof(not_an_archive));
+ not_an_archive[0] = '~';
+
+ if ((e = elf_memory(not_an_archive, sizeof(not_an_archive))) == NULL ||
+ elf_kind(e) != ELF_K_NONE)
+ tet_result(TET_FAIL);
+
+ (void) elf_end(e);
+ tet_result(TET_PASS);
+}
+
+/*
+ * TODO
+ * - `ar' archives with an archive symbol table.
+ */
diff --git a/test/libelf/tset/elf_ndxscn/Makefile b/test/libelf/tset/elf_ndxscn/Makefile
new file mode 100644
index 0000000000000..579f8867a7306
--- /dev/null
+++ b/test/libelf/tset/elf_ndxscn/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1189 2010-09-11 16:04:59Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= ndxscn.m4
+TS_YAML= newscn
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_ndxscn/ndxscn.m4 b/test/libelf/tset/elf_ndxscn/ndxscn.m4
new file mode 100644
index 0000000000000..5a8eb3b48cbc3
--- /dev/null
+++ b/test/libelf/tset/elf_ndxscn/ndxscn.m4
@@ -0,0 +1,119 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: ndxscn.m4 1415 2011-02-05 12:45:23Z jkoshy $
+ */
+
+#include <ar.h>
+#include <libelf.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+include(`elfts.m4')
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * A NULL argument is handled.
+ */
+void
+tcArgsNull(void)
+{
+ int error, result;
+ size_t shn;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_ndxscn(NULL) fails.");
+
+ result = TET_PASS;
+ if ((shn = elf_ndxscn(NULL)) != SHN_UNDEF ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("shn=%d error=%d \"%s\".", shn,
+ error, elf_errmsg(error));
+
+ tet_result(result);
+}
+
+/*
+ * elf_ndxscn() on a valid section succeeds.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcScnSuccess$1$2(void)
+{
+ Elf *e;
+ Elf_Scn *scn;
+ int fd, result;
+ size_t nscn, n, r;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: elf_ndxscn(elf) succeeds.");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;);
+
+ if (elf_getshnum(e, &nscn) == 0) {
+ TP_UNRESOLVED("elf_getshnum(old) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ result = TET_PASS;
+ for (n = SHN_UNDEF; n < nscn; n++) {
+ if ((scn = elf_getscn(e, n)) == NULL) {
+ TP_UNRESOLVED("elf_getscn(%d) failed: \"%s\".", n,
+ elf_errmsg(-1));
+ break;
+ }
+
+ if ((r = elf_ndxscn(scn)) != n) {
+ TP_FAIL("r=%d != %n, error=\"%s\".", r, n,
+ elf_errmsg(-1));
+ break;
+ }
+ }
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
diff --git a/test/libelf/tset/elf_newscn/Makefile b/test/libelf/tset/elf_newscn/Makefile
new file mode 100644
index 0000000000000..5aff1dea5a2ae
--- /dev/null
+++ b/test/libelf/tset/elf_newscn/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1189 2010-09-11 16:04:59Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= newscn.m4
+TS_YAML= newscn
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_newscn/newscn.m4 b/test/libelf/tset/elf_newscn/newscn.m4
new file mode 100644
index 0000000000000..db76058abe645
--- /dev/null
+++ b/test/libelf/tset/elf_newscn/newscn.m4
@@ -0,0 +1,290 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: newscn.m4 1389 2011-01-26 02:31:24Z jkoshy $
+ */
+
+#include <ar.h>
+#include <libelf.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+IC_REQUIRES_VERSION_INIT();
+
+include(`elfts.m4')
+
+/*
+ * A null argument is handled.
+ */
+void
+tcArgsNull(void)
+{
+ int error, result;
+ Elf_Scn *scn;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_newscn(NULL) fails.");
+
+ result = TET_PASS;
+ if ((scn = elf_newscn(NULL)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn,
+ error, elf_errmsg(error));
+
+ tet_result(result);
+}
+
+/*
+ * An ELF descriptor for a data file is rejected.
+ */
+static char *nonelf = "This is not an ELF file.";
+
+void
+tcArgsNonElf(void)
+{
+ Elf *e;
+ Elf_Scn *scn;
+ int error, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_newscn(non-elf) fails.");
+
+ TS_OPEN_MEMORY(e, nonelf);
+
+ result = TET_PASS;
+
+ if ((scn = elf_newscn(e)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn,
+ error, elf_errmsg(error));
+
+ (void) elf_end(e);
+
+ tet_result(result);
+}
+
+/*
+ * elf_newscn() on a valid elf file succeeds.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcElfSuccess$1$2(void)
+{
+ Elf *e;
+ Elf_Scn *scn;
+ int fd, result;
+ size_t oldn, newn;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: elf_newscn(read-only-elf) succeeds.");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;);
+
+ if (elf_getshnum(e, &oldn) == 0) {
+ TP_UNRESOLVED("elf_getshnum(old) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_FAIL("elf_newscn() failed: error=\"%s\".",
+ elf_errmsg(-1));
+ result = TET_FAIL;
+ goto done;
+ }
+
+ if (elf_getshnum(e, &newn) == 0) {
+ TP_UNRESOLVED("elf_getshnum(new) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ result = TET_PASS;
+ if (newn != (oldn + 1))
+ TP_FAIL("newn %d != oldn %d + 1.", newn, oldn);
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+/*
+ * elf_newscn() sets the dirty bit on the new descriptor.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcAllocateDirty$1$2(void)
+{
+ Elf *e;
+ Elf_Scn *scn;
+ int fd, result;
+ unsigned int flags;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: newly returned section is \"dirty\".");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;);
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_newscn() failed: error=\"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ result = TET_PASS;
+ if ((flags = elf_flagscn(scn, ELF_C_SET, 0U)) != ELF_F_DIRTY)
+ TP_FAIL("flags=0x%x != 0x%x.", flags, ELF_F_DIRTY);
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+/*
+ * elf_newscn() on a file with lacking an ehdr fails.
+ */
+
+void
+tcAllocateNoEhdr(void)
+{
+ Elf *e;
+ Elf_Scn *scn;
+ int error, fd, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_newscn() fails without an EHdr.");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;);
+
+ result = TET_PASS;
+ if ((scn = elf_newscn(e)) != NULL ||
+ (error = elf_errno()) != ELF_E_CLASS)
+ TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn,
+ error, elf_errmsg(error));
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);
+
+ tet_result(result);
+}
+
+/*
+ * elf_newscn() on a new file returns a section descriptor with index 1.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcAllocateNew$1$2(void)
+{
+ Elf *e;
+ Elf_Scn *scn;
+ Elf$1_Ehdr *eh;
+ int fd, result;
+ size_t ndx;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: newly returned section is \"dirty\".");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;);
+
+ if ((eh = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: error=\"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_newscn() failed: error=\"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ result = TET_PASS;
+ if ((ndx = elf_ndxscn(scn)) != 1U)
+ TP_FAIL("ndx=%d.", ndx);
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
diff --git a/test/libelf/tset/elf_next/Makefile b/test/libelf/tset/elf_next/Makefile
new file mode 100644
index 0000000000000..179b45748a0b4
--- /dev/null
+++ b/test/libelf/tset/elf_next/Makefile
@@ -0,0 +1,36 @@
+# $Id: Makefile 1156 2010-09-02 08:55:45Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= next.m4
+TS_DATA= a1.ar a1.o a2.ar a2.o a3.ar
+TS_LONGNAME= s------------------------2
+CLEANFILES+= a1.c a2.c s1 ${TS_LONGNAME} "s 3"
+
+s1:
+ echo 'This is s1.' > ${.TARGET}
+${TS_LONGNAME}:
+ echo ${TS_LONGNAME} > ${.TARGET}
+
+# a1.ar contains short names only; a2.ar contains long names; a3.ar contains ELF binaries
+# and a symbol table.
+
+a1.c: .SILENT
+ echo "int a1;" > ${.TARGET}
+a2.c: .SILENT
+ echo "int a2;" > ${.TARGET}
+
+a1.ar: s1 .SILENT
+ rm -f ${.TARGET}
+ echo 's-3.' > "s 3"
+ ${AR} crv ${.TARGET} s1 "s 3" > /dev/null
+
+a2.ar: s1 ${TS_LONGNAME} .SILENT
+ rm -f ${.TARGET}
+ ${AR} crv ${.TARGET} ${.ALLSRC} > /dev/null
+
+a3.ar: s1 ${TS_LONGNAME} a1.o a2.o .SILENT
+ rm -f ${.TARGET}
+ ${AR} crv ${.TARGET} ${.ALLSRC} > /dev/null
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_next/next.m4 b/test/libelf/tset/elf_next/next.m4
new file mode 100644
index 0000000000000..8611de6fee494
--- /dev/null
+++ b/test/libelf/tset/elf_next/next.m4
@@ -0,0 +1,151 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: next.m4 1622 2011-07-07 11:48:35Z jkoshy $
+ */
+
+#include <libelf.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+
+#include "elfts.h"
+
+IC_REQUIRES_VERSION_INIT();
+
+include(`elfts.m4')
+
+/*
+ * Test the `elf_next' API.
+ */
+
+/*
+ * Assertion: with a NULL value passed in, elf_next returns ELF_C_NULL.
+ */
+void
+tcArgsNull(void)
+{
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("NULL argument returns ELF_C_NULL");
+
+ tet_result(elf_next(NULL) == ELF_C_NULL ? TET_PASS : TET_FAIL);
+}
+
+/*
+ * Invoking elf_next on a non-archive should return ELF_C_NULL.
+ */
+
+static char *notar = "This is not an AR archive.";
+static char *elf = "\177ELF\001\001\001 \001\000\000\000\000"
+ "\000\000\000\001\000\003\000\001\000\000\000\357\276\255\336"
+ "\000\000\000\000\000\000\000\000\003\000\000\0004\000 \000"
+ "\000\000(\000\000\000\000\000";
+
+undefine(`FN')
+define(`FN',`
+void
+tcArgsNonAr`'TOUPPER($1)(void)
+{
+ Elf *e;
+ Elf_Cmd c;
+ int result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("error ELF_C_NULL with a non-archive \"$1\".");
+
+ TS_OPEN_MEMORY(e, $1);
+
+ result = TET_PASS;
+ if ((c = elf_next(e)) != ELF_C_NULL)
+ TP_FAIL("\"$1\" c=%d, != ELF_C_NULL", c);
+
+ (void) elf_end(e);
+
+ tet_result(result);
+}')
+
+FN(notar)
+FN(elf)
+
+/*
+ * FN(ar-file-name, count)
+ *
+ * Returns ELF_C_READ as expected for an archive with > 1 members (as measured
+ * by the number of ELF_C_READ return values).
+ *
+ * The test cases for elf_begin() verify that the correct Elf * pointers get
+ * returned by a subsequent call to elf_begin().
+ *
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcArArchive$1(void)
+{
+ int error, fd, i, result;
+ Elf_Cmd c;
+ Elf *a, *e;
+
+ TP_ANNOUNCE("correctly iterates through \"a$1.ar\" with $2 members.");
+
+ result = TET_UNRESOLVED;
+ a = e = NULL;
+ fd = -1;
+ i = 0;
+
+ _TS_OPEN_FILE(a, "a$1.ar", ELF_C_READ, fd, goto done;);
+
+ (void) elf_errno();
+ c = ELF_C_READ;
+ while ((e = elf_begin(fd, c, a)) != NULL) {
+ c = elf_next(e);
+ (void) elf_end(e);
+ i++;
+ }
+
+ if ((error = elf_errno()) != ELF_E_NONE) {
+ TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+ if (i != $2)
+ TP_FAIL("i=%d expected $2.", i);
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(1, 2) dnl text files with short names
+FN(2, 2) dnl text files with long names
+FN(3, 4) dnl text files + ELF objects.
+
diff --git a/test/libelf/tset/elf_nextscn/Makefile b/test/libelf/tset/elf_nextscn/Makefile
new file mode 100644
index 0000000000000..2284967f895fa
--- /dev/null
+++ b/test/libelf/tset/elf_nextscn/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1189 2010-09-11 16:04:59Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= nextscn.m4
+TS_YAML= newscn
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_nextscn/nextscn.m4 b/test/libelf/tset/elf_nextscn/nextscn.m4
new file mode 100644
index 0000000000000..c9315a125f2bc
--- /dev/null
+++ b/test/libelf/tset/elf_nextscn/nextscn.m4
@@ -0,0 +1,378 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: nextscn.m4 1385 2011-01-23 15:10:19Z jkoshy $
+ */
+
+#include <ar.h>
+#include <libelf.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+IC_REQUIRES_VERSION_INIT();
+
+include(`elfts.m4')
+
+/*
+ * Null arguments are handled correctly.
+ */
+void
+tcArgsNull(void)
+{
+ int error, result;
+ Elf_Scn *scn;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_nextscn(NULL,*) fails.");
+
+ result = TET_PASS;
+ if ((scn = elf_nextscn(NULL, NULL)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn,
+ error, elf_errmsg(error));
+
+ tet_result(result);
+}
+
+/*
+ * elf_nextscn(non-elf) fails.
+ */
+
+static char *nonelf = "This is not an ELF file.";
+
+void
+tcArgsNonElf(void)
+{
+ Elf *e;
+ Elf_Scn *scn;
+ int error, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_nextscn(non-elf) fails.");
+
+ TS_OPEN_MEMORY(e, nonelf);
+
+ result = TET_PASS;
+
+ if ((scn = elf_nextscn(e, NULL)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn,
+ error, elf_errmsg(error));
+
+ (void) elf_end(e);
+
+ tet_result(result);
+}
+
+/*
+ * elf_nextscn(e,NULL) returns section number 1.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcElfSuccess$1$2(void)
+{
+ Elf *e;
+ Elf_Scn *scn;
+ int fd, result;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: elf_nextscn(elf,NULL) succeeds.");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;);
+
+ result = TET_PASS;
+ if ((scn = elf_nextscn(e, NULL)) == NULL) {
+ TP_FAIL("elf_newscn() failed: error=\"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((n = elf_ndxscn(scn)) != 1)
+ TP_FAIL("elf_nextscn() returned index %d.", n);
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+/*
+ * elf_nextscn(new-elf, last-section) returns NULL and no error.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcElfLastNewFile$1(void)
+{
+ Elf *e;
+ Elf_Scn *scn, *nextscn;
+ Elf$1_Ehdr *eh;
+ int error, fd, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_nextscn(newelf,last-scn) returns NULL.");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+
+ _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;);
+
+ if ((eh = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_newscn() failed.");
+ goto done;
+ }
+
+ (void) elf_errno();
+
+ result = TET_PASS;
+ if ((nextscn = elf_nextscn(e, scn)) != NULL ||
+ (error = elf_errno()) != ELF_E_NONE)
+ TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn,
+ error, elf_errmsg(error));
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);
+
+ tet_result(result);
+}')
+
+FN(32)
+FN(64)
+
+
+/*
+ * elf_nextscn(old-elf, last-section) returns NULL and no error.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcElfLastOldFile$2$1(void)
+{
+ Elf *e;
+ Elf_Scn *scn, *nextscn;
+ int error, fd, result;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_nextscn(oldelf,last-scn) returns NULL.");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;);
+
+ if (elf_getshnum(e, &n) == 0) {
+ TP_UNRESOLVED("elf_getshnum() failed.");
+ goto done;
+ }
+
+ if ((scn = elf_getscn(e, n - 1)) == NULL) {
+ TP_UNRESOLVED("elf_getscn(%d) failed.", (n-1));
+ goto done;
+ }
+
+ (void) elf_errno();
+
+ result = TET_PASS;
+ if ((nextscn = elf_nextscn(e, scn)) != NULL ||
+ (error = elf_errno()) != ELF_E_NONE)
+ TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn,
+ error, elf_errmsg(error));
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+/*
+ * elf_nextscn(iterates through sections in ascending order.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcElfAscending$2$1(void)
+{
+ Elf *e;
+ Elf_Scn *scn, *oldscn;
+ int error, fd, result;
+ size_t nsections, n, r;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_nextscn(elf,last-scn) returns NULL.");
+
+ e = NULL;
+ fd = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;);
+
+ if (elf_getshnum(e, &nsections) == 0) {
+ TP_UNRESOLVED("elf_getshnum() failed.");
+ goto done;
+ }
+
+ if ((oldscn = elf_getscn(e, 0)) == NULL) {
+ TP_UNRESOLVED("elf_getscn(0) failed.");
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ for (n = 0; n < nsections-1; n++) {
+ if ((scn = elf_nextscn(e, oldscn)) == NULL) {
+ TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn,
+ error, elf_errmsg(error));
+ goto done;
+ }
+
+ if ((r = elf_ndxscn(scn)) != n+1) {
+ TP_FAIL("scn=%p ndx %d != %d.", (void *) scn, r, n+1);
+ goto done;
+ }
+ oldscn = scn;
+ }
+
+ /* check the last one */
+ if ((scn = elf_nextscn(e, oldscn)) != NULL ||
+ (r = elf_ndxscn(oldscn)) != (nsections-1))
+ TP_FAIL("scn=%p r=%d", (void *) scn, r);
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+
+/*
+ * elf_nextscn() returns an error on mismatched Elf,Scn.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcElfMismatch$2$1(void)
+{
+ Elf *e1, *e2;
+ Elf_Scn *scn, *nextscn;
+ int error, fd1, fd2, result;
+ size_t n;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_nextscn(e1,scn-not-of-e1) fails.");
+
+ e1 = e2 = NULL;
+ fd1 = fd2 = -1;
+ result = TET_UNRESOLVED;
+
+ _TS_OPEN_FILE(e1, "newscn.$2$1", ELF_C_READ, fd1, goto done;);
+ _TS_OPEN_FILE(e2, TS_NEWFILE, ELF_C_WRITE, fd2, goto done;);
+
+ if ((scn = elf_getscn(e1, 0)) == NULL) {
+ TP_UNRESOLVED("elf_getscn(%d) failed.", (n-1));
+ goto done;
+ }
+
+ result = TET_PASS;
+ if ((nextscn = elf_nextscn(e2, scn)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn,
+ error, elf_errmsg(error));
+
+ done:
+ if (e1)
+ (void) elf_end(e1);
+ if (e2)
+ (void) elf_end(e2);
+ if (fd1 != -1)
+ (void) close(fd1);
+ if (fd2 != -1)
+ (void) close(fd2);
+ (void) unlink(TS_NEWFILE);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
diff --git a/test/libelf/tset/elf_rawfile/Makefile b/test/libelf/tset/elf_rawfile/Makefile
new file mode 100644
index 0000000000000..cb543cb1bbb3d
--- /dev/null
+++ b/test/libelf/tset/elf_rawfile/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= rawfile.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_rawfile/rawfile.m4 b/test/libelf/tset/elf_rawfile/rawfile.m4
new file mode 100644
index 0000000000000..a8beda1c8be32
--- /dev/null
+++ b/test/libelf/tset/elf_rawfile/rawfile.m4
@@ -0,0 +1,154 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: rawfile.m4 1694 2011-08-02 04:34:35Z jkoshy $
+ */
+
+#include <libelf.h>
+#include <string.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+include(`elfts.m4')
+
+/*
+ * Test the `elf_rawfile' entry point.
+ */
+
+IC_REQUIRES_VERSION_INIT();
+
+/*
+ * A NULL `elf *' argument should return the appropriate error,
+ * and set the `sz' pointer to zero.
+ */
+void
+tcNullNonNull(void)
+{
+ size_t sz;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_rawfile(NULL,...) returns an error,"
+ " and sets the size pointer to zero.");
+
+ sz = -1;
+ if (elf_rawfile(NULL, &sz) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT ||
+ sz != 0)
+ tet_result(TET_FAIL);
+ else
+ tet_result(TET_PASS);
+}
+
+changequote({,})
+static char ar_file[] = "!<arch>\n"
+ "t/ 1151656346 1001 0 100644 5 `\n"
+ "Test\n";
+changequote
+
+void
+tcValidAr(void)
+{
+ char *p;
+ Elf *e;
+ size_t sz;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_rawfile(E,...) descriptor with a valid"
+ " descriptor `E' to an ar(1) archive succeeds and returns"
+ " correct values.");
+
+ TS_OPEN_MEMORY(e, ar_file);
+
+ if ((p = elf_rawfile(e, &sz)) == NULL ||
+ sz != sizeof(ar_file) ||
+ memcmp(p, ar_file, sizeof(ar_file)))
+ tet_result(TET_FAIL);
+ else
+ tet_result(TET_PASS);
+
+ (void) elf_end(e);
+}
+
+static char elf_file[] = "\177ELF\001\001\001 \001\000\000\000\000"
+ "\000\000\000\001\000\003\000\001\000\000\000\357\276\255\336"
+ "\000\000\000\000\000\000\000\000\003\000\000\0004\000 \000"
+ "\000\000(\000\000\000\000\000";
+
+void
+tcValidElf(void)
+{
+ char *p;
+ Elf *e;
+ size_t sz;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_rawfile(E,...) descriptor with a valid"
+ " descriptor `E' to an ELF object succeeds and returns"
+ " correct values.");
+
+ TS_OPEN_MEMORY(e, elf_file);
+
+ if ((p = elf_rawfile(e, &sz)) == NULL ||
+ sz != sizeof(elf_file) ||
+ memcmp(p, elf_file, sizeof(elf_file)))
+ tet_result(TET_FAIL);
+ else
+ tet_result(TET_PASS);
+
+ (void) elf_end(e);
+}
+
+void
+tcValidNull(void)
+{
+ char *p;
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("assertion: elf_rawfile(E,NULL) on a valid descriptor "
+ "`E' and NULL sz pointer succeeds and returns the correct "
+ "value.");
+
+ TS_OPEN_MEMORY(e, elf_file);
+
+ if ((p = elf_rawfile(e, NULL)) == NULL ||
+ memcmp(p, elf_file, sizeof(elf_file)))
+ tet_result(TET_FAIL);
+ else
+ tet_result(TET_PASS);
+
+ (void) elf_end(e);
+}
+
+/*
+ * Todo:
+ *
+ * Test elf_rawfile() on an ELF object embedded inside an `ar' archive.
+ */
diff --git a/test/libelf/tset/elf_strptr/Makefile b/test/libelf/tset/elf_strptr/Makefile
new file mode 100644
index 0000000000000..9e3ec2b42d711
--- /dev/null
+++ b/test/libelf/tset/elf_strptr/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1189 2010-09-11 16:04:59Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= strptr.m4
+TS_YAML= newscn xscn-2
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_strptr/strptr.m4 b/test/libelf/tset/elf_strptr/strptr.m4
new file mode 100644
index 0000000000000..b89dfcc0d9df3
--- /dev/null
+++ b/test/libelf/tset/elf_strptr/strptr.m4
@@ -0,0 +1,363 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: strptr.m4 1380 2011-01-23 07:21:25Z jkoshy $
+ */
+
+#include <errno.h>
+#include <libelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "tet_api.h"
+
+#include "elfts.h"
+
+IC_REQUIRES_VERSION_INIT();
+
+include(`elfts.m4')
+
+/*
+ * A Null ELF value is rejected.
+ */
+
+void
+tcArgsNull(void)
+{
+ int error, result;
+ char *r;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_strptr(NULL,*,*) fails.");
+
+ result = TET_PASS;
+ if ((r = elf_strptr(NULL, (size_t) 0, (size_t) 0)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("r=%p error=%d \"%s\".", r, error, elf_errmsg(error));
+
+ tet_result(result);
+}
+
+/*
+ * An illegal section index is rejected.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcArgsIllegalSection$1`'TOUPPER($2)(void)
+{
+ int error, fd, result;
+ Elf *e;
+ char *r;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: a non-STRTAB section is rejected.");
+
+ _TS_OPEN_FILE(e, "$3.$2$1", ELF_C_READ, fd, goto done;);
+
+ result = TET_PASS;
+ if ((r = elf_strptr(e, SHN_UNDEF, (size_t) 0)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("r=%p error=%d \"%s\".", r, error,
+ elf_errmsg(error));
+
+ done:
+ (void) elf_end(e);
+ tet_result(result);
+}')
+
+FN(32,`lsb',`newscn')
+FN(32,`msb',`newscn')
+FN(64,`lsb',`newscn')
+FN(64,`msb',`newscn')
+
+/*
+ * An invalid section offset is rejected.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcArgsIllegalOffset$1`'TOUPPER($2)(void)
+{
+ Elf *e;
+ char *r;
+ Elf_Scn *scn;
+ Elf$1_Ehdr *eh;
+ Elf$1_Shdr *sh;
+ int error, fd, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: invalid offsets are rejected.");
+
+ _TS_OPEN_FILE(e, "$3.$2$1", ELF_C_READ, fd, goto done;);
+
+ if ((eh = elf$1_getehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_getehdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((scn = elf_getscn(e, eh->e_shstrndx)) == NULL) {
+ TP_UNRESOLVED("elf_getscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr() faied: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ result = TET_PASS;
+ if ((r = elf_strptr(e, eh->e_shstrndx, sh->sh_size)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("r=%p error=%d \"%s\".", (void *) r, error,
+ elf_errmsg(error));
+
+ /* Try a very large value */
+ if ((r = elf_strptr(e, eh->e_shstrndx, ~ (size_t) 0)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("r=%p error=%d \"%s\".", (void *) r, error,
+ elf_errmsg(error));
+
+ done:
+ (void) elf_end(e);
+ tet_result(result);
+}')
+
+FN(32,`lsb',`newscn')
+FN(32,`msb',`newscn')
+FN(64,`lsb',`newscn')
+FN(64,`msb',`newscn')
+
+/*
+ * A section index inside a 'hole' is rejected.
+ */
+
+static char teststring[] = {
+ 'a', 'b', 'c', 'd', '\0'
+};
+
+undefine(`FN')
+define(`FN',`
+void
+tcArgsOffsetInHole$1`'TOUPPER($2)(void)
+{
+ int error, fd, result;
+ Elf *e;
+ size_t sz;
+ Elf_Scn *scn;
+ Elf_Data *d;
+ Elf$1_Shdr *sh;
+ Elf$1_Ehdr *eh;
+ char *r;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: invalid offsets are rejected.");
+
+ _TS_OPEN_FILE(e, "$3.$2$1", ELF_C_READ, fd, goto done;);
+
+ if ((eh = elf$1_getehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_getehdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((scn = elf_getscn(e, eh->e_shstrndx)) == NULL) {
+ TP_UNRESOLVED("elf_getscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr(): failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Get the current size of the section. */
+ sz = sh->sh_size;
+
+ /* Add a new data descriptor to the section. */
+ if ((d = elf_newdata(scn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ d->d_align = 512;
+ d->d_buf = teststring;
+ d->d_size = sizeof(teststring);
+
+ /* Resync. */
+ if (elf_update(e, ELF_C_NULL) < 0) {
+ TP_UNRESOLVED("elf_update() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ /* first byte offset in the "hole". */
+ if ((r = elf_strptr(e, eh->e_shstrndx, sz)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("r=%p offset=%d error=%d \"%s\".", (void *) r, sz,
+ error, elf_errmsg(error));
+
+ /* last offset in the "hole". */
+ if ((r = elf_strptr(e, eh->e_shstrndx, (size_t) d->d_align - 1)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("r=%p offset=%d error=%d \"%s\".", (void *) r, (d->d_align-1),
+ error, elf_errmsg(error));
+
+ /* offset after the new end of the section. */
+ if ((r = elf_strptr(e, eh->e_shstrndx, (size_t) d->d_align + d->d_size)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("r=%p offset=%d error=%d \"%s\".", (void *) r,
+ (d->d_align+d->d_size), error, elf_errmsg(error));
+
+ done:
+ (void) elf_end(e);
+ tet_result(result);
+}')
+
+FN(32,`lsb',`newscn')
+FN(32,`msb',`newscn')
+FN(64,`lsb',`newscn')
+FN(64,`msb',`newscn')
+
+/*
+ * Check that all strings have their correct offsets.
+ */
+
+struct refstr {
+ size_t offset;
+ char *string;
+} refstr[] = {
+ /* From the newscn.* file. */
+ { .offset = 0, .string = "" },
+ { .offset = 1, .string = ".shstrtab" },
+ { .offset = 11, .string = ".foobar" },
+#define NSTATIC 3
+ /* added by test case() */
+ { .offset = 512, .string = "abcd" }
+};
+
+undefine(`FN')
+define(`FN',`
+void
+tcArgsValidOffset$1`'TOUPPER($2)(void)
+{
+ int error, fd, result;
+ Elf *e;
+ Elf_Scn *scn;
+ Elf_Data *d;
+ Elf$1_Shdr *sh;
+ Elf$1_Ehdr *eh;
+ char *r;
+ struct refstr *rs;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: invalid offsets are rejected.");
+
+ _TS_OPEN_FILE(e, "$3.$2$1", ELF_C_READ, fd, goto done;);
+
+ if ((eh = elf$1_getehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_getehdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((scn = elf_getscn(e, eh->e_shstrndx)) == NULL) {
+ TP_UNRESOLVED("elf_getscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr(): failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ for (rs = refstr; rs < &refstr[NSTATIC]; rs++)
+ if ((r = elf_strptr(e, eh->e_shstrndx, rs->offset)) == NULL ||
+ strcmp(r, rs->string) != 0) {
+ TP_FAIL("r=\"%s\" rs=\"%s\" offset=%d error=\"%s\".",
+ r, rs->string, rs->offset, elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Add a new data descriptor to the section. */
+ if ((d = elf_newdata(scn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ d->d_align = 512;
+ d->d_buf = teststring;
+ d->d_size = sizeof(teststring);
+
+ /* Resync. */
+ if (elf_update(e, ELF_C_NULL) < 0) {
+ TP_UNRESOLVED("elf_update() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ /* first byte offset in the "hole". */
+ if ((r = elf_strptr(e, eh->e_shstrndx, rs->offset)) == NULL ||
+ strcmp(r, rs->string) != 0)
+ TP_FAIL("r=\"%s\" rs=\"%s\" offset=%d error=\"%s\".", r,
+ rs->string, rs->offset, elf_errmsg(error));
+
+ done:
+ (void) elf_end(e);
+ tet_result(result);
+}')
+
+FN(32,`lsb',`newscn')
+FN(32,`msb',`newscn')
+FN(64,`lsb',`newscn')
+FN(64,`msb',`newscn')
+
+/*
+ * TODO: With the layout bit set, an out of bounds offset is detected.
+ */
+
+/*
+ * TODO: With the layout bit set, strings are correctly retrieved.
+ */
+
diff --git a/test/libelf/tset/elf_update/Makefile b/test/libelf/tset/elf_update/Makefile
new file mode 100644
index 0000000000000..d2b4d6701d0d5
--- /dev/null
+++ b/test/libelf/tset/elf_update/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1705 2011-08-09 08:48:36Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= update.m4
+TS_YAML= newehdr newscn newscn2 rdwr rdwr1 rdwr2 u1
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_update/update.m4 b/test/libelf/tset/elf_update/update.m4
new file mode 100644
index 0000000000000..e1d3e6b33f534
--- /dev/null
+++ b/test/libelf/tset/elf_update/update.m4
@@ -0,0 +1,2308 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: update.m4 2833 2012-12-30 16:16:51Z jkoshy $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <gelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elfts.h"
+
+#include "tet_api.h"
+
+include(`elfts.m4')
+define(`TS_OFFSET_SHDR',512)
+define(`MAKE_EM',
+ `ifelse($1,32,
+ ifelse($2,msb,EM_SPARC,EM_386),
+ ifelse($2,msb,EM_SPARCV9,EM_X86_64))')
+
+/*
+ * Tests for the `elf_update' API.
+ */
+
+IC_REQUIRES_VERSION_INIT();
+
+static char rawdata[] = "This is not an ELF file.";
+
+/*
+ * A NULL Elf argument returns ELF_E_ARGUMENT.
+ */
+
+void
+tcArgsNull(void)
+{
+ int error, result;
+ off_t offset;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_update(NULL,*) fails with ELF_E_ARGUMENT.");
+
+ if ((offset = elf_update(NULL, 0)) != (off_t) -1) {
+ TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.",
+ (intmax_t) offset);
+ goto done;
+ }
+
+ if ((error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("elf_update() did not fail with ELF_E_ARGUMENT; "
+ "error=%d \"%s\".", error, elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ tet_result(result);
+}
+
+/*
+ * Illegal values for argument `cmd' are rejected.
+ */
+
+void
+tcArgsBadCmd(void)
+{
+ Elf *e;
+ Elf_Cmd c;
+ int error, result;
+ off_t offset;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("illegal cmd values are rejected with ELF_E_ARGUMENT.");
+
+ TS_OPEN_MEMORY(e, rawdata);
+
+ result = TET_PASS;
+ for (c = ELF_C_NULL-1; result == TET_PASS && c < ELF_C_NUM; c++) {
+ if (c == ELF_C_WRITE || c == ELF_C_NULL) /* legal values */
+ continue;
+ if ((offset = elf_update(e, c)) != (off_t) -1)
+ TP_FAIL("elf_update() succeeded unexpectedly; "
+ "offset=%jd.", (intmax_t) offset);
+ else if ((error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("elf_update() did not fail with "
+ "ELF_E_ARGUMENT; error=%d \"%s\".", error,
+ elf_errmsg(error));
+ }
+
+ (void) elf_end(e);
+ tet_result(result);
+}
+
+/*
+ * Non-ELF descriptors are rejected by elf_update().
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcArgsNonElf$1(void)
+{
+ Elf *e;
+ int error, fd, result;
+ off_t offset;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_update(non-elf,ELF_C_$1) returns ELF_E_ARGUMENT.");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+
+ _TS_WRITE_FILE(TS_NEWFILE,rawdata,sizeof(rawdata),goto done;);
+ _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_READ, fd, goto done;);
+
+ if ((offset = elf_update(e, ELF_C_$1)) != (off_t) -1) {
+ TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.",
+ (intmax_t) offset);
+ goto done;
+ }
+
+ if ((error = elf_errno()) != ELF_E_ARGUMENT) {
+ TP_FAIL("elf_update() did not fail with ELF_E_ARGUMENT; "
+ "error=%d \"%s\".", error, elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);
+
+ tet_result(result);
+}')
+
+FN(`NULL')
+FN(`WRITE')
+
+/*
+ * In-memory (i.e., non-writeable) ELF objects are rejected for
+ * ELF_C_WRITE with error ELF_E_MODE.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcMemElfWrite$1$2(void)
+{
+ Elf *e;
+ off_t offset;
+ int error, result;
+ char elf[sizeof(Elf64_Ehdr)]; /* larger of the Ehdr variants */
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: ELF_C_WRITE with in-memory objects "
+ "returns ELF_E_MODE.");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+
+ _TS_READ_FILE("newehdr.$2$1", elf, sizeof(elf), goto done;);
+
+ TS_OPEN_MEMORY(e, elf);
+
+ if ((offset = elf_update(e, ELF_C_WRITE)) != (off_t) -1) {
+ TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.",
+ (intmax_t) offset);
+ goto done;
+ }
+
+ if ((error = elf_errno()) != ELF_E_MODE) {
+ TP_FAIL("elf_update() did not fail with ELF_E_MODE; "
+ "error=%d \"%s\".", error, elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ (void) elf_end(e);
+ tet_result(result);
+}')
+
+FN(`32', `lsb')
+FN(`32', `msb')
+FN(`64', `lsb')
+FN(`64', `msb')
+
+/*
+ * In-memory ELF objects are updateable with command ELF_C_NULL.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcMemElfNull$1$2(void)
+{
+ Elf *e;
+ int result;
+ size_t fsz;
+ off_t offset;
+ char elf[sizeof(Elf64_Ehdr)];
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: ELF_C_NULL updates in-memory objects.");
+
+ result = TET_UNRESOLVED;
+
+ _TS_READ_FILE("newehdr.$2$1", elf, sizeof(elf), goto done;);
+
+ TS_OPEN_MEMORY(e, elf);
+
+ if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) {
+ TP_UNRESOLVED("elf$2_fsize() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ result = TET_PASS;
+ if ((offset = elf_update(e, ELF_C_NULL)) != fsz)
+ TP_FAIL("offset=%jd != %d, error=%d \"%s\".",
+ (intmax_t) offset, fsz, elf_errmsg(-1));
+
+ done:
+ (void) elf_end(e);
+ tet_result(result);
+}')
+
+FN(`32', `lsb')
+FN(`32', `msb')
+FN(`64', `lsb')
+FN(`64', `msb')
+
+/*
+ * A mismatched class in the Ehdr returns an ELF_E_CLASS error.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcClassMismatch$1$2(void)
+{
+ int error, fd, result;
+ off_t offset;
+ Elf *e;
+ Elf$1_Ehdr *eh;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: a class-mismatch is detected.");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+
+ TS_OPEN_FILE(e, "newehdr.$2$1", ELF_C_READ, fd);
+
+ if ((eh = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: %s", elf_errmsg(-1));
+ goto done;
+ }
+
+ /* change the class */
+ eh->e_ident[EI_CLASS] = ELFCLASS`'ifelse($1,32,64,32);
+
+ if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) {
+ TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.",
+ (intmax_t) offset);
+ goto done;
+ }
+
+ if ((error = elf_errno()) != ELF_E_CLASS) {
+ TP_FAIL("elf_update() did not fail with ELF_E_CLASS; "
+ "error=%d \"%s\".", error, elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ tet_result(result);
+}')
+
+FN(`32', `lsb')
+FN(`32', `msb')
+FN(`64', `lsb')
+FN(`64', `msb')
+
+/*
+ * Changing the byte order of an ELF file on the fly is not allowed.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcByteOrderChange$1$2(void)
+{
+ int error, fd, result;
+ Elf *e;
+ off_t offset;
+ Elf$1_Ehdr *eh;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: byte order changes are rejected.");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+
+ TS_OPEN_FILE(e, "newehdr.$2$1", ELF_C_READ, fd);
+
+ if ((eh = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ eh->e_ident[EI_DATA] = ELFDATA2`'ifelse($2,`lsb',`MSB',`LSB');
+
+ if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) {
+ TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.",
+ (intmax_t) offset);
+ goto done;
+ }
+
+ if ((error = elf_errno()) != ELF_E_HEADER) {
+ TP_FAIL("elf_update() did not fail with ELF_E_HEADER; "
+ "error=%d \"%s\".", error, elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ tet_result(result);
+}')
+
+FN(`32', `lsb')
+FN(`32', `msb')
+FN(`64', `lsb')
+FN(`64', `msb')
+
+/*
+ * An unsupported ELF version is rejected with ELF_E_VERSION.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcUnsupportedVersion$1$2(void)
+{
+ int error, fd, result;
+ off_t offset;
+ Elf *e;
+ Elf$1_Ehdr *eh;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: version changes are rejected.");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+
+ TS_OPEN_FILE(e, "newehdr.$2$1", ELF_C_READ, fd);
+
+ if ((eh = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ eh->e_version = EV_CURRENT+1;
+
+ if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) {
+ TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.",
+ (intmax_t) offset);
+ goto done;
+ }
+
+ if ((error = elf_errno()) != ELF_E_VERSION) {
+ TP_FAIL("elf_update() did not fail with ELF_E_VERSION; "
+ "error=%d \"%s\".", error, elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ tet_result(result);
+}')
+
+FN(`32', `lsb')
+FN(`32', `msb')
+FN(`64', `lsb')
+FN(`64', `msb')
+
+/*
+ * Invoking an elf_cntl(ELF_C_FDDONE) causes a subsequent elf_update()
+ * to fail with ELF_E_SEQUENCE.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcSequenceFdDoneWrite$1(void)
+{
+ int error, fd, result;
+ off_t offset;
+ Elf *e;
+ Elf$1_Ehdr *eh;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("*$1: elf_update(ELF_C_WRITE) after an elf_cntl(FDDONE) "
+ "is rejected.");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+
+ _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;);
+
+ if ((eh = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ if (elf_cntl(e, ELF_C_FDDONE) != 0) {
+ TP_UNRESOLVED("elf_cntl() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((offset = elf_update(e, ELF_C_WRITE)) != (off_t) -1) {
+ TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.",
+ (intmax_t) offset);
+ goto done;
+ }
+
+ if ((error = elf_errno()) != ELF_E_SEQUENCE) {
+ TP_FAIL("elf_update() did not fail with ELF_E_SEQUENCE; "
+ "error=%d \"%s\".", error, elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ tet_result(result);
+}')
+
+FN(32)
+FN(64)
+
+/*
+ * Invoking an elf_cntl(ELF_C_FDDONE) causes a subsequent
+ * elf_update(ELF_C_NULL) to succeed.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcSequenceFdDoneNull$1(void)
+{
+ int fd, result;
+ off_t offset;
+ size_t fsz;
+ Elf *e;
+ Elf$1_Ehdr *eh;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("elf_update(ELF_C_NULL) after an elf_cntl(FDDONE) "
+ "succeeds.");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+
+ _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;);
+
+ if ((eh = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ if (elf_cntl(e, ELF_C_FDDONE) != 0) {
+ TP_UNRESOLVED("elf_cntl() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) {
+ TP_UNRESOLVED("fsize() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((offset = elf_update(e, ELF_C_NULL)) != fsz) {
+ TP_FAIL("elf_update()->%jd, (expected %d).",
+ (intmax_t) offset, fsz);
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ tet_result(result);
+}')
+
+FN(32)
+FN(64)
+
+/*
+ * Check that elf_update() can create a legal ELF file.
+ */
+
+const char strtab[] = {
+ '\0',
+ '.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', '\0'
+};
+
+#define INIT_PHDR(P) do { \
+ (P)->p_type = PT_NULL; \
+ (P)->p_offset = 0x0F0F0F0F; \
+ (P)->p_vaddr = 0xA0A0A0A0; \
+ (P)->p_filesz = 0x1234; \
+ (P)->p_memsz = 0x5678; \
+ (P)->p_flags = PF_X | PF_R; \
+ (P)->p_align = 64; \
+ } while (0)
+
+#define INIT_SHDR(S,O) do { \
+ (S)->sh_name = 1; \
+ (S)->sh_type = SHT_STRTAB; \
+ (S)->sh_flags = 0; \
+ (S)->sh_addr = 0; \
+ (S)->sh_offset = (O); \
+ (S)->sh_size = sizeof(strtab); \
+ (S)->sh_link = 0; \
+ (S)->sh_info = 0; \
+ (S)->sh_addralign = 1; \
+ (S)->sh_entsize = 0; \
+ } while (0)
+
+undefine(`FN')
+define(`FN',`
+void
+tcUpdate$1$2(void)
+{
+ int fd, result;
+ off_t offset;
+ size_t esz, fsz, psz, roundup, ssz;
+ Elf$1_Shdr *sh;
+ Elf$1_Ehdr *eh;
+ Elf$1_Phdr *ph;
+ Elf_Data *d;
+ Elf_Scn *scn;
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: elf_update() creates a legal ELF file.");
+
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;);
+
+ if ((eh = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Set the version and endianness */
+ eh->e_version = EV_CURRENT;
+ eh->e_ident[EI_DATA] = ELFDATA2`'TOUPPER($2);
+ eh->e_type = ET_REL;
+
+ if ((esz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0 ||
+ (psz = elf$1_fsize(ELF_T_PHDR, 1, EV_CURRENT)) == 0 ||
+ (ssz = elf$1_fsize(ELF_T_SHDR, 2, EV_CURRENT)) == 0) {
+ TP_UNRESOLVED("elf$1_fsize() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((ph = elf$1_newphdr(e,1)) == NULL) {
+ TP_UNRESOLVED("elf$1_newphdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ INIT_PHDR(ph);
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_newscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ eh->e_shstrndx = elf_ndxscn(scn);
+
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((d = elf_newdata(scn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ d->d_buf = (char *) strtab;
+ d->d_size = sizeof(strtab);
+ d->d_off = (off_t) 0;
+
+ INIT_SHDR(sh, esz+psz);
+
+ fsz = esz + psz + sizeof(strtab);
+ roundup = ifelse($1,32,4,8);
+ fsz = (fsz + roundup - 1) & ~(roundup - 1);
+
+ fsz += ssz;
+
+ if ((offset = elf_update(e, ELF_C_WRITE)) != fsz) {
+ TP_FAIL("ret=%jd != %d [elferror=\"%s\"]",
+ (intmax_t) offset, fsz, elf_errmsg(-1));
+ goto done;
+ }
+
+ (void) elf_end(e); e = NULL;
+ (void) close(fd); fd = -1;
+
+ result = elfts_compare_files("u1.$2$1", TS_NEWFILE);
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+/*
+ * An unsupported section type should be rejected.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcSectionType$2$1(void)
+{
+ int error, fd, result;
+ off_t offset;
+ Elf *e;
+ Elf_Scn *scn;
+ Elf$1_Shdr *sh;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: unsupported section types are rejected.");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+
+ _TS_OPEN_FILE(e, "newehdr.$2$1", ELF_C_READ, fd, goto done;);
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ sh->sh_type = SHT_NULL - 1;
+ (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
+
+ if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) {
+ TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.",
+ (intmax_t) offset);
+ goto done;
+ }
+
+ if ((error = elf_errno()) != ELF_E_SECTION) {
+ TP_FAIL("elf_update() did not fail with ELF_E_SECTION; "
+ "error=%d \"%s\".", error, elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd)
+ (void) close(fd);
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+/*
+ * An Elf_Data descriptor that is malformed in various ways
+ * should be rejected.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tc$3_$2$1(void)
+{
+ int error, fd, result;
+ off_t offset;
+ Elf *e;
+ Elf_Data *d;
+ Elf_Scn *scn;
+ Elf$1_Shdr *sh;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: data descriptors with " $6
+ " are rejected.");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+
+ _TS_OPEN_FILE(e, "newehdr.$2$1", ELF_C_READ, fd, goto done;);
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ sh->sh_type = SHT_SYMTAB;
+ (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
+
+ if ((d = elf_newdata(scn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Setup defaults for the test. */
+ d->d_buf = (char *) NULL;
+ d->d_size = sizeof(Elf$1_Sym);
+ d->d_type = ELF_T_SYM;
+ d->d_align = 1;
+
+ /* Override, on a per test case basis. */
+ $4
+
+ if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) {
+ TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.",
+ (intmax_t) offset);
+ goto done;
+ }
+
+ if ((error = elf_errno()) != ELF_E_$5) {
+ TP_FAIL("elf_update() did not fail with ELF_E_$5; "
+ "error=%d \"%s\".", error, elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd)
+ (void) close(fd);
+ tet_result(result);
+}')
+
+define(`MKFN',`
+FN(32,`lsb',$1,$2,$3,$4)
+FN(32,`msb',$1,$2,$3,$4)
+FN(64,`lsb',$1,$2,$3,$4)
+FN(64,`msb',$1,$2,$3,$4)
+')
+
+MKFN(IllegalAlignment, `d->d_align = 3;', DATA, "incorrect alignments")
+MKFN(UnsupportedVersion, `d->d_version = EV_CURRENT+1;', VERSION,
+ "an unknown version")
+MKFN(UnknownElfType, `d->d_type = ELF_T_NUM;', DATA, "an unknown type")
+MKFN(IllegalSize, `d->d_size = 1;', DATA, "an illegal size")
+
+
+/*
+ * Ensure that updating the section header on an ELF object opened
+ * in ELF_C_RDWR mode in an idempotent manner leaves the object
+ * in a sane state. See ticket #269.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcRdWrShdrIdempotent$2$1(void)
+{
+ Elf *e;
+ off_t fsz;
+ struct stat sb;
+ size_t strtabidx;
+ Elf_Scn *strtabscn;
+ int error, fd, tfd, result;
+ GElf_Shdr strtabshdr;
+ char *srcfile = "newscn.$2$1", *tfn;
+ char *reffile = "newscn2.$2$1";
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: (liblayout) a no-op update of section "
+ "headers works as expected");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ tfn = NULL;
+ fd = tfd = -1;
+
+ /* Make a copy of the reference object. */
+ if ((tfn = elfts_copy_file(srcfile, &error)) < 0) {
+ TP_UNRESOLVED("elfts_copyfile(%s) failed: \"%s\".", srcfile,
+ strerror(error));
+ goto done;
+ }
+
+ /* Open the copied object in RDWR mode. */
+ _TS_OPEN_FILE(e, tfn, ELF_C_RDWR, tfd, goto done;);
+
+ if (stat(reffile, &sb) < 0) {
+ TP_UNRESOLVED("stat() failed: \"%s\".", strerror(errno));
+ goto done;
+ }
+
+ /* Retrieve the index of the section name string table. */
+ if (elf_getshdrstrndx(e, &strtabidx) != 0) {
+ TP_UNRESOLVED("elf_getshdrstrndx() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /*
+ * Retrieve the section descriptor for the section name string table.
+ */
+ if ((strtabscn = elf_getscn(e, strtabidx)) == NULL) {
+ TP_UNRESOLVED("elf_getscn() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Read the section header ... */
+ if (gelf_getshdr(strtabscn, &strtabshdr) == NULL) {
+ TP_UNRESOLVED("gelf_getshdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /* ... and write it back. */
+ if (gelf_update_shdr(strtabscn, &strtabshdr) == 0) {
+ TP_UNRESOLVED("gelf_update_shdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Update the underlying ELF object. */
+ if ((fsz = elf_update(e, ELF_C_WRITE)) < 0) {
+ TP_UNRESOLVED("elf_update() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if (fsz != sb.st_size) {
+ TP_FAIL("Size error: expected=%d, elf_update()=%d",
+ sb.st_size, fsz);
+ goto done;
+ }
+
+ /* Close the temporary file. */
+ if ((error = elf_end(e)) != 0) {
+ TP_UNRESOLVED("elf_end() returned %d.", error);
+ goto done;
+ }
+
+ e = NULL;
+ /* Compare against the original. */
+ result = elfts_compare_files(reffile, tfn);
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ if (tfd != -1)
+ (void) close(tfd);
+ if (tfn != NULL)
+ (void) unlink(tfn);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+/*
+ * Ensure that updating the section header table on an ELF object opened
+ * in ELF_C_RDWR mode in an idempotent manner leaves the object
+ * in a sane state. See ticket #269.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcRdWrShdrIdempotentAppLayout$2$1(void)
+{
+ Elf *e;
+ off_t fsz;
+ struct stat sb;
+ size_t strtabidx;
+ Elf_Scn *strtabscn;
+ unsigned int flags;
+ int error, fd, tfd, result;
+ GElf_Shdr strtabshdr;
+ char *srcfile = "newscn.$2$1", *tfn;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: (applayout) a no-op update of section "
+ "headers works as expected");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ tfn = NULL;
+ fd = tfd = -1;
+
+ /* Make a copy of the reference object. */
+ if ((tfn = elfts_copy_file(srcfile, &error)) < 0) {
+ TP_UNRESOLVED("elfts_copyfile(%s) failed: \"%s\".", srcfile,
+ strerror(error));
+ goto done;
+ }
+
+ /* Open the copied object in RDWR mode. */
+ _TS_OPEN_FILE(e, tfn, ELF_C_RDWR, tfd, goto done;);
+
+ flags = elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT);
+ if ((flags & ELF_F_LAYOUT) == 0) {
+ TP_UNRESOLVED("elf_flagelf() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (fstat(tfd, &sb) < 0) {
+ TP_UNRESOLVED("fstat() failed: \"%s\".",
+ strerror(errno));
+ goto done;
+ }
+
+ /* Retrieve the index of the section name string table. */
+ if (elf_getshdrstrndx(e, &strtabidx) != 0) {
+ TP_UNRESOLVED("elf_getshdrstrndx() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /*
+ * Retrieve the section descriptor for the section name string table.
+ */
+ if ((strtabscn = elf_getscn(e, strtabidx)) == NULL) {
+ TP_UNRESOLVED("elf_getscn() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Read the section header ... */
+ if (gelf_getshdr(strtabscn, &strtabshdr) == NULL) {
+ TP_UNRESOLVED("gelf_getshdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /* ... and write it back. */
+ if (gelf_update_shdr(strtabscn, &strtabshdr) == 0) {
+ TP_UNRESOLVED("gelf_update_shdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Update the underlying ELF object. */
+ if ((fsz = elf_update(e, ELF_C_WRITE)) < 0) {
+ TP_UNRESOLVED("elf_update() failed: \"%s\".", elf_errmsg(-1));
+ goto done;
+ }
+
+ if (fsz != sb.st_size) {
+ TP_FAIL("Size error: expected=%d, elf_update()=%d",
+ sb.st_size, fsz);
+ goto done;
+ }
+
+ /* Close the temporary file. */
+ if ((error = elf_end(e)) != 0) {
+ TP_UNRESOLVED("elf_end() returned %d.", error);
+ goto done;
+ }
+
+ e = NULL;
+ /* Compare against the original. */
+ result = elfts_compare_files(srcfile, tfn);
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ if (tfd != -1)
+ (void) close(tfd);
+ if (tfn != NULL)
+ (void) unlink(tfn);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+/*
+ * Test handling of sections with buffers of differing Elf_Data types.
+ */
+
+/*
+ * The contents of the first Elf_Data buffer for section ".foo"
+ * (ELF_T_WORD, align 4).
+ */
+uint32_t hash_words[] = {
+ 0x01234567,
+ 0x89abcdef,
+ 0xdeadc0de
+};
+
+/*
+ * The contents of the second Elf_Data buffer for section ".foo"
+ * (ELF_T_BYTE, align 1)
+ */
+char data_string[] = "helloworld";
+
+/*
+ * The contents of the third Elf_Data buffer for section ".foo"
+ * (ELF_T_WORD, align 4)
+ */
+uint32_t checksum[] = {
+ 0xffffeeee
+};
+
+/*
+ * The contents of the ".shstrtab" section.
+ */
+char string_table[] = {
+ /* Offset 0 */ '\0',
+ /* Offset 1 */ '.', 'f' ,'o', 'o', '\0',
+ /* Offset 6 */ '.', 's' , 'h' , 's' , 't',
+ 'r', 't', 'a', 'b', '\0'
+};
+
+undefine(`FN')
+define(`FN',`
+void
+tcMixedBuffer_$2$1(void)
+{
+ Elf *e;
+ Elf_Scn *scn, *strscn;
+ int error, fd, result;
+ Elf$1_Ehdr *ehdr;
+ Elf$1_Shdr *shdr, *strshdr;
+ Elf_Data *data1, *data2, *data3, *data4;
+ char *reffile = "mixedscn.$2$1", *tfn;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: sections with mixed data work "
+ "as expected");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ tfn = NULL;
+ fd = -1;
+
+ _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;);
+
+ if ((ehdr = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ ehdr->e_ident[EI_DATA] = `ELFDATA2'TOUPPER($2);
+ ehdr->e_machine = MAKE_EM($1,$2);
+ ehdr->e_type = ET_REL;
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_newscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((data1 = elf_newdata(scn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata(data1) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ data1->d_align = 4;
+ data1->d_off = 0;
+ data1->d_buf = hash_words;
+ data1->d_type = ELF_T_WORD;
+ data1->d_size = sizeof(hash_words);
+ data1->d_version = EV_CURRENT;
+
+ if ((data2 = elf_newdata(scn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata(data2) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ data2->d_align = 1;
+ data2->d_off = 0;
+ data2->d_buf = data_string;
+ data2->d_type = ELF_T_BYTE;
+ data2->d_size = sizeof(data_string);
+ data2->d_version = EV_CURRENT;
+
+
+ if ((data3 = elf_newdata(scn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata(data3) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ data3->d_align = 4;
+ data3->d_off = 0;
+ data3->d_buf = checksum;
+ data3->d_type = ELF_T_WORD;
+ data3->d_size = sizeof(checksum);
+ data3->d_version = EV_CURRENT;
+
+ if ((shdr = elf$1_getshdr(scn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ shdr->sh_name = 1; /* offset of ".foo" */
+ shdr->sh_type = SHT_PROGBITS;
+ shdr->sh_flags = SHF_ALLOC;
+ shdr->sh_entsize = 0;
+ shdr->sh_addralign = 4;
+
+ /*
+ * Create the .shstrtab section.
+ */
+ if ((strscn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_newscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((data4 = elf_newdata(strscn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ data4->d_align = 1;
+ data4->d_off = 0;
+ data4->d_buf = string_table;
+ data4->d_type = ELF_T_BYTE;
+ data4->d_size = sizeof(string_table);
+ data4->d_version = EV_CURRENT;
+
+ if ((strshdr = elf$1_getshdr(strscn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ strshdr->sh_name = 6; /* \0 + strlen(".foo") + \0 */
+ strshdr->sh_type = SHT_STRTAB;
+ strshdr->sh_flags = SHF_STRINGS | SHF_ALLOC;
+ strshdr->sh_entsize = 0;
+
+ ehdr->e_shstrndx = elf_ndxscn(strscn);
+
+ if (elf_update(e, ELF_C_WRITE) < 0) {
+ TP_FAIL("elf_update() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Compare files here. */
+ TP_UNRESOLVED("Verification is yet to be implemented.");
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);
+
+ tet_result(result);
+}')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+/*
+ * Test that a call to elf_update() without any changes flagged
+ * leaves the ELF object unchanged.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcRdWrModeNoOp_$1$2(void)
+{
+ struct stat sb;
+ int error, fd, result;
+ Elf *e;
+ Elf$1_Ehdr *eh;
+ const char *srcfile = "rdwr.$2$1";
+ off_t fsz1, fsz2;
+ char *tfn;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: elf_update() without flagged changes "
+ "is a no-op");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+ tfn = NULL;
+
+ /* Make a copy of the reference object. */
+ if ((tfn = elfts_copy_file(srcfile, &error)) < 0) {
+ TP_UNRESOLVED("elfts_copyfile(%s) failed: \"%s\".",
+ srcfile, strerror(error));
+ goto done;
+ }
+
+ /* Open the copied object in RDWR mode. */
+ _TS_OPEN_FILE(e, tfn, ELF_C_RDWR, fd, goto done;);
+
+ if (fstat(fd, &sb) < 0) {
+ TP_UNRESOLVED("fstat() failed: \"%s\".",
+ strerror(errno));
+ goto done;
+ }
+
+ if ((eh = elf$1_getehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_getehdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((fsz1 = elf_update(e, ELF_C_NULL)) < 0) {
+ TP_FAIL("elf_update(NULL) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (fsz1 != sb.st_size) {
+ TP_FAIL("Size error: expected=%d, elf_update()=%d",
+ sb.st_size, fsz1);
+ goto done;
+ }
+
+ if ((fsz2 = elf_update(e, ELF_C_WRITE)) < 0) {
+ TP_FAIL("elf_update(WRITE) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Close the temporary file. */
+ if ((error = elf_end(e)) != 0) {
+ TP_UNRESOLVED("elf_end() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (fsz1 != fsz2) {
+ TP_FAIL("fsz1 (%d) != fsz2 (%d)", fsz1, fsz2);
+ goto done;
+ }
+
+ e = NULL;
+ (void) close(fd);
+
+ /* compare against the original */
+ result = elfts_compare_files(srcfile, tfn);
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ if (tfn != NULL)
+ (void) unlink(tfn);
+
+ tet_result(result);
+}')
+
+FN(32,lsb)
+FN(32,msb)
+FN(64,lsb)
+FN(64,msb)
+
+/*
+ * Test that a call to elf_update() without a change to underlying
+ * data for the object is a no-op.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcRdWrModeNoDataChange_$1$2(void)
+{
+ int error, fd, result;
+ Elf *e;
+ Elf_Scn *scn;
+ const char *srcfile = "rdwr.$2$1";
+ off_t fsz1, fsz2;
+ struct stat sb;
+ char *tfn;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: elf_update() with no data changes "
+ "is a no-op");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+ tfn = NULL;
+
+ /* Make a copy of the reference object. */
+ if ((tfn = elfts_copy_file(srcfile, &error)) < 0) {
+ TP_UNRESOLVED("elfts_copyfile(%s) failed: \"%s\".",
+ srcfile, strerror(error));
+ goto done;
+ }
+
+ /* Open the copied object in RDWR mode. */
+ _TS_OPEN_FILE(e, tfn, ELF_C_RDWR, fd, goto done;);
+
+ if (fstat(fd, &sb) < 0) {
+ TP_UNRESOLVED("fstat() failed: \"%s\".",
+ strerror(errno));
+ goto done;
+ }
+
+ if ((scn = elf_getscn(e, 1)) == NULL) {
+ TP_UNRESOLVED("elf_getscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY) != ELF_F_DIRTY) {
+ TP_UNRESOLVED("elf_flagscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((fsz1 = elf_update(e, ELF_C_NULL)) < 0) {
+ TP_FAIL("elf_update(NULL) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (fsz1 != sb.st_size) {
+ TP_FAIL("Size error: expected=%d, elf_update()=%d",
+ sb.st_size, fsz1);
+ goto done;
+ }
+
+ if ((fsz2 = elf_update(e, ELF_C_WRITE)) < 0) {
+ TP_FAIL("elf_update(WRITE) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (fsz1 != fsz2) {
+ TP_FAIL("fsz1 (%d) != fsz2 (%d)", fsz1, fsz2);
+ goto done;
+ }
+
+ /* Close the temporary file. */
+ if ((error = elf_end(e)) != 0) {
+ TP_UNRESOLVED("elf_end() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ e = NULL;
+ (void) close(fd);
+
+ /* compare against the original */
+ result = elfts_compare_files(srcfile, tfn);
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ if (tfn != NULL)
+ (void) unlink(tfn);
+
+ tet_result(result);
+}')
+
+FN(32,lsb)
+FN(32,msb)
+FN(64,lsb)
+FN(64,msb)
+
+/*
+ * Test that a call to elf_update() with a changed ehdr causes the
+ * underlying file to change.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcRdWrModeEhdrChange_$1$2(void)
+{
+ int error, fd, result;
+ unsigned int flag;
+ struct stat sb;
+ Elf *e;
+ Elf$1_Ehdr *eh;
+ const char *srcfile = "rdwr.$2$1";
+ const char *reffile = "rdwr1.$2$1";
+ off_t fsz1, fsz2;
+ char *tfn;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: elf_update() updates a changed "
+ "header correctly");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+ tfn = NULL;
+
+ /* Make a copy of the reference object. */
+ if ((tfn = elfts_copy_file(srcfile, &error)) < 0) {
+ TP_UNRESOLVED("elfts_copyfile(%s) failed: \"%s\".",
+ srcfile, strerror(error));
+ goto done;
+ }
+
+ /* Open the copied object in RDWR mode. */
+ _TS_OPEN_FILE(e, tfn, ELF_C_RDWR, fd, goto done;);
+
+ if (fstat(fd, &sb) < 0) {
+ TP_UNRESOLVED("fstat() failed: \"%s\".",
+ strerror(errno));
+ goto done;
+ }
+
+ if ((eh = elf$1_getehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf_getscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Change the ELFCLASS of the object. */
+ eh->e_type = ET_DYN;
+
+ flag = elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY);
+ if ((flag & ELF_F_DIRTY) == 0) {
+ TP_UNRESOLVED("elf_flagehdr failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((fsz1 = elf_update(e, ELF_C_NULL)) < 0) {
+ TP_FAIL("elf_update(NULL) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (fsz1 != sb.st_size) {
+ TP_FAIL("Size error: expected=%d, elf_update()=%d",
+ sb.st_size, fsz1);
+ goto done;
+ }
+
+ if ((fsz2 = elf_update(e, ELF_C_WRITE)) < 0) {
+ TP_FAIL("elf_update(WRITE) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (fsz1 != fsz2) {
+ TP_FAIL("fsz1 (%d) != fsz2 (%d)", fsz1, fsz2);
+ goto done;
+ }
+
+ /* Close the temporary file. */
+ if ((error = elf_end(e)) != 0) {
+ TP_UNRESOLVED("elf_end() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ e = NULL;
+ (void) close(fd);
+
+ /* compare against the reference */
+ result = elfts_compare_files(reffile, tfn);
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ if (tfn != NULL)
+ (void) unlink(tfn);
+
+ tet_result(result);
+}
+')
+
+FN(32,lsb)
+FN(32,msb)
+FN(64,lsb)
+FN(64,msb)
+
+/*
+ * Test extending a section.
+ */
+
+static char *base_data = "hello world";
+static char *extra_data = "goodbye world";
+
+undefine(`FN')
+define(`FN',`
+void
+tcRdWrExtendSection_$1$2(void)
+{
+ int error, fd, result;
+ unsigned int flag;
+ struct stat sb;
+ Elf *e;
+ Elf_Scn *scn;
+ Elf_Data *d;
+ const char *srcfile = "rdwr.$2$1";
+ const char *reffile = "rdwr2.$2$1";
+ off_t fsz1, fsz2;
+ char *tfn;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: elf_update() deals with an "
+ "extended section correctly");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+ tfn = NULL;
+
+ /* Make a copy of the reference object. */
+ if ((tfn = elfts_copy_file(srcfile, &error)) < 0) {
+ TP_UNRESOLVED("elfts_copyfile(%s) failed: \"%s\".",
+ srcfile, strerror(error));
+ goto done;
+ }
+
+ /* Open the copied object in RDWR mode. */
+ _TS_OPEN_FILE(e, tfn, ELF_C_RDWR, fd, goto done;);
+
+ if (stat(reffile, &sb) < 0) {
+ TP_UNRESOLVED("stat() failed: \"%s\".", strerror(errno));
+ goto done;
+ }
+
+ /* Retrieve section 1 and extend it. */
+
+ if ((scn = elf_getscn(e, 1)) == NULL) {
+ TP_UNRESOLVED("elf_getscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((d = elf_newdata(scn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ d->d_buf = extra_data;
+ d->d_size = strlen(extra_data);
+
+ if (elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY) != ELF_F_DIRTY) {
+ TP_UNRESOLVED("elf_flagscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((fsz1 = elf_update(e, ELF_C_NULL)) < 0) {
+ TP_FAIL("elf_update(NULL) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (fsz1 != sb.st_size) {
+ TP_FAIL("Size error: expected=%d, elf_update()=%d",
+ sb.st_size, fsz1);
+ goto done;
+ }
+
+ if ((fsz2 = elf_update(e, ELF_C_WRITE)) < 0) {
+ TP_FAIL("elf_update(WRITE) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (fsz1 != fsz2) {
+ TP_FAIL("fsz1 (%d) != fsz2 (%d)", fsz1, fsz2);
+ goto done;
+ }
+
+ /* Close the temporary file. */
+ if ((error = elf_end(e)) != 0) {
+ TP_UNRESOLVED("elf_end() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ e = NULL;
+ (void) close(fd);
+
+ /* compare against the reference */
+ result = elfts_compare_files(reffile, tfn);
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ if (tfn != NULL)
+ (void) unlink(tfn);
+
+ tet_result(result);
+}
+')
+
+FN(32,lsb)
+FN(32,msb)
+FN(64,lsb)
+FN(64,msb)
+
+/*
+ * Test shrinking a section.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcRdWrShrinkSection_$1$2(void)
+{
+ int error, fd, result;
+ unsigned int flag;
+ struct stat sb;
+ Elf *e;
+ Elf_Scn *scn;
+ Elf_Data *d;
+ const char *srcfile = "rdwr2.$2$1";
+ const char *reffile = "rdwr.$2$1";
+ off_t fsz1, fsz2;
+ char *tfn;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: elf_update() deals with an "
+ "shrunk section correctly");
+
+ result = TET_UNRESOLVED;
+ e = NULL;
+ fd = -1;
+ tfn = NULL;
+
+ /* Make a copy of the reference object. */
+ if ((tfn = elfts_copy_file(srcfile, &error)) < 0) {
+ TP_UNRESOLVED("elfts_copyfile(%s) failed: \"%s\".",
+ srcfile, strerror(error));
+ goto done;
+ }
+
+ /* Open the copied object in RDWR mode. */
+ _TS_OPEN_FILE(e, tfn, ELF_C_RDWR, fd, goto done;);
+
+ if (stat(reffile, &sb) < 0) {
+ TP_UNRESOLVED("stat() failed: \"%s\".", strerror(errno));
+ goto done;
+ }
+
+ /* Retrieve section 1 and shrink it. */
+
+ if ((scn = elf_getscn(e, 1)) == NULL) {
+ TP_UNRESOLVED("elf_getscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((d = elf_getdata(scn, NULL)) == NULL) {
+ TP_UNRESOLVED("elf_getdata() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ d->d_size = strlen(base_data);
+
+ if (elf_flagdata(d, ELF_C_SET, ELF_F_DIRTY) != ELF_F_DIRTY) {
+ TP_UNRESOLVED("elf_flagdata() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY) != ELF_F_DIRTY) {
+ TP_UNRESOLVED("elf_flagscn() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((fsz1 = elf_update(e, ELF_C_NULL)) < 0) {
+ TP_FAIL("elf_update(NULL) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (fsz1 != sb.st_size) {
+ TP_FAIL("Size error: expected=%d, elf_update()=%d",
+ sb.st_size, fsz1);
+ goto done;
+ }
+
+ if ((fsz2 = elf_update(e, ELF_C_WRITE)) < 0) {
+ TP_FAIL("elf_update(WRITE) failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if (fsz1 != fsz2) {
+ TP_FAIL("fsz1 (%d) != fsz2 (%d)", fsz1, fsz2);
+ goto done;
+ }
+
+ /* Close the temporary file. */
+ if ((error = elf_end(e)) != 0) {
+ TP_UNRESOLVED("elf_end() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ e = NULL;
+ (void) close(fd);
+
+ /* compare against the reference */
+ result = elfts_compare_files(reffile, tfn);
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ if (tfn != NULL)
+ (void) unlink(tfn);
+
+ tet_result(result);
+}
+')
+
+FN(32,lsb)
+FN(32,msb)
+FN(64,lsb)
+FN(64,msb)
+
+/*
+ * Test cases rejecting malformed ELF files created with the
+ * ELF_F_LAYOUT flag set.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcEhdrPhdrCollision$1$2(void)
+{
+ int error, fd, result, flags;
+ off_t offset;
+ size_t fsz, psz, roundup, ssz;
+ Elf$1_Ehdr *eh;
+ Elf$1_Phdr *ph;
+ Elf_Data *d;
+ Elf_Scn *scn;
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: an overlap of the ehdr and phdr is "
+ "detected.");
+
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;);
+
+ flags = elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT);
+ if ((flags & ELF_F_LAYOUT) == 0) {
+ TP_UNRESOLVED("elf_flagelf() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((eh = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Fill in sane values for the Ehdr. */
+ eh->e_type = ET_REL;
+ eh->e_shoff = 0;
+ eh->e_ident[EI_CLASS] = ELFCLASS`'$1;
+ eh->e_ident[EI_DATA] = ELFDATA2`'TOUPPER($2);
+
+ if ((ph = elf$1_newphdr(e, 1)) == NULL) {
+ TP_UNRESOLVED("elf$1_newphdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) {
+ TP_UNRESOLVED("fsize() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Make the phdr table overlap with the ehdr. */
+ eh->e_phoff = fsz - 1;
+
+ /* Check the return values from elf_update(). */
+ if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) {
+ TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd",
+ (intmax_t) offset);
+ goto done;
+ }
+
+ if ((error = elf_errno()) != ELF_E_LAYOUT) {
+ TP_FAIL("elf_update() did not fail with ELF_E_LAYOUT, "
+ "error=%d \"%s\".", error, elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);
+
+ tet_result(result);
+}
+')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+undefine(`FN')
+define(`FN',`
+void
+tcShdrPhdrCollision$1$2(void)
+{
+ int error, fd, result, flags;
+ off_t offset;
+ size_t fsz, psz, roundup, ssz;
+ Elf$1_Ehdr *eh;
+ Elf$1_Phdr *ph;
+ Elf_Data *d;
+ Elf_Scn *scn;
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: an overlap of the shdr and phdr is "
+ "detected.");
+
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;);
+
+ flags = elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT);
+ if ((flags & ELF_F_LAYOUT) == 0) {
+ TP_UNRESOLVED("elf_flagelf() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((eh = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Fill in sane values for the Ehdr. */
+ eh->e_type = ET_REL;
+ eh->e_ident[EI_CLASS] = ELFCLASS`'$1;
+ eh->e_ident[EI_DATA] = ELFDATA2`'TOUPPER($2);
+
+ if ((ph = elf$1_newphdr(e, 1)) == NULL) {
+ TP_UNRESOLVED("elf$1_newphdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) {
+ TP_UNRESOLVED("fsize() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_newscn() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Make the PHDR and SHDR tables overlap. */
+ eh->e_phoff = fsz;
+ eh->e_shoff = fsz;
+
+ if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) {
+ TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.",
+ (intmax_t) offset);
+ goto done;
+ }
+
+ if ((error = elf_errno()) != ELF_E_LAYOUT) {
+ TP_FAIL("elf_update() did not fail with ELF_E_LAYOUT; "
+ "error=%d \"%s\".", error, elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);
+
+ tet_result(result);
+}
+')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+/*
+ * Verify that an overlap between a section's data and the SHDR
+ * table is detected.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcShdrSectionCollision$1$2(void)
+{
+ int error, fd, result, flags;
+ off_t offset;
+ size_t fsz, psz, roundup, ssz;
+ Elf$1_Ehdr *eh;
+ Elf$1_Shdr *sh;
+ Elf_Data *d;
+ Elf_Scn *scn;
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: an overlap of the shdr and a section is "
+ "detected.");
+
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;);
+
+ flags = elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT);
+ if ((flags & ELF_F_LAYOUT) == 0) {
+ TP_UNRESOLVED("elf_flagelf() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((eh = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Fill in sane values for the Ehdr. */
+ eh->e_type = ET_REL;
+ eh->e_ident[EI_CLASS] = ELFCLASS`'$1;
+ eh->e_ident[EI_DATA] = ELFDATA2`'TOUPPER($2);
+
+ if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) {
+ TP_UNRESOLVED("fsize() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_newscn() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ eh->e_shoff = fsz;
+
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Fill in application-specified fields. */
+ sh->sh_type = SHT_PROGBITS;
+ sh->sh_addralign = 1;
+ sh->sh_size = 1;
+ sh->sh_entsize = 1;
+
+ /* Make this section overlap with the section header. */
+ sh->sh_offset = fsz;
+
+ if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) {
+ TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.",
+ (intmax_t) offset);
+ goto done;
+ }
+
+ if ((error = elf_errno()) != ELF_E_LAYOUT) {
+ TP_FAIL("elf_update() did not fail with ELF_E_LAYOUT; "
+ "error=%d \"%s\".", error, elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);
+
+ tet_result(result);
+}
+')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
+
+/*
+ * Check that overlapping sections are rejected when ELF_F_LAYOUT is set.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcSectionOverlap$1$2(void)
+{
+ int error, fd, result, flags;
+ off_t offset;
+ size_t fsz, psz, roundup, ssz;
+ Elf$1_Ehdr *eh;
+ Elf$1_Shdr *sh;
+ Elf_Data *d;
+ Elf_Scn *scn;
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("TOUPPER($2)$1: an overlap between two sections is "
+ "detected.");
+
+ result = TET_UNRESOLVED;
+ fd = -1;
+ e = NULL;
+
+ _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;);
+
+ flags = elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT);
+ if ((flags & ELF_F_LAYOUT) == 0) {
+ TP_UNRESOLVED("elf_flagelf() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((eh = elf$1_newehdr(e)) == NULL) {
+ TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ /* Fill in sane values for the Ehdr. */
+ eh->e_type = ET_REL;
+ eh->e_ident[EI_CLASS] = ELFCLASS`'$1;
+ eh->e_ident[EI_DATA] = ELFDATA2`'TOUPPER($2);
+ eh->e_shoff = TS_OFFSET_SHDR;
+
+ if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) {
+ TP_UNRESOLVED("fsize() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ /*
+ * Build the first section.
+ */
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_newscn() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((d = elf_newdata(scn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ d->d_type = ELF_T_BYTE;
+ d->d_off = 0;
+ d->d_buf = base_data;
+ d->d_size = strlen(base_data);
+
+ /* Fill in application-specified fields. */
+ sh->sh_type = SHT_PROGBITS;
+ sh->sh_addralign = 1;
+ sh->sh_size = 1;
+ sh->sh_entsize = 1;
+ sh->sh_offset = fsz;
+
+ /*
+ * Build the second section.
+ */
+
+ if ((scn = elf_newscn(e)) == NULL) {
+ TP_UNRESOLVED("elf_newscn() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((sh = elf$1_getshdr(scn)) == NULL) {
+ TP_UNRESOLVED("elf$1_getshdr() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ if ((d = elf_newdata(scn)) == NULL) {
+ TP_UNRESOLVED("elf_newdata() failed: \"%s\".",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ d->d_buf = base_data;
+ d->d_size = strlen(base_data);
+
+ /* Fill in application-specified fields. */
+ sh->sh_type = SHT_PROGBITS;
+ sh->sh_addralign = 1;
+ sh->sh_size = 1;
+ sh->sh_entsize = 1;
+
+ sh->sh_offset = fsz + 1; /* Overlap with the first section. */
+
+ if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) {
+ TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.",
+ (intmax_t) offset);
+ goto done;
+ }
+
+ if ((error = elf_errno()) != ELF_E_LAYOUT) {
+ TP_FAIL("elf_update() did not fail with ELF_E_LAYOUT; "
+ "error=%d \"%s\".", error, elf_errmsg(error));
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ (void) unlink(TS_NEWFILE);
+
+ tet_result(result);
+}
+')
+
+FN(32,`lsb')
+FN(32,`msb')
+FN(64,`lsb')
+FN(64,`msb')
diff --git a/test/libelf/tset/elf_version/Makefile b/test/libelf/tset/elf_version/Makefile
new file mode 100644
index 0000000000000..c130a5d1b491f
--- /dev/null
+++ b/test/libelf/tset/elf_version/Makefile
@@ -0,0 +1,7 @@
+# $Id: Makefile 1338 2010-12-31 15:41:20Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= version.m4
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/elf_version/version.m4 b/test/libelf/tset/elf_version/version.m4
new file mode 100644
index 0000000000000..56880f640b03d
--- /dev/null
+++ b/test/libelf/tset/elf_version/version.m4
@@ -0,0 +1,185 @@
+/*-
+ * Copyright (c) 2006 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: version.m4 1339 2010-12-31 15:42:52Z jkoshy $
+ */
+
+include(`elfts.m4')
+
+#include <libelf.h>
+
+#include "tet_api.h"
+
+/*
+ * Test the `elf_version' entry point.
+ *
+ * Each test case requires a separate invocation of the test
+ * executable because the first call of elf_version() sets private
+ * state in the library. Consequently these tests are organized as
+ * one test purpose per test case.
+ */
+
+/*
+ * Test version number retrieval.
+ */
+
+void
+tcParamNoneReturnsCurrentVersion(void)
+{
+ TP_ANNOUNCE("Param EV_NONE returns version == EV_CURRENT");
+ if (elf_version(EV_NONE) != EV_CURRENT)
+ tet_result(TET_FAIL);
+ else
+ tet_result(TET_PASS);
+}
+
+
+/*
+ * Test that an unsupported version number is not accepted.
+ */
+
+void
+tcValueTooLarge(void)
+{
+ TP_ANNOUNCE("calling elf_version() with an unsupported "
+ "(too-large) value fails and sets the error to ELF_E_VERSION.");
+
+ if (elf_version(EV_CURRENT+1) != EV_NONE) {
+ tet_result(TET_FAIL);
+ return;
+ }
+
+ if (elf_errno() != ELF_E_VERSION) {
+ tet_result(TET_FAIL);
+ return;
+ }
+
+ tet_result(TET_PASS);
+}
+
+/*
+ * Test that a reject version number does not cause the internal
+ * version number to change.
+ */
+
+void
+tcValueErrorNoChange(void)
+{
+ TP_ANNOUNCE("the library's current version should not be "
+ "changed by a failing call to elf_version().");
+
+ if (elf_version(EV_CURRENT+1) != EV_NONE) {
+ tet_infoline("unresolved: illegal elf_version() call did not "
+ "fail as expected.");
+ tet_result(TET_UNRESOLVED);
+ return;
+ }
+
+ if (elf_version(EV_NONE) != EV_CURRENT) {
+ tet_result(TET_FAIL);
+ return;
+ }
+
+ tet_result(TET_PASS);
+}
+
+/*
+ * Test that setting the library version to a legal value should
+ * succeed.
+ *
+ * Currently, EV_CURRENT (== 1) is the only legal version. When more
+ * ELF versions are defined, this test should be changed to iterate
+ * over all of them.
+ */
+
+void
+tcValidValuesAreOk(void)
+{
+ int result;
+ unsigned int old_version, new_version;
+
+ TP_ANNOUNCE("setting the ELF version to a legal value"
+ "passes");
+
+ result = TET_UNRESOLVED;
+ old_version = elf_version(EV_NONE);
+
+ if (old_version == EV_NONE) {
+ TP_UNRESOLVED("unknown current elf version");
+ goto done;
+ }
+
+ new_version = EV_CURRENT;
+ if (elf_version(new_version) != old_version) {
+ TP_FAIL("unexpected return value from "
+ "elf_version(new_version)");
+ goto done;
+ }
+
+ /* retrieve the version that was set and check */
+ if (elf_version(EV_NONE) != new_version) {
+ TP_FAIL("the new ELF version was not succesfully "
+ "set. ");
+ goto done;
+ }
+
+ result = TET_PASS;
+
+done:
+ tet_result(result);
+}
+
+/*
+ * Other APIs that shouldn't have elf_version() called.
+ */
+
+void
+tcSequenceErrorElfMemory(void)
+{
+ Elf *e;
+
+ TP_ANNOUNCE("elf_memory() before elf_version() "
+ "fails with ELF_E_SEQUENCE.");
+
+ if ((e = elf_memory(NULL, 0)) != NULL ||
+ elf_errno() != ELF_E_SEQUENCE)
+ tet_result(TET_FAIL);
+ else
+ tet_result(TET_PASS);
+}
+
+void
+tcSequenceErrorElfKind(void)
+{
+ TP_ANNOUNCE("assertion: calling elf_kind() before elf_version() "
+ "fails with ELF_E_SEQUENCE.");
+
+ /* Note: no elf_version() call */
+ if (elf_kind(NULL) != ELF_K_NONE &&
+ elf_errno() != ELF_E_SEQUENCE)
+ tet_result(TET_FAIL);
+ else
+ tet_result(TET_PASS);
+}
diff --git a/test/libelf/tset/gelf_getclass/Makefile b/test/libelf/tset/gelf_getclass/Makefile
new file mode 100644
index 0000000000000..155b8dc4f8da8
--- /dev/null
+++ b/test/libelf/tset/gelf_getclass/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= getclass.m4
+TS_DATA= getclass.msb32 getclass.msb64
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/gelf_getclass/getclass.m4 b/test/libelf/tset/gelf_getclass/getclass.m4
new file mode 100644
index 0000000000000..9ea731dfbefdd
--- /dev/null
+++ b/test/libelf/tset/gelf_getclass/getclass.m4
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2006 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: getclass.m4 1358 2011-01-08 05:40:41Z jkoshy $
+ */
+
+#include <fcntl.h>
+#include <gelf.h>
+#include <unistd.h>
+
+#include "elfts.h"
+#include "tet_api.h"
+
+/*
+ * Test the `gelf_getclass' entry point.
+ */
+
+IC_REQUIRES_VERSION_INIT();
+
+void
+tp_null(void)
+{
+ tet_infoline("assertion: gelf_getclass(NULL) should return "
+ "ELFCLASSNONE.");
+
+ tet_result (gelf_getclass(NULL) != ELFCLASSNONE ? TET_FAIL : TET_PASS);
+}
+
+void
+tp_class32(void)
+{
+ Elf *e;
+ int fd;
+
+ TP_CHECK_INITIALIZATION();
+
+ tet_infoline("assertion: gelf_getclass() return ELFCLASS32 for a "
+ "32 bit ELF file.");
+
+ TS_OPEN_FILE(e,"getclass.msb32",ELF_C_READ,fd);
+
+ tet_result (gelf_getclass(e) != ELFCLASS32 ? TET_FAIL : TET_PASS);
+
+ (void) elf_end(e);
+ (void) close(fd);
+}
+
+void
+tp_class64(void)
+{
+ Elf *e;
+ int fd;
+
+ TP_CHECK_INITIALIZATION();
+
+ tet_infoline("assertion: gelf_getclass() return ELFCLASS64 for a "
+ "64 bit ELF file.");
+
+ TS_OPEN_FILE(e,"getclass.msb64",ELF_C_READ,fd);
+
+ tet_result (gelf_getclass(e) != ELFCLASS64 ? TET_FAIL : TET_PASS);
+
+ (void) elf_end(e);
+ (void) close(fd);
+}
diff --git a/test/libelf/tset/gelf_getehdr/Makefile b/test/libelf/tset/gelf_getehdr/Makefile
new file mode 100644
index 0000000000000..eb4a5436a6249
--- /dev/null
+++ b/test/libelf/tset/gelf_getehdr/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1352 2011-01-01 15:48:52Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= ehdr.m4
+TS_YAML= ehdr
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/gelf_getehdr/ehdr.m4 b/test/libelf/tset/gelf_getehdr/ehdr.m4
new file mode 100644
index 0000000000000..ba8f948c9e833
--- /dev/null
+++ b/test/libelf/tset/gelf_getehdr/ehdr.m4
@@ -0,0 +1,282 @@
+/*-
+ * Copyright (c) 2006,2010 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: ehdr.m4 2054 2011-10-26 12:12:06Z jkoshy $
+ */
+
+include(`elfts.m4')
+
+#include <sys/cdefs.h>
+
+#include <gelf.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+
+#include "elfts.h"
+
+#include "gelf_ehdr_template.h"
+
+
+void
+tcNullGelfGetNullElf(void)
+{
+ int result;
+ GElf_Ehdr dst;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("gelf_getehdr(NULL,*) fails with ELF_E_ARGUMENT");
+
+ result = TET_PASS;
+ if (gelf_getehdr(NULL,&dst) != NULL || elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+ tet_result(result);
+}
+
+void
+tcNullGelfGetNullDst(void)
+{
+ Elf *e;
+ int fd;
+ char *fn = "ehdr.msb32";
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("gelf_getehdr(*,NULL) fails with ELF_E_ARGUMENT");
+
+ TS_OPEN_FILE(e,fn,ELF_C_READ,fd);
+
+ if (gelf_getehdr(e, NULL) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ tet_result(TET_FAIL);
+ else
+ tet_result(TET_PASS);
+
+ (void) elf_end(e);
+ (void) close(fd);
+}
+
+void
+tcNonElfFails(void)
+{
+ Elf *e;
+ GElf_Ehdr d;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("gelf_getehdr(E) for non-ELF (E) fails with "
+ "ELF_E_ARGUMENT");
+
+ TS_OPEN_MEMORY(e,data);
+
+ if (gelf_getehdr(e, &d) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ tet_result(TET_FAIL);
+ else
+ tet_result(TET_PASS);
+
+ (void) elf_end(e);
+}
+
+void
+tcBadElfVersion(void)
+{
+ int err;
+ Elf *e;
+ void *eh;
+ GElf_Ehdr d;
+ char badelf[sizeof(badelftemplate)];
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("gelf_getehdr() on an ELF object with an unsupported "
+ "version fails with ELF_E_VERSION");
+
+ (void) memcpy(badelf, badelftemplate, sizeof(badelf));
+
+ badelf[EI_VERSION] = EV_NONE;
+ badelf[EI_CLASS] = ELFCLASS32;
+ badelf[EI_DATA] = ELFDATA2MSB;
+
+ TS_OPEN_MEMORY(e,badelf);
+
+ if ((eh = gelf_getehdr(e, &d)) != NULL ||
+ (err = elf_errno()) != ELF_E_VERSION) {
+ tet_printf("fail: error=%d eh=%p.", err, (void *) eh);
+ tet_result(TET_FAIL);
+ } else
+ tet_result(TET_PASS);
+
+ (void) elf_end(e);
+}
+
+void
+tcMalformedElf(void)
+{
+ int err;
+ Elf *e;
+ void *eh;
+ GElf_Ehdr d;
+ char badelf[sizeof(badelftemplate)];
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("gelf_getehdr() on a malformed ELF object fails with "
+ "ELF_E_HEADER");
+
+ (void) memcpy(badelf, badelftemplate, sizeof(badelf));
+ badelf[EI_VERSION] = EV_CURRENT;
+ badelf[EI_CLASS] = ELFCLASS32;
+ badelf[EI_DATA] = ELFDATA2MSB;
+
+ TS_OPEN_MEMORY(e, badelf);
+
+ if ((eh = gelf_getehdr(e, &d)) != NULL ||
+ (err = elf_errno()) != ELF_E_HEADER) {
+ tet_printf("fail: error=%d eh=%p.", err, (void *) eh);
+ tet_result(TET_FAIL);
+ } else
+ tet_result(TET_PASS);
+
+ (void) elf_end(e);
+}
+
+static char *filenames[] = {
+ "ehdr.lsb32",
+ "ehdr.msb32",
+ "ehdr.lsb64",
+ "ehdr.msb64",
+ NULL
+};
+
+void
+tcGoodElfValid(void)
+{
+ int fd, result;
+ GElf_Ehdr d1, *eh;
+ Elf *e;
+ char *fn;
+ int i, data, class;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("a successful gelf_getehdr() call returns "
+ "a pointer to the passed in structure, filled with the correct "
+ "contents");
+
+ result = TET_PASS;
+ e = NULL;
+ fd = -1;
+
+ for (i = 0; i < 4; i++) {
+ fn = filenames[i];
+
+ TS_OPEN_FILE(e, fn, ELF_C_READ, fd);
+
+ if ((eh = gelf_getehdr(e, &d1)) == NULL) {
+ tet_printf("fail: gelf_getehdr(%s): %s.", *fn,
+ elf_errmsg(-1));
+ result = TET_FAIL;
+ goto done;
+ }
+
+ if (eh != &d1) {
+ tet_printf("fail: gelf_getehdr() return != argument.");
+ result = TET_FAIL;
+ goto done;
+ }
+
+ data = (i & 1) ? ELFDATA2MSB : ELFDATA2LSB;
+ class = (i <= 1) ? ELFCLASS32 : ELFCLASS64;
+
+ CHECK_EHDR(eh, data, class);
+
+ if (result != TET_PASS)
+ break;
+
+ (void) elf_end(e); e = NULL;
+ (void) close(fd); fd = -1;
+ }
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ tet_result(result);
+}
+
+void
+tcDupCalls(void)
+{
+ int fd, result;
+ Elf *e;
+ GElf_Ehdr d1, d2;
+ GElf_Ehdr *eh1, *eh2;
+ char **fn;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("successful calls to gelf_getehdr() for the same object "
+ "return identical contents");
+
+ result = TET_PASS;
+ e = NULL;
+ fd = -1;
+
+ for (fn = filenames; *fn; fn++) {
+ TS_OPEN_FILE(e,*fn,ELF_C_READ,fd);
+
+ if ((eh1 = gelf_getehdr(e, &d1)) == NULL ||
+ (eh2 = gelf_getehdr(e, &d2)) == NULL) {
+ tet_printf("unresolved: gelf_getehdr(%s) failed.",
+ *fn);
+ result = TET_UNRESOLVED;
+ goto done;
+ }
+
+ COMPARE_EHDR(*fn, d1, d2);
+
+ if (result != TET_PASS)
+ goto done;
+
+ (void) elf_end(e); e = NULL;
+ (void) close(fd); fd = -1;
+ }
+
+ done:
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+
+ tet_result(result);
+
+}
+
diff --git a/test/libelf/tset/gelf_newehdr/Makefile b/test/libelf/tset/gelf_newehdr/Makefile
new file mode 100644
index 0000000000000..8a5574404fdef
--- /dev/null
+++ b/test/libelf/tset/gelf_newehdr/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1189 2010-09-11 16:04:59Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= ehdr.m4
+TS_YAML= ehdr newehdr
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/gelf_newehdr/ehdr.m4 b/test/libelf/tset/gelf_newehdr/ehdr.m4
new file mode 100644
index 0000000000000..3cf55b66bc96e
--- /dev/null
+++ b/test/libelf/tset/gelf_newehdr/ehdr.m4
@@ -0,0 +1,470 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: ehdr.m4 2054 2011-10-26 12:12:06Z jkoshy $
+ */
+
+#include <sys/cdefs.h>
+
+#include <gelf.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+
+#include "elfts.h"
+
+#include "gelf_ehdr_template.h"
+
+include(`elfts.m4')
+
+/*
+ * A NULL `Elf *' argument returns an ELF_E_ARGUMENT error.
+ */
+undefine(`FN')dnl
+define(`FN',`
+void
+tcGelfGetNullElf$1(void)
+{
+ void *eh;
+ int error, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("gelf_newehdr(NULL,ELFCLASS$2) fails with "
+ "ELF_E_ARGUMENT.");
+
+ result = TET_PASS;
+ if ((eh = gelf_newehdr(NULL,ELFCLASS$1)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("eh=%p, error=\"%s\".", eh, elf_errmsg(error));
+
+ tet_result(result);
+}')
+
+FN(`NONE')
+FN(`32')
+FN(`64')
+
+/*
+ * For a non-NULL but non Elf descriptor, the function should fail
+ * with ELF_E_ARGUMENT.
+ */
+undefine(`FN')dnl
+define(`FN',`
+void
+tcDataNonElfDesc$1(void)
+{
+ int error, result;
+ void *eh;
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("gelf_newehdr(E,ELFCLASS$1) for non-ELF (E) "
+ "fails with ELF_E_ARGUMENT.");
+
+ TS_OPEN_MEMORY(e, data);
+
+ result = TET_PASS;
+ if ((eh = gelf_newehdr(e, ELFCLASS$1)) != NULL ||
+ (error = elf_errno()) != ELF_E_ARGUMENT)
+ TP_FAIL("eh=%p error=%d \"%s\".", (void *) eh,
+ error, elf_errmsg(error));
+
+ (void) elf_end(e);
+ tet_result(result);
+}')
+
+FN(`NONE')
+FN(`32')
+FN(`64')
+
+/*
+ * A valid Elf descriptor with of an unsupported version should
+ * return an ELF_E_VERSION error.
+ */
+undefine(`FN')dnl
+define(`FN',`
+void
+tcBadElfVersion$1$2(void)
+{
+ int err, result;
+ Elf *e;
+ void *eh;
+ char badelf[sizeof(badelftemplate)];
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("gelf_newehdr(E,ELFCLASS$1) with an unsupported "
+ "version fails with ELF_E_VERSION.");
+
+ (void) memcpy(badelf, badelftemplate, sizeof(badelf));
+
+ badelf[EI_VERSION] = EV_NONE;
+ badelf[EI_CLASS] = ELFCLASS$2;
+ badelf[EI_DATA] = ELFDATA2$1;
+
+ TS_OPEN_MEMORY(e, badelf);
+
+ result = TET_PASS;
+ if ((eh = gelf_newehdr(e, ELFCLASS$2)) != NULL ||
+ (err = elf_errno()) != ELF_E_VERSION)
+ TP_FAIL("eh=%p error=\"%s\".", (void *) eh, elf_errmsg(err));
+
+ (void) elf_end(e);
+ tet_result(result);
+}')
+
+FN(`LSB',`32')
+FN(`LSB',`64')
+FN(`MSB',`32')
+FN(`MSB',`64')
+
+/*
+ * A malformed ELF descriptor should return an ELF_E_HEADER error.
+ */
+undefine(`FN')dnl
+define(`FN',`
+void
+tcMalformedElf$1$2(void)
+{
+ int err, result;
+ Elf *e;
+ void *eh;
+ char badelf[sizeof(badelftemplate)];
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("gelf_newehdr($2,ELFCLASS$1) on a malformed "
+ "ELF header fails with ELF_E_HEADER.");
+
+ (void) memcpy(badelf, badelftemplate, sizeof(badelf));
+ badelf[EI_VERSION] = EV_CURRENT;
+ badelf[EI_CLASS] = ELFCLASS$1;
+ badelf[EI_DATA] = ELFDATA2$2;
+
+ TS_OPEN_MEMORY(e, badelf);
+
+ result = TET_PASS;
+ if ((eh = gelf_newehdr(e, ELFCLASS$1)) != NULL ||
+ (err = elf_errno()) != ELF_E_HEADER)
+ TP_FAIL("eh=%p error=\"%s\".", (void *) eh, elf_errmsg(err));
+
+ (void) elf_end(e);
+ tet_result(result);
+}')
+
+FN(`32',`LSB')
+FN(`32',`MSB')
+FN(`64',`LSB')
+FN(`64',`MSB')
+
+/*
+ * Attempting to open pre-existing ELF file of the wrong class
+ * should fail with ELF_E_CLASS.
+ */
+undefine(`FN')dnl
+define(`FN',`
+void
+tcWrongElfClass$1$2(void)
+{
+ int error, fd, result;
+ Elf$2_Ehdr *eh;
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("A call to gelf_newehdr(ehdr.$1$3,ELFCLASS$2) "
+ "fails with ELF_E_CLASS");
+
+ TS_OPEN_FILE(e, "ehdr.$1$3", ELF_C_READ, fd);
+
+ result = TET_PASS;
+ error = 0;
+ eh = NULL;
+
+ result = TET_PASS;
+ if ((eh = (Elf$2_Ehdr *) gelf_newehdr(e, ELFCLASS$2)) != NULL ||
+ (error = elf_errno()) != ELF_E_CLASS)
+ TP_FAIL("eh=%p, error=\"%s\".", (void *) eh, elf_errmsg(error));
+
+ (void) elf_end(e);
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(`lsb',`32',`64')
+FN(`lsb',`64',`32')
+FN(`msb',`32',`64')
+FN(`msb',`64',`32')
+
+/*
+ * Attempting to open a pre-existing ELF file of the correct class
+ * should succeed.
+ */
+undefine(`FN')
+define(`FN',`
+void
+tcElfValidClass$1$2(void)
+{
+ int fd, result;
+ Elf$2_Ehdr *eh;
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("a successful gelf_newehdr(ehdr.$1$2,"
+ "ELFCLASS$2) call returns the correct contents.");
+
+ TS_OPEN_FILE(e, "ehdr.$1$2", ELF_C_READ, fd);
+
+ result = TET_PASS;
+
+ result = TET_PASS;
+ if ((eh = (Elf$2_Ehdr *) gelf_newehdr(e, ELFCLASS$2)) == NULL) {
+ TP_FAIL("gelf_newehdr(ehdr.$1$2) failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ CHECK_EHDR(eh, ELFDATA2`'TOUPPER($1), ELFCLASS$2);
+
+ done:
+ (void) elf_end(e);
+ (void) close(fd);
+
+ tet_result(result);
+}')
+
+FN(`lsb',`32')
+FN(`lsb',`64')
+FN(`msb',`32')
+FN(`msb',`64')
+
+define(`TS_NEWELF',`"new.elf"')
+define(`CHECK_NEWEHDR',` do {
+ if (($1)->e_ident[EI_MAG0] != ELFMAG0 ||
+ ($1)->e_ident[EI_MAG1] != ELFMAG1 ||
+ ($1)->e_ident[EI_MAG2] != ELFMAG2 ||
+ ($1)->e_ident[EI_MAG3] != ELFMAG3 ||
+ ($1)->e_ident[EI_CLASS] != ELFCLASS$2 ||
+ ($1)->e_ident[EI_DATA] != ELFDATANONE ||
+ ($1)->e_ident[EI_VERSION] != EV_CURRENT ||
+ ($1)->e_machine != EM_NONE ||
+ ($1)->e_type != ELF_K_NONE ||
+ ($1)->e_version != EV_CURRENT)
+ TP_FAIL("gelf_getnewehdr(ELFCLASS$2) "
+ "header mismatch.");
+} while (0)
+')
+
+/*
+ * Retrieving the header from a new ELF file should return the
+ * correct values.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcNewElfExpected$1(void)
+{
+ int fd, result;
+ Elf$1_Ehdr *eh;
+ Elf *e;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("gelf_newehdr(new.elf,ELFCLASS$1) returns "
+ "the correct header.");
+
+ TS_OPEN_FILE(e, TS_NEWELF, ELF_C_WRITE, fd);
+
+ result = TET_PASS;
+ if ((eh = (Elf$1_Ehdr *) gelf_newehdr(e, ELFCLASS$1)) == NULL) {
+ TP_FAIL("gelf_newehdr("TS_NEWELF",ELFCLASS$1) failed: %s",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ CHECK_NEWEHDR(eh, $1);
+
+ done:
+ (void) elf_end(e);
+ (void) close(fd);
+ (void) unlink(TS_NEWELF);
+ tet_result(result);
+}')
+
+FN(`32')
+FN(`64')
+
+/*
+ * Allocating a new Ehdr should mark it as dirty.
+ */
+
+undefine(`FN')
+define(`FN',`
+void
+tcNewElfFlagDirty$1(void)
+{
+ Elf *e;
+ Elf$1_Ehdr *eh;
+ int fd, flags, result;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("gelf_newehdr("TS_NEWELF",ELFCLASS$1) marks "
+ "the header as dirty.");
+
+ TS_OPEN_FILE(e, TS_NEWELF, ELF_C_WRITE, fd);
+
+ if ((eh = (Elf$1_Ehdr *) gelf_newehdr(e, ELFCLASS$1)) == NULL) {
+ TP_FAIL("gelf_newehdr("TS_NEWELF",ELFCLASS$1) failed: %s.",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ flags = elf_flagehdr(e, ELF_C_CLR, 0);
+
+ result = (flags & ELF_F_DIRTY) == 0 ? TET_FAIL : TET_PASS;
+
+ done:
+ (void) elf_end(e);
+ (void) close(fd);
+ (void) unlink(TS_NEWELF);
+
+ tet_result(result);
+}')
+
+FN(`32')
+FN(`64')
+
+/*
+ * Allocating and updating an Elf_Ehdr works correctly.
+ */
+
+define(`TS_REFELF',`"newehdr."')
+
+undefine(`FN')
+define(`FN',`
+void
+tcUpdateElf$1$2(void)
+{
+ Elf$2_Ehdr *eh;
+ Elf *e;
+ int fd, reffd, result;
+ off_t offset;
+ size_t fsz;
+ void *t, *tref;
+
+ TP_CHECK_INITIALIZATION();
+
+ TP_ANNOUNCE("The contents of the $1$2 Ehdr structure are "
+ "correctly updated.");
+
+ t = tref = NULL;
+ fd = reffd = -1;
+
+ TS_OPEN_FILE(e, TS_NEWELF, ELF_C_WRITE, fd);
+
+ result = TET_UNRESOLVED;
+
+ if ((eh = (Elf$2_Ehdr *) gelf_newehdr(e, ELFCLASS$2)) == NULL) {
+ TP_UNRESOLVED("gelf_newehdr(ELFCLASS$2) failed: %s",
+ elf_errmsg(-1));
+ goto done;
+ }
+
+ eh->e_ident[EI_DATA] = ELFDATA2`'TOUPPER($1);
+
+ if ((offset = elf_update(e, ELF_C_WRITE)) < 0) {
+ TP_UNRESOLVED("elf_update() failed: %s.", elf_errmsg(-1));
+ goto done;
+ }
+
+ fsz = gelf_fsize(e, ELF_T_EHDR, 1, EV_CURRENT);
+
+ if (offset != fsz) {
+ TP_FAIL("elf_update() -> %d, expected %d.", offset, fsz);
+ goto done;
+ }
+
+ (void) elf_end(e); e = NULL;
+ (void) close(fd); fd = -1;
+
+ if ((t = malloc(fsz)) == NULL ||
+ (tref = malloc(fsz)) == NULL) {
+ TP_UNRESOLVED("malloc(%d) failed.", fsz);
+ goto done;
+ }
+
+ if ((fd = open(TS_NEWELF, O_RDONLY, 0)) < 0) {
+ TP_UNRESOLVED("open("TS_NEWELF") failed: %s", strerror(errno));
+ goto done;
+ }
+
+ if (read(fd, t, fsz) != fsz) {
+ TP_UNRESOLVED("read(%d) failed: %s", fsz, strerror(errno));
+ goto done;
+ }
+
+ if ((reffd = open(TS_REFELF "$1$2", O_RDONLY, 0)) < 0) {
+ TP_UNRESOLVED("open("TS_REFELF"$1$2) failed: %s.",
+ strerror(errno));
+ goto done;
+ }
+
+ if (read(reffd, tref, fsz) != fsz) {
+ TP_UNRESOLVED("read(%d) failed: %s.", fsz, strerror(errno));
+ goto done;
+ }
+
+ result = TET_PASS;
+ if (memcmp(t, tref, fsz) != 0)
+ TP_FAIL("memcmp("TS_NEWELF","TS_REFELF"$1$2) failed.");
+
+ done:
+ (void) unlink(TS_NEWELF);
+ if (e)
+ (void) elf_end(e);
+ if (fd != -1)
+ (void) close(fd);
+ if (reffd != -1)
+ (void) close(reffd);
+ if (t)
+ free(t);
+ if (tref)
+ free(tref);
+ tet_result(result);
+}')
+
+FN(`lsb',`32')
+FN(`lsb',`64')
+FN(`msb',`32')
+FN(`msb',`64')
diff --git a/test/libelf/tset/gelf_xlate/Makefile b/test/libelf/tset/gelf_xlate/Makefile
new file mode 100644
index 0000000000000..b0de14fe96cac
--- /dev/null
+++ b/test/libelf/tset/gelf_xlate/Makefile
@@ -0,0 +1,8 @@
+# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
+
+TOP= ../../../..
+
+TS_SRCS= xlate.m4
+TS_YAML= xlate
+
+.include "${TOP}/mk/elftoolchain.tet.mk"
diff --git a/test/libelf/tset/gelf_xlate/xlate.m4 b/test/libelf/tset/gelf_xlate/xlate.m4
new file mode 100644
index 0000000000000..1b9b447510aaf
--- /dev/null
+++ b/test/libelf/tset/gelf_xlate/xlate.m4
@@ -0,0 +1,1356 @@
+/*-
+ * Copyright (c) 2006,2011 Joseph Koshy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: xlate.m4 2586 2012-09-15 14:32:47Z jkoshy $
+ */
+
+#include <sys/cdefs.h>
+
+#include <gelf.h>
+#include <libelf.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tet_api.h"
+#include "elfts.h"
+
+include(`elfts.m4')
+
+IC_REQUIRES_VERSION_INIT();
+
+#define NO_TESTCASE_FUNCTIONS /* only want the tables */
+
+#define TS_XLATESZ 32
+#include "xlate_template.c"
+
+#undef TS_XLATESZ
+#define TS_XLATESZ 64
+#include "xlate_template.c"
+
+static int
+check_gelf_xlate(Elf_Data *xlator(Elf *e,Elf_Data *d, const Elf_Data *s, unsigned int enc),
+ Elf *e, int ed, Elf_Data *dst, Elf_Data *src, struct testdata *td, int ncopies)
+{
+ Elf_Data *dstret;
+ int result;
+ size_t msz;
+
+ msz = td->tsd_msz;
+ result = TET_UNRESOLVED;
+
+ /* Invoke translator */
+ if ((dstret = xlator(e, dst, src, ed)) != dst) {
+ TP_FAIL("\"%s\" " __XSTRING(TC_XLATETOM)
+ ": %s", td->tsd_name, elf_errmsg(-1));
+ return (result);
+ }
+
+ /* Check return parameters. */
+ if (dst->d_type != td->tsd_type || dst->d_size != msz*ncopies) {
+ TP_FAIL("\"%s\" type(ret=%d,expected=%d) "
+ "size (ret=%d,expected=%d).", td->tsd_name,
+ dst->d_type, td->tsd_type, dst->d_size, msz*ncopies);
+ return (result);
+ }
+
+ return (TET_PASS);
+}
+
+static const char *testfns[] = {
+ "xlate.lsb32",
+ "xlate.msb32",
+ "xlate.lsb64",
+ "xlate.msb64",
+ NULL
+};
+
+static int
+tcDriver(int (*tf)(const char *fn, Elf *e))
+{
+ int fd, result;
+ Elf *e;
+ const char **fn;
+
+ result = TET_PASS;
+ for (fn = testfns; result == TET_PASS && *fn; fn++) {
+
+ _TS_OPEN_FILE(e,*fn,ELF_C_READ,fd,;);
+
+ if (e == NULL) {
+ result = TET_UNRESOLVED;
+ break;
+ }
+
+ result = (*tf)(*fn, e);
+
+ (void) elf_end(e);
+ (void) close(fd);
+ }
+
+ return (result);
+}
+
+/*
+ * Check byte conversions:
+ */
+
+static int
+_tcByte(const char *fn, Elf *e)
+{
+ Elf_Data dst, src;
+ int i, offset, sz, result;
+ char *filebuf, *membuf, *t, *ref;
+
+ ref = td_L32_QUAD;
+ sz = sizeof(td_L32_QUAD);
+
+ if ((membuf = malloc(sz*NCOPIES)) == NULL ||
+ (filebuf = malloc(sz*NCOPIES+NOFFSET)) == NULL) {
+ TP_UNRESOLVED("malloc() failed.");
+ goto done;
+ }
+
+ /*
+ * Check memory to file conversions.
+ */
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++)
+ t = memcpy(t,ref,sz) + sz;
+
+ src.d_buf = membuf;
+ src.d_size = sz*NCOPIES;
+ src.d_type = ELF_T_BYTE;
+ src.d_version = EV_CURRENT;
+
+ TP_ANNOUNCE("\"%s\" Byte TOF() succeeds.", fn);
+
+ for (offset = 0; offset < NOFFSET; offset++) {
+ /*
+ * LSB
+ */
+ dst.d_buf = filebuf + offset;
+ dst.d_size = sz*NCOPIES;
+ dst.d_version = EV_CURRENT;
+
+ if (gelf_xlatetof(e,&dst,&src,ELFDATA2LSB) != &dst ||
+ dst.d_size != sz*NCOPIES) {
+ TP_FAIL("LSB TOF() conversion.");
+ goto done;
+ }
+
+ if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) {
+ TP_FAIL("LSB TOF() memcmp().");
+ goto done;
+ }
+
+ /*
+ * MSB
+ */
+ dst.d_buf = filebuf + offset;
+ dst.d_size = sz*NCOPIES;
+ dst.d_version = EV_CURRENT;
+
+ if (gelf_xlatetof(e,&dst,&src,ELFDATA2MSB) != &dst ||
+ dst.d_size != sz*NCOPIES) {
+ TP_FAIL("MSB TOF() conversion.");
+ goto done;
+ }
+
+ if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) {
+ TP_FAIL("MSB TOF() memcmp().");
+ goto done;
+ }
+ }
+
+ /*
+ * Check file to memory conversions.
+ */
+
+ TP_ANNOUNCE("\"%s\" Byte TOM() succeeds.", fn);
+
+ ref = td_M32_QUAD;
+ sz = sizeof(td_M32_QUAD);
+
+ for (offset = 0; offset < NOFFSET; offset++) {
+
+ src.d_buf = t = filebuf + offset;
+ for (i = 0; i < NCOPIES; i++)
+ t = memcpy(t,ref,sz);
+
+ src.d_size = sz*NCOPIES;
+ src.d_type = ELF_T_BYTE;
+ src.d_version = EV_CURRENT;
+
+ /*
+ * LSB
+ */
+ dst.d_buf = membuf;
+ dst.d_size = sz*NCOPIES;
+ dst.d_version = EV_CURRENT;
+
+ if (gelf_xlatetom(e,&dst,&src,ELFDATA2LSB) != &dst ||
+ dst.d_size != sz * NCOPIES) {
+ TP_FAIL("LSB TOM() conversion.");
+ goto done;
+ }
+
+ if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) {
+ TP_FAIL("LSB TOM() memcmp().");
+ goto done;
+ }
+
+ /*
+ * MSB
+ */
+ dst.d_buf = membuf;
+ dst.d_size = sz*NCOPIES;
+ dst.d_version = EV_CURRENT;
+
+ if (gelf_xlatetom(e,&dst,&src,ELFDATA2MSB) != &dst ||
+ dst.d_size != sz * NCOPIES) {
+ TP_FAIL("MSB TOM() conversion.");
+ goto done;
+ }
+
+ if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) {
+ TP_FAIL("MSB TOM() memcmp().");
+ goto done;
+ }
+ }
+
+ result = TET_PASS;
+
+ done:
+ if (membuf)
+ free(membuf);
+ if (filebuf)
+ free(filebuf);
+
+ return (result);
+}
+
+void
+tcXlateByte(void)
+{
+ tet_result(tcDriver(_tcByte));
+}
+
+static int
+_tpToM(const char *fn, Elf *e)
+{
+ Elf_Data dst, src;
+ struct testdata *td;
+ size_t fsz, msz;
+ int i, offset, result;
+ char *srcbuf, *membuf, *t;
+
+ srcbuf = NULL; /* file data (bytes) */
+ membuf = NULL; /* memory data (struct) */
+
+ result = TET_PASS;
+
+ td = gelf_getclass(e) == ELFCLASS32 ? tests32 : tests64;
+
+ /* Loop over all types for this ELF class */
+ for (; td->tsd_name; td++) {
+
+ fsz = gelf_fsize(e, td->tsd_type, 1, EV_CURRENT);
+ msz = td->tsd_msz;
+
+ if (msz == 0 ||
+ fsz != td->tsd_fsz) {
+ TP_UNRESOLVED("\"%s\" %s: msz=%d fsz=%d td->fsz=%d.",
+ fn, td->tsd_name, msz, fsz, td->tsd_fsz);
+ goto done;
+ }
+
+ assert(fsz == td->tsd_fsz);
+
+ /*
+ * allocate space for NCOPIES of data + offset for file data and
+ * NCOPIES of memory data.
+ */
+ if ((srcbuf = malloc(NCOPIES*fsz+NOFFSET)) == NULL ||
+ ((membuf = malloc(NCOPIES*msz))) == NULL) {
+ TP_UNRESOLVED("malloc() failed.");
+ goto done;
+ }
+
+
+ TP_ANNOUNCE("\"%s\" gelf_xlatetom(%s) succeeds.", fn,
+ td->tsd_name);
+
+ for (offset = 0; offset < NOFFSET; offset++) {
+
+ src.d_buf = t = srcbuf + offset;
+ src.d_size = fsz * NCOPIES;
+ src.d_type = td->tsd_type;
+ src.d_version = EV_CURRENT;
+
+ dst.d_buf = membuf;
+ dst.d_size = msz * NCOPIES;
+ dst.d_version = EV_CURRENT;
+
+
+ /*
+ * Check conversion of LSB encoded data.
+ */
+
+ /* copy `NCOPIES*fsz' bytes in `srcbuf+offset' */
+ for (i = 0; i < NCOPIES; i++) {
+ (void) memcpy(t, td->tsd_lsb, fsz);
+ t += fsz;
+ }
+ (void) memset(membuf, 0, NCOPIES*msz);
+
+ if ((result = check_gelf_xlate(gelf_xlatetom,e,
+ ELFDATA2LSB, &dst,&src,td,NCOPIES)) !=
+ TET_PASS)
+ goto done;
+
+ /*
+ * Compare the retrieved data with the canonical
+ * value
+ */
+ t = dst.d_buf;
+ for (i = 0; i < NCOPIES; i++) {
+ if (memcmp(t, td->tsd_mem, msz)) {
+ TP_FAIL("\"%s\" \"%s\" LSB "
+ "memory compare failed.", fn,
+ td->tsd_name);
+ goto done;
+ }
+ t += msz;
+ }
+
+ /*
+ * Check conversion of MSB encoded data.
+ */
+
+ t = srcbuf + offset;
+ for (i = 0; i < NCOPIES; i++) {
+ (void) memcpy(t, td->tsd_msb, fsz);
+ t += fsz;
+ }
+ (void) memset(membuf, 0, NCOPIES*msz);
+ if ((result = check_gelf_xlate(gelf_xlatetom,e,
+ ELFDATA2MSB, &dst,&src,td,NCOPIES)) !=
+ TET_PASS)
+ goto done;
+
+ /* compare the retrieved data with the canonical value */
+ t = dst.d_buf;
+ for (i = 0; i < NCOPIES; i++) {
+ if (memcmp(t, td->tsd_mem, msz)) {
+ TP_FAIL("\"%s\" \"%s\" MSB "
+ "memory compare failed.", fn,
+ td->tsd_name);
+ goto done;
+ }
+ t += msz;
+ }
+ }
+
+ free(srcbuf); srcbuf = NULL;
+ free(membuf); membuf = NULL;
+ }
+
+ done:
+ if (srcbuf)
+ free(srcbuf);
+ if (membuf)
+ free(membuf);
+
+ return (result);
+}
+
+void
+tcXlateToM(void)
+{
+ tet_result(tcDriver(_tpToM));
+}
+
+/*
+ * Check non-byte conversions from memory to file.
+ */
+static int
+_tpToF(const char *fn, Elf *e)
+{
+ Elf_Data dst, src;
+ struct testdata *td;
+ size_t fsz, msz;
+ int i, offset, result;
+ char *filebuf, *membuf, *t;
+
+ filebuf = NULL; /* file data (bytes) */
+ membuf = NULL; /* memory data (struct) */
+
+ td = gelf_getclass(e) == ELFCLASS32 ? tests32 : tests64;
+
+ result = TET_PASS;
+
+ /* Loop over all types */
+ for (; td->tsd_name; td++) {
+
+ fsz = gelf_fsize(e, td->tsd_type, 1, EV_CURRENT);
+ msz = td->tsd_msz;
+
+ if (msz == 0 ||
+ fsz != td->tsd_fsz) {
+ TP_UNRESOLVED("? \"%s\" %s: msz=%d fsz=%d td->fsz=%d.",
+ fn, td->tsd_name, msz, fsz, td->tsd_fsz);
+ goto done;
+ }
+
+ assert(msz > 0);
+ assert(fsz == td->tsd_fsz);
+
+ /*
+ * allocate space for NCOPIES of data + offset for file data and
+ * NCOPIES of memory data.
+ */
+ if ((filebuf = malloc(NCOPIES*fsz+NOFFSET)) == NULL ||
+ ((membuf = malloc(NCOPIES*msz))) == NULL) {
+ TP_UNRESOLVED("malloc() failed.");
+ goto done;
+ }
+
+
+ TP_ANNOUNCE("\"%s\" gelf_xlatetof(%s) succeeds.", fn,
+ td->tsd_name);
+
+ for (offset = 0; offset < NOFFSET; offset++) {
+
+ src.d_buf = membuf;
+ src.d_size = msz * NCOPIES;
+ src.d_type = td->tsd_type;
+ src.d_version = EV_CURRENT;
+
+ /*
+ * Check LSB conversion.
+ */
+
+ /*
+ * Copy `NCOPIES' of canonical memory data to the
+ * src buffer.
+ */
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++) {
+ (void) memcpy(t, td->tsd_mem, msz);
+ t += msz;
+ }
+ (void) memset(filebuf, 0, NCOPIES*fsz+NOFFSET);
+
+ dst.d_buf = filebuf + offset;
+ dst.d_size = fsz * NCOPIES;
+ dst.d_version = EV_CURRENT;
+
+ if ((result = check_gelf_xlate(gelf_xlatetof, e,
+ ELFDATA2LSB, &dst, &src, td, NCOPIES)) !=
+ TET_PASS)
+ goto done;
+
+ /* compare converted data to canonical form */
+ t = filebuf + offset;
+ for (i = 0; i < NCOPIES; i++) {
+ if (memcmp(t, td->tsd_lsb, fsz)) {
+ TP_FAIL("\"%s\" \"%s\" LSB memory "
+ "compare.", fn, td->tsd_name);
+ goto done;
+ }
+ t += fsz;
+ }
+
+ /*
+ * Check MSB conversion.
+ */
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++) {
+ (void) memcpy(t, td->tsd_mem, msz);
+ t += msz;
+ }
+ (void) memset(filebuf, 0, NCOPIES*fsz+NOFFSET);
+
+ dst.d_buf = filebuf + offset;
+ dst.d_size = fsz * NCOPIES;
+ dst.d_version = EV_CURRENT;
+
+ if ((result = check_gelf_xlate(gelf_xlatetof, e,
+ ELFDATA2MSB, &dst, &src, td, NCOPIES)) ==
+ TET_PASS)
+ goto done;
+
+ /* compare converted data to canonical form */
+ t = filebuf + offset;
+ for (i = 0; i < NCOPIES; i++) {
+ if (memcmp(t, td->tsd_msb, fsz)) {
+ TP_FAIL("\"%s\" \"%s\" MSB "
+ "memory compare.", fn,
+ td->tsd_name);
+ goto done;
+ }
+ t += fsz;
+ }
+ }
+
+ free(filebuf); filebuf = NULL;
+ free(membuf); membuf = NULL;
+ }
+
+ done:
+ if (filebuf)
+ free(filebuf);
+ if (membuf)
+ free(membuf);
+
+ return (result);
+}
+
+void
+tcXlateToF(void)
+{
+ tet_result(tcDriver(_tpToF));
+}
+
+
+/*
+ * Various checks for invalid arguments.
+ */
+
+static int
+_tpNullArgs(const char *fn, Elf *e)
+{
+ Elf_Data ed;
+ int result;
+
+ TP_ANNOUNCE("gelf_xlatetof(%s)/gelf_xlatetom(%s)"
+ " with NULL arguments fails with ELF_E_ARGUMENT.",
+ fn, fn);
+
+ result = TET_PASS;
+
+ if (gelf_xlatetof(NULL, NULL, NULL, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ if (gelf_xlatetof(e, NULL, &ed, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ if (gelf_xlatetof(e, &ed, NULL, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ if (gelf_xlatetom(NULL, NULL, NULL, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ if (gelf_xlatetom(e, NULL, &ed, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ if (gelf_xlatetom(e, &ed, NULL, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ return (result);
+}
+
+void
+tcArgsNull(void)
+{
+ tet_result(tcDriver(_tpNullArgs));
+}
+
+
+static int
+_tpBadType(const char *fn, Elf *e)
+{
+ Elf_Data ed, es;
+ int result;
+ char buf[1024];
+
+ TP_ANNOUNCE("gelf_xlatetof(%s)/"
+ "gelf_xlatetom(%s) with an out of range type "
+ "fails with ELF_E_DATA.", fn, fn);
+
+ result = TET_PASS;
+
+ es.d_version = ed.d_version = EV_CURRENT;
+ es.d_buf = ed.d_buf = buf;
+ es.d_size = ed.d_size = sizeof(buf);
+
+ es.d_type = (Elf_Type) -1;
+
+ if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ es.d_type = ELF_T_NUM;
+
+ if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ return (result);
+}
+
+void
+tcArgsBadType(void)
+{
+ tet_result(tcDriver(_tpBadType));
+}
+
+static int
+_tpBadEncoding(const char *fn, Elf *e)
+{
+ Elf_Data ed, es;
+ int result;
+
+ TP_ANNOUNCE("gelf_xlatetof/"
+ "gelf_xlatetom()(*,*,BADENCODING) "
+ "fails with ELF_E_ARGUMENT.");
+
+ result = TET_PASS;
+
+ if (gelf_xlatetof(e, &ed, &es, ELFDATANONE-1) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+ else if (gelf_xlatetof(e, &ed, &es, ELFDATA2MSB+1) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ if (gelf_xlatetom(e, &ed, &es, ELFDATANONE-1) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+ else if (gelf_xlatetom(e, &ed, &es, ELFDATA2MSB+1) != NULL ||
+ elf_errno() != ELF_E_ARGUMENT)
+ result = TET_FAIL;
+
+ return (result);
+}
+
+void
+tcArgsBadEncoding(void)
+{
+ tet_result(tcDriver(_tpBadEncoding));
+}
+
+static int
+_tpDstSrcVersion(const char *fn, Elf *e)
+{
+ Elf_Data ed, es;
+ int result;
+ char buf[sizeof(int)];
+
+ TP_ANNOUNCE("gelf_xlateto[fm]() with unequal src,dst versions "
+ "fails with ELF_E_UNIMPL.");
+
+ es.d_buf = ed.d_buf = buf;
+ es.d_type = ELF_T_BYTE;
+ es.d_size = ed.d_size = sizeof(buf);
+ es.d_version = EV_CURRENT;
+ ed.d_version = EV_NONE;
+
+ result = TET_PASS;
+
+ if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_UNIMPL)
+ result = TET_FAIL;
+
+ if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_UNIMPL)
+ result = TET_FAIL;
+
+ return (result);
+}
+
+void
+tcArgsDstSrcVersion(void)
+{
+ tet_result(tcDriver(_tpDstSrcVersion));
+}
+
+/*
+ * Check for an unimplemented type.
+ */
+static int
+_tpUnimplemented(const char *fn, Elf *e)
+{
+ Elf_Data ed, es;
+ int i, result;
+ char *buf;
+
+ buf = NULL;
+ result = TET_UNRESOLVED;
+
+ TP_ANNOUNCE("gelf_xlateto[fm]() on unimplemented types will "
+ "fail with ELF_E_UNIMPL.");
+
+ /*
+ * allocate a buffer that is large enough for any potential
+ * ELF data structure.
+ */
+ if ((buf = malloc(1024)) == NULL) {
+ TP_UNRESOLVED("malloc() failed.");
+ goto done;
+ }
+
+ ed.d_buf = es.d_buf = buf;
+ ed.d_size = es.d_size = 1024;
+ ed.d_version = es.d_version = EV_CURRENT;
+
+ result = TET_PASS;
+
+ for (i = 0; i < ELF_T_NUM; i++) {
+ switch (i) {
+ case ELF_T_MOVEP:
+ break;
+
+ case ELF_T_SXWORD: /* unimplemented for 32 bit ELF */
+ case ELF_T_XWORD:
+ if (gelf_getclass(e) == ELFCLASS64)
+ continue;
+ break;
+ default:
+ continue;
+ }
+
+ es.d_type = i;
+
+ if (gelf_xlatetof(e, &ed, &es, ELFDATA2LSB) != NULL ||
+ elf_errno() != ELF_E_UNIMPL) {
+ TP_FAIL("TOF/LSB/type=%d.", i);
+ goto done;
+ }
+
+ if (gelf_xlatetof(e, &ed, &es, ELFDATA2MSB) != NULL ||
+ elf_errno() != ELF_E_UNIMPL) {
+ TP_FAIL("TOF/MSB/type=%d.", i);
+ goto done;
+ }
+
+ if (gelf_xlatetom(e, &ed, &es, ELFDATA2LSB) != NULL ||
+ elf_errno() != ELF_E_UNIMPL) {
+ TP_FAIL("TOM/LSB/type=%d.", i);
+ goto done;
+ }
+
+ if (gelf_xlatetom(e, &ed, &es, ELFDATA2MSB) != NULL ||
+ elf_errno() != ELF_E_UNIMPL) {
+ TP_FAIL("fail: TOM/MSB/type=%d.", i);
+ goto done;
+ }
+ }
+
+done:
+ if (buf)
+ free(buf);
+ return (result);
+}
+
+void
+tcArgsUnimplemented(void)
+{
+ tet_result(tcDriver(_tpUnimplemented));
+}
+
+/*
+ * Check for null buffer pointers.
+ */
+static int
+_tpNullDataPtr(const char *fn, Elf *e)
+{
+ Elf_Data ed, es;
+ int result;
+ char buf[sizeof(int)];
+
+ TP_ANNOUNCE("gelf_xlateto[fm](%s) with a null "
+ "src,dst buffer pointer fails with ELF_E_DATA.", fn);
+
+ result = TET_PASS;
+
+ es.d_type = ELF_T_BYTE;
+ es.d_size = ed.d_size = sizeof(buf);
+ es.d_version = EV_CURRENT;
+ ed.d_version = EV_CURRENT;
+
+ es.d_buf = NULL;
+ ed.d_buf = buf;
+ if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ es.d_buf = buf;
+ ed.d_buf = NULL;
+ if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA)
+ result = TET_FAIL;
+
+ return (result);
+}
+
+void
+tcBufferNullDataPtr(void)
+{
+ tet_result(tcDriver(_tpNullDataPtr));
+}
+
+/*
+ * Misaligned data.
+ */
+
+static int
+_tpMisaligned(const char *fn, Elf *e)
+{
+ Elf_Data ed, es;
+ int result;
+ size_t fsz, msz;
+ char *sb, *db;
+ struct testdata *td;
+
+ sb = db = NULL;
+ result = TET_UNRESOLVED;
+
+ TP_ANNOUNCE("\"%s\" misaligned buffers are rejected with "
+ "ELF_E_DATA.", fn);
+
+ if ((sb = malloc(1024)) == NULL ||
+ (db = malloc(1024)) == NULL) {
+ TP_UNRESOLVED("malloc() failed.");
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ td = gelf_getclass(e) == ELFCLASS32 ? tests32 : tests64;
+
+ for (; td->tsd_name; td++) {
+ fsz = td->tsd_fsz;
+ msz = td->tsd_msz;
+
+ es.d_type = td->tsd_type;
+ es.d_version = EV_CURRENT;
+
+ /* Misalign the destination for to-memory xfers */
+ es.d_size = (1024 / fsz) * fsz; /* round down */
+ es.d_buf = sb;
+
+ ed.d_buf = db + 1; /* guaranteed to be misaliged */
+ ed.d_version = EV_CURRENT;
+ ed.d_size = 1024;
+
+ if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ TP_FAIL("\"%s\" TOM alignment.", td->tsd_name);
+ goto done;
+ }
+
+ /* Misalign the source for to-file xfers */
+ es.d_buf = sb + 1;
+ es.d_size = (1024/msz) * msz; /* round down */
+ ed.d_buf = db;
+
+ if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ TP_FAIL("\"%s\" TOF alignment.",
+ td->tsd_name);
+ goto done;
+ }
+ }
+
+done:
+ if (sb)
+ free(sb);
+ if (db)
+ free(db);
+ return (result);
+}
+
+void
+tcBufferMisaligned(void)
+{
+ tet_result(tcDriver(_tpMisaligned));
+}
+
+/*
+ * Overlapping buffers.
+ */
+static int
+_tpOverlap(const char *fn, Elf *e)
+{
+ Elf_Data ed, es;
+ int result;
+ char buf[sizeof(int)];
+
+ TP_ANNOUNCE("\"%s\" overlapping buffers are rejected with "
+ "ELF_E_DATA.", fn);
+
+ es.d_buf = buf; ed.d_buf = buf+1;
+ es.d_version = ed.d_version = EV_CURRENT;
+ es.d_size = ed.d_size = sizeof(buf);
+ es.d_type = ELF_T_BYTE;
+
+ result = TET_PASS;
+
+ if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ TP_FAIL("gelf_xlatetof().");
+ goto done;
+ }
+
+ if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ TP_FAIL("gelf_xlatetom().");
+ goto done;
+ }
+
+done:
+ return (result);
+}
+
+void
+tcBufferOverlap(void)
+{
+ tet_result(tcDriver(_tpOverlap));
+}
+
+/*
+ * Non-integral number of src elements.
+ */
+static int
+_tpSrcExtra(const char *fn, Elf *e)
+{
+ Elf_Data ed, es;
+ int result;
+ size_t fsz, msz;
+ char *sb, *db;
+ struct testdata *td;
+
+ TP_ANNOUNCE("\"%s\" mis-sized buffers are rejected with "
+ "ELF_E_DATA.", fn);
+
+ sb = db = NULL;
+ if ((sb = malloc(1024)) == NULL ||
+ (db = malloc(1024)) == NULL) {
+ TP_UNRESOLVED("malloc() failed.");
+ goto done;
+ }
+
+ result = TET_PASS;
+
+ td = gelf_getclass(e) == ELFCLASS32 ? tests32 : tests64;
+
+ for (; td->tsd_name; td++) {
+ fsz = td->tsd_fsz;
+ msz = td->tsd_msz;
+
+ es.d_type = td->tsd_type;
+ es.d_version = EV_CURRENT;
+ ed.d_version = EV_CURRENT;
+ ed.d_buf = db;
+ es.d_buf = sb;
+ ed.d_size = 1024;
+
+ /* Pad src bytes with extra bytes for to memor */
+ es.d_size = fsz+1;
+
+ if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ TP_FAIL("\"%s\" TOM buffer size.", td->tsd_name);
+ goto done;
+ }
+
+ es.d_size = msz+1;
+ if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ TP_FAIL("\"%s\" TOF buffer size.", td->tsd_name);
+ goto done;
+ }
+ }
+
+done:
+ if (sb)
+ free(sb);
+ if (db)
+ free(db);
+
+ return (result);
+}
+
+void
+tcBufferSrcExtra(void)
+{
+ tet_result(tcDriver(_tpSrcExtra));
+}
+
+static int
+_tpDstTooSmall(const char *fn, Elf *e)
+{
+ Elf_Data ed, es;
+ int result;
+ struct testdata *td;
+ size_t fsz, msz;
+ char buf[1024];
+
+ result = TET_PASS;
+
+ TP_ANNOUNCE("\"%s\" too small destination buffers are "
+ "rejected with ELF_E_DATA.", fn);
+
+ td = gelf_getclass(e) == ELFCLASS32 ? tests32 : tests64;
+
+ for (; td->tsd_name; td++) {
+ msz = td->tsd_msz;
+ fsz = td->tsd_fsz;
+
+ es.d_type = td->tsd_type;
+ es.d_version = ed.d_version = EV_CURRENT;
+ es.d_buf = ed.d_buf = buf;
+
+ es.d_size = (sizeof(buf) / msz) * msz;
+ ed.d_size = 1; /* too small a size */
+
+ if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ TP_FAIL("\"%s\" TOF dst size.", td->tsd_name);
+ goto done;
+ }
+
+ es.d_size = (sizeof(buf) / fsz) * fsz;
+ if (gelf_xlatetom(e, &ed,&es,ELFDATANONE) != NULL ||
+ elf_errno() != ELF_E_DATA) {
+ TP_FAIL("\"%s\" TOF dst size.", td->tsd_name);
+ goto done;
+ }
+ }
+
+done:
+ return (result);
+}
+
+void
+tcBufferDstTooSmall(void)
+{
+ tet_result(tcDriver(_tpDstTooSmall));
+}
+
+static int
+_tpSharedBufferByte(const char *fn, Elf *e)
+{
+ int i, result;
+ size_t sz;
+ Elf_Data dst, src;
+ char *membuf, *t, *ref;
+
+#define PREPARE_SHARED(T,SZ) do { \
+ src.d_buf = dst.d_buf = membuf; \
+ src.d_size = dst.d_size = (SZ) * NCOPIES; \
+ src.d_type = dst.d_type = (T); \
+ src.d_version = dst.d_version = EV_CURRENT; \
+ } while (0)
+
+#define VERIFY(R,SZ) do { \
+ t = dst.d_buf; \
+ for (i = 0; i < NCOPIES; i++, t += (SZ)) \
+ if (memcmp((R), t, (SZ))) { \
+ TP_FAIL("LSB TOF() memcmp()."); \
+ goto done; \
+ } \
+ } while (0)
+
+ membuf = NULL;
+ ref = TYPEDEFNAME(L,QUAD);
+ sz = sizeof(TYPEDEFNAME(L,QUAD));
+
+ if ((membuf = malloc(sz * NCOPIES)) == NULL) {
+ TP_UNRESOLVED("\"%s\" malloc() failed.", fn);
+ return (TET_UNRESOLVED);
+ }
+
+ result = TET_PASS;
+
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++)
+ t = memcpy(t, ref, sz) + sz;
+
+ TP_ANNOUNCE("\"%s\" byte TOF() on a shared dst/src arena "
+ "succeeds.", fn);
+
+ PREPARE_SHARED(ELF_T_BYTE, sz);
+ if (gelf_xlatetof(e, &dst, &src, ELFDATA2LSB) != &dst ||
+ dst.d_size != sz * NCOPIES ||
+ dst.d_buf != src.d_buf) {
+ TP_FAIL("\"%s\" LSB TOF() conversion: %s.", fn,
+ elf_errmsg(-1));
+ goto done;
+ }
+ VERIFY(ref,sz);
+
+ PREPARE_SHARED(ELF_T_BYTE, sz);
+ if (gelf_xlatetof(e, &dst, &src, ELFDATA2MSB) != &dst ||
+ dst.d_size != sz * NCOPIES ||
+ dst.d_buf != src.d_buf) {
+ TP_FAIL("\"%s\" MSB TOF() conversion: %s.", fn,
+ elf_errmsg(-1));
+ goto done;
+ }
+ VERIFY(ref,sz);
+
+ TP_ANNOUNCE("assertion: \"%s\" byte TOM() on a shared dst/src arena "
+ "succeeds.", fn);
+
+ PREPARE_SHARED(ELF_T_BYTE, sz);
+ if (gelf_xlatetom(e, &dst, &src, ELFDATA2LSB) != &dst ||
+ dst.d_size != sz * NCOPIES ||
+ dst.d_buf != src.d_buf) {
+ TP_FAIL("\"%s\" LSB TOM() conversion: %s.", fn,
+ elf_errmsg(-1));
+ goto done;
+ }
+ VERIFY(ref,sz);
+
+ PREPARE_SHARED(ELF_T_BYTE, sz);
+ if (gelf_xlatetom(e, &dst, &src, ELFDATA2MSB) != &dst ||
+ dst.d_size != sz * NCOPIES ||
+ dst.d_buf != src.d_buf) {
+ TP_FAIL("\"%s\" MSB TOM() conversion: %s.", fn,
+ elf_errmsg(-1));
+ goto done;
+ }
+ VERIFY(ref,sz);
+
+ done:
+ if (membuf)
+ free(membuf);
+
+ return (result);
+}
+
+
+void
+tcBufferSharedBufferByte(void)
+{
+ tet_result(tcDriver(_tpSharedBufferByte));
+}
+
+static int
+_tpToMShared(const char *fn, Elf *e)
+{
+ Elf_Data dst, src;
+ struct testdata *td;
+ size_t fsz, msz;
+ int i, r, result;
+ char *membuf, *t;
+
+ membuf = NULL;
+
+ td = gelf_getclass(e) == ELFCLASS32 ? tests32 : tests64;
+
+ result = TET_PASS;
+
+ for (; td->tsd_name; td++) {
+
+ TP_ANNOUNCE("\"%s\" in-place gelf_xlatetom"
+ "(\"%s\").", fn, td->tsd_name);
+
+ fsz = gelf_fsize(e, td->tsd_type, 1, EV_CURRENT);
+ msz = td->tsd_msz;
+
+ assert(msz >= fsz);
+
+ if ((membuf = malloc(fsz * NCOPIES)) == NULL) {
+ TP_UNRESOLVED("\"%s\" \"%s\" malloc() failed.",
+ fn, td->tsd_name);
+ goto done;
+ }
+
+ /*
+ * In-place conversion of LSB data.
+ */
+
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++)
+ t = memcpy(t, td->tsd_lsb, fsz) + fsz;
+
+ PREPARE_SHARED(td->tsd_type, fsz);
+ r = gelf_xlatetom(e, &dst, &src, ELFDATA2LSB) == &dst;
+
+ if (fsz < msz) {
+ /* conversion should fail with ELF_E_DATA */
+ if (r || elf_errno() != ELF_E_DATA) {
+ TP_FAIL("\"%s\" \"%s\" LSB TOM() succeeded "
+ "with fsz < msz", fn, td->tsd_name);
+ goto done;
+ }
+ free(membuf); membuf = NULL;
+ continue;
+ }
+
+ /* conversion should have succeeded. */
+ if (!r) {
+ TP_FAIL("\"%s\" \"%s\" LSB TOM() failed.",
+ fn, td->tsd_name);
+ goto done;
+ }
+
+ VERIFY(td->tsd_mem,msz);
+
+ /*
+ * In-place conversion of MSB data.
+ */
+
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++)
+ t = memcpy(t, td->tsd_msb, fsz) + fsz;
+
+ PREPARE_SHARED(td->tsd_type, fsz);
+ r = gelf_xlatetom(e, &dst, &src, ELFDATA2MSB) == &dst;
+
+ if (fsz < msz) {
+ /* conversion should fail with ELF_E_DATA */
+ if (r || elf_errno() != ELF_E_DATA) {
+ TP_FAIL("\"%s\" \"%s\" MSB TOM() succeeded "
+ "with fsz < msz", fn, td->tsd_name);
+ goto done;
+ }
+ free(membuf); membuf = NULL;
+ continue;
+ }
+
+ /* conversion should have succeeded. */
+ if (!r) {
+ TP_FAIL("\"%s\" \"%s\" MSB TOM() failed.",
+ fn, td->tsd_name);
+ goto done;
+ }
+
+ VERIFY(td->tsd_mem,msz);
+
+ }
+
+ done:
+ if (membuf)
+ free(membuf);
+ return (result);
+}
+
+void
+tcXlateToMShared(void)
+{
+ tet_result(tcDriver(_tpToMShared));
+}
+
+static int
+_tpToFShared(const char *fn, Elf *e)
+{
+ Elf_Data dst, src;
+ struct testdata *td;
+ size_t fsz, msz;
+ int i, result;
+ char *membuf, *t;
+
+ membuf = NULL;
+
+ td = gelf_getclass(e) == ELFCLASS32 ? tests32 : tests64;
+ result = TET_PASS;
+
+ for (; td->tsd_name; td++) {
+
+ TP_ANNOUNCE("\"%s\" in-place gelf_xlatetof(\"%s\").",
+ fn, td->tsd_name);
+
+ fsz = gelf_fsize(e, td->tsd_type, 1, EV_CURRENT);
+ msz = td->tsd_msz;
+
+ assert(msz >= fsz);
+
+ if ((membuf = malloc(msz * NCOPIES)) == NULL) {
+ TP_UNRESOLVED("\"%s\" \"%s\" malloc() failed.",
+ fn, td->tsd_name);
+ goto done;
+ }
+
+ /*
+ * In-place conversion to LSB data.
+ */
+
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++)
+ t = memcpy(t, td->tsd_mem, msz) + msz;
+
+ PREPARE_SHARED(td->tsd_type, msz);
+ if (gelf_xlatetof(e, &dst, &src, ELFDATA2LSB) != &dst) {
+ TP_FAIL("\"%s\" \"%s\" LSB TOF() failed: %s.",
+ fn, td->tsd_name, elf_errmsg(-1));
+ goto done;
+ }
+ VERIFY(td->tsd_lsb,fsz);
+
+ /*
+ * In-place conversion to MSB data.
+ */
+
+ t = membuf;
+ for (i = 0; i < NCOPIES; i++)
+ t = memcpy(t, td->tsd_mem, msz) + msz;
+
+ PREPARE_SHARED(td->tsd_type, msz);
+ if (gelf_xlatetof(e, &dst, &src, ELFDATA2MSB) != &dst) {
+ TP_FAIL("\"%s\" \"%s\" MSB TOF() failed: %s.",
+ fn, td->tsd_name, elf_errmsg(-1));
+ goto done;
+ }
+ VERIFY(td->tsd_msb,fsz);
+ }
+
+ done:
+ if (membuf)
+ free(membuf);
+ return (result);
+}
+
+void
+tcXlateToFShared(void)
+{
+ tet_result(tcDriver(_tpToFShared));
+}