1/*-
2 * Copyright (c) 2011 Joseph Koshy
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $Id: getdata.m4 2090 2011-10-27 08:07:39Z jkoshy $
27 */
28
29#include <libelf.h>
30#include <gelf.h>
31#include <string.h>
32#include <unistd.h>
33
34#include "elfts.h"
35#include "tet_api.h"
36
37include(`elfts.m4')
38
39IC_REQUIRES_VERSION_INIT();
40
41/*
42 * Find an ELF section with the given name.
43 */
44static Elf_Scn *
45findscn(Elf *e, const char *name)
46{
47	size_t shstrndx;
48	const char *scn_name;
49	Elf_Scn *scn;
50	GElf_Shdr shdr;
51
52	/* Locate the string table. */
53	if (elf_getshdrstrndx(e, &shstrndx) != 0)
54		return (NULL);
55
56	/* Find a section with a matching name. */
57	scn = NULL;
58	while ((scn = elf_nextscn(e, scn)) != NULL) {
59		if (gelf_getshdr(scn, &shdr) == NULL)
60			return (NULL);
61		if ((scn_name = elf_strptr(e, shstrndx,
62		    (size_t) shdr.sh_name)) == NULL)
63			return (NULL);
64		if (strcmp(scn_name, name) == 0)
65			return (scn);
66	}
67
68	return (NULL);
69}
70
71define(`ZEROSECTION',".zerosection")
72undefine(`FN')
73define(`FN',`
74void
75tcZeroSection$1$2(void)
76{
77	Elf *e;
78	int error, fd, result;
79	Elf_Scn *scn;
80	Elf_Data *ed;
81
82	e = NULL;
83	fd = -1;
84	result = TET_UNRESOLVED;
85
86	TP_ANNOUNCE("a data descriptor for a zero sized section is correctly retrieved");
87
88	_TS_OPEN_FILE(e, "zerosection.$1$2", ELF_C_READ, fd, goto done;);
89
90	if ((scn = findscn(e, ZEROSECTION)) == NULL) {
91		TP_UNRESOLVED("Cannot find section \""ZEROSECTION"\"");
92		goto done;
93	}
94
95	ed = NULL;
96	if ((ed = elf_getdata(scn, ed)) == NULL) {
97		error = elf_errno();
98		TP_FAIL("elf_getdata failed %d \"%s\"", error,
99		    elf_errmsg(error));
100		goto done;
101	}
102
103	if (ed->d_size != 0 || ed->d_buf != NULL) {
104		TP_FAIL("Illegal values returned: size %d buf %p",
105		    (int) ed->d_size, (void *) ed->d_buf);
106		goto done;
107	}
108
109	result = TET_PASS;
110
111done:
112	if (e)
113		elf_end(e);
114	if (fd != -1)
115		(void) close(fd);
116	tet_result(result);
117}
118')
119
120FN(lsb,32)
121FN(lsb,64)
122FN(msb,32)
123FN(msb,64)
124
125/*
126 * Verify that a non-zero section is correctly read.
127 */
128
129static const char stringsection[] = {
130changequote({,})
131       '\0',
132       '.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', '\0',
133       '.', 'z', 'e', 'r', 'o', 's', 'e', 'c', 't', 'i', 'o', 'n', '\0'
134changequote
135       };
136
137undefine(`_FN')
138define(`_FN',`
139void
140tcNonZeroSection$1$2(void)
141{
142	Elf *e;
143	int error, fd, result;
144	const size_t strsectionsize = sizeof stringsection;
145	size_t n, shstrndx;
146	const char *buf;
147	Elf_Scn *scn;
148	Elf_Data *ed;
149
150	e = NULL;
151	fd = -1;
152	result = TET_UNRESOLVED;
153
154	TP_ANNOUNCE("a data descriptor for a non-zero sized section "
155	    "is correctly retrieved");
156
157	_TS_OPEN_FILE(e, "zerosection.$1$2", ELF_C_READ, fd, goto done;);
158
159	if (elf_getshdrstrndx(e, &shstrndx) != 0 ||
160	    (scn = elf_getscn(e, shstrndx)) == NULL) {
161		TP_UNRESOLVED("Cannot find string table section");
162		goto done;
163	}
164
165	ed = NULL;
166	if ((ed = elf_getdata(scn, ed)) == NULL) {
167		error = elf_errno();
168		TP_FAIL("elf_getdata failed %d \"%s\"", error,
169		    elf_errmsg(error));
170		goto done;
171	}
172
173	if (ed->d_size != strsectionsize) {
174		TP_FAIL("Illegal values returned: d_size %d != expected %d",
175		    (int) ed->d_size, strsectionsize);
176		goto done;
177	}
178
179	if (memcmp(stringsection, ed->d_buf, strsectionsize) != 0) {
180		buf = (const char *) ed->d_buf;
181		for (n = 0; n < strsectionsize; n++)
182			if (buf[n] != stringsection[n])
183				break;
184		TP_FAIL("String mismatch: buf[%d] \"%c\" != \"%c\"",
185		    n, buf[n], stringsection[n]);
186		goto done;
187	}
188
189	result = TET_PASS;
190
191done:
192	if (e)
193		elf_end(e);
194	if (fd != -1)
195		(void) close(fd);
196	tet_result(result);
197}
198')
199
200_FN(lsb,32)
201_FN(lsb,64)
202_FN(msb,32)
203_FN(msb,64)
204