aboutsummaryrefslogtreecommitdiff
path: root/test/libelf/tset/common
diff options
context:
space:
mode:
Diffstat (limited to 'test/libelf/tset/common')
-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
33 files changed, 5829 insertions, 0 deletions
diff --git a/test/libelf/tset/common/Makefile b/test/libelf/tset/common/Makefile
new file mode 100644
index 000000000000..5dd5bf9c1a5b
--- /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 000000000000..6c9bc06cd00e
--- /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 000000000000..cf4edf9da615
--- /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 000000000000..4f60fffa1a3e
--- /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 000000000000..cc92f3e68c22
--- /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 000000000000..6d22dc9f0dd3
--- /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 000000000000..1fef268e3dbd
--- /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 000000000000..bab1cc91d7e8
--- /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 000000000000..6f6640a489f6
--- /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 000000000000..b1632da831d6
--- /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 000000000000..cd6cbe7b1cbe
--- /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 000000000000..741409e28d02
--- /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 000000000000..f438651febcc
--- /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 000000000000..060c1f44a420
--- /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 000000000000..bc717dbe6167
--- /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 000000000000..52a7cea3ec86
--- /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 000000000000..735a45023815
--- /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 000000000000..f9f2c7d8dfe2
--- /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 000000000000..14ad5d1bb0af
--- /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 000000000000..808743d9639d
--- /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 000000000000..927c5a4865d4
--- /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 000000000000..433106b967a7
--- /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 000000000000..abb579132ed7
--- /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 000000000000..c8c67a055a22
--- /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 000000000000..992ddd0aded7
--- /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 000000000000..37e8995b6c46
--- /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 000000000000..bd4aa7e0171a
--- /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 000000000000..84bdb4c1b97a
--- /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 000000000000..05efc59f2107
--- /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 000000000000..113dbcb68d3e
--- /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 000000000000..54b6752e0c96
--- /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 000000000000..b5edbff46c47
--- /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 000000000000..8bcc2d73c2d1
--- /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