xref: /freebsd-src/cddl/contrib/opensolaris/tools/ctf/cvt/input.c (revision 1673e4046da975ab0e2bf67d45499930ebab0dbe)
1*1673e404SJohn Birrell /*
2*1673e404SJohn Birrell  * CDDL HEADER START
3*1673e404SJohn Birrell  *
4*1673e404SJohn Birrell  * The contents of this file are subject to the terms of the
5*1673e404SJohn Birrell  * Common Development and Distribution License (the "License").
6*1673e404SJohn Birrell  * You may not use this file except in compliance with the License.
7*1673e404SJohn Birrell  *
8*1673e404SJohn Birrell  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*1673e404SJohn Birrell  * or http://www.opensolaris.org/os/licensing.
10*1673e404SJohn Birrell  * See the License for the specific language governing permissions
11*1673e404SJohn Birrell  * and limitations under the License.
12*1673e404SJohn Birrell  *
13*1673e404SJohn Birrell  * When distributing Covered Code, include this CDDL HEADER in each
14*1673e404SJohn Birrell  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*1673e404SJohn Birrell  * If applicable, add the following below this CDDL HEADER, with the
16*1673e404SJohn Birrell  * fields enclosed by brackets "[]" replaced with your own identifying
17*1673e404SJohn Birrell  * information: Portions Copyright [yyyy] [name of copyright owner]
18*1673e404SJohn Birrell  *
19*1673e404SJohn Birrell  * CDDL HEADER END
20*1673e404SJohn Birrell  */
21*1673e404SJohn Birrell /*
22*1673e404SJohn Birrell  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23*1673e404SJohn Birrell  * Use is subject to license terms.
24*1673e404SJohn Birrell  */
25*1673e404SJohn Birrell 
26*1673e404SJohn Birrell #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*1673e404SJohn Birrell 
28*1673e404SJohn Birrell /*
29*1673e404SJohn Birrell  * Routines for retrieving CTF data from a .SUNW_ctf ELF section
30*1673e404SJohn Birrell  */
31*1673e404SJohn Birrell 
32*1673e404SJohn Birrell #include <stdio.h>
33*1673e404SJohn Birrell #include <stdlib.h>
34*1673e404SJohn Birrell #include <fcntl.h>
35*1673e404SJohn Birrell #include <unistd.h>
36*1673e404SJohn Birrell #include <gelf.h>
37*1673e404SJohn Birrell #include <strings.h>
38*1673e404SJohn Birrell #include <sys/types.h>
39*1673e404SJohn Birrell 
40*1673e404SJohn Birrell #include "ctftools.h"
41*1673e404SJohn Birrell #include "memory.h"
42*1673e404SJohn Birrell #include "symbol.h"
43*1673e404SJohn Birrell 
44*1673e404SJohn Birrell typedef int read_cb_f(tdata_t *, char *, void *);
45*1673e404SJohn Birrell 
46*1673e404SJohn Birrell /*
47*1673e404SJohn Birrell  * Return the source types that the object was generated from.
48*1673e404SJohn Birrell  */
49*1673e404SJohn Birrell source_types_t
50*1673e404SJohn Birrell built_source_types(Elf *elf, char const *file)
51*1673e404SJohn Birrell {
52*1673e404SJohn Birrell 	source_types_t types = SOURCE_NONE;
53*1673e404SJohn Birrell 	symit_data_t *si;
54*1673e404SJohn Birrell 
55*1673e404SJohn Birrell 	if ((si = symit_new(elf, file)) == NULL)
56*1673e404SJohn Birrell 		return (SOURCE_NONE);
57*1673e404SJohn Birrell 
58*1673e404SJohn Birrell 	while (symit_next(si, STT_FILE) != NULL) {
59*1673e404SJohn Birrell 		char *name = symit_name(si);
60*1673e404SJohn Birrell 		size_t len = strlen(name);
61*1673e404SJohn Birrell 		if (len < 2 || name[len - 2] != '.') {
62*1673e404SJohn Birrell 			types |= SOURCE_UNKNOWN;
63*1673e404SJohn Birrell 			continue;
64*1673e404SJohn Birrell 		}
65*1673e404SJohn Birrell 
66*1673e404SJohn Birrell 		switch (name[len - 1]) {
67*1673e404SJohn Birrell 		case 'c':
68*1673e404SJohn Birrell 			types |= SOURCE_C;
69*1673e404SJohn Birrell 			break;
70*1673e404SJohn Birrell 		case 'h':
71*1673e404SJohn Birrell 			/* ignore */
72*1673e404SJohn Birrell 			break;
73*1673e404SJohn Birrell 		case 's':
74*1673e404SJohn Birrell 		case 'S':
75*1673e404SJohn Birrell 			types |= SOURCE_S;
76*1673e404SJohn Birrell 			break;
77*1673e404SJohn Birrell 		default:
78*1673e404SJohn Birrell 			types |= SOURCE_UNKNOWN;
79*1673e404SJohn Birrell 		}
80*1673e404SJohn Birrell 	}
81*1673e404SJohn Birrell 
82*1673e404SJohn Birrell 	symit_free(si);
83*1673e404SJohn Birrell 	return (types);
84*1673e404SJohn Birrell }
85*1673e404SJohn Birrell 
86*1673e404SJohn Birrell static int
87*1673e404SJohn Birrell read_file(Elf *elf, char *file, char *label, read_cb_f *func, void *arg,
88*1673e404SJohn Birrell     int require_ctf)
89*1673e404SJohn Birrell {
90*1673e404SJohn Birrell 	Elf_Scn *ctfscn;
91*1673e404SJohn Birrell 	Elf_Data *ctfdata = NULL;
92*1673e404SJohn Birrell 	symit_data_t *si = NULL;
93*1673e404SJohn Birrell 	int ctfscnidx;
94*1673e404SJohn Birrell 	tdata_t *td;
95*1673e404SJohn Birrell 
96*1673e404SJohn Birrell 	if ((ctfscnidx = findelfsecidx(elf, file, ".SUNW_ctf")) < 0) {
97*1673e404SJohn Birrell 		if (require_ctf &&
98*1673e404SJohn Birrell 		    (built_source_types(elf, file) & SOURCE_C)) {
99*1673e404SJohn Birrell 			terminate("Input file %s was partially built from "
100*1673e404SJohn Birrell 			    "C sources, but no CTF data was present\n", file);
101*1673e404SJohn Birrell 		}
102*1673e404SJohn Birrell 		return (0);
103*1673e404SJohn Birrell 	}
104*1673e404SJohn Birrell 
105*1673e404SJohn Birrell 	if ((ctfscn = elf_getscn(elf, ctfscnidx)) == NULL ||
106*1673e404SJohn Birrell 	    (ctfdata = elf_getdata(ctfscn, NULL)) == NULL)
107*1673e404SJohn Birrell 		elfterminate(file, "Cannot read CTF section");
108*1673e404SJohn Birrell 
109*1673e404SJohn Birrell 	/* Reconstruction of type tree */
110*1673e404SJohn Birrell 	if ((si = symit_new(elf, file)) == NULL) {
111*1673e404SJohn Birrell 		warning("%s has no symbol table - skipping", file);
112*1673e404SJohn Birrell 		return (0);
113*1673e404SJohn Birrell 	}
114*1673e404SJohn Birrell 
115*1673e404SJohn Birrell 	td = ctf_load(file, ctfdata->d_buf, ctfdata->d_size, si, label);
116*1673e404SJohn Birrell 	tdata_build_hashes(td);
117*1673e404SJohn Birrell 
118*1673e404SJohn Birrell 	symit_free(si);
119*1673e404SJohn Birrell 
120*1673e404SJohn Birrell 	if (td != NULL) {
121*1673e404SJohn Birrell 		if (func(td, file, arg) < 0)
122*1673e404SJohn Birrell 			return (-1);
123*1673e404SJohn Birrell 		else
124*1673e404SJohn Birrell 			return (1);
125*1673e404SJohn Birrell 	}
126*1673e404SJohn Birrell 	return (0);
127*1673e404SJohn Birrell }
128*1673e404SJohn Birrell 
129*1673e404SJohn Birrell static int
130*1673e404SJohn Birrell read_archive(int fd, Elf *elf, char *file, char *label, read_cb_f *func,
131*1673e404SJohn Birrell     void *arg, int require_ctf)
132*1673e404SJohn Birrell {
133*1673e404SJohn Birrell 	Elf *melf;
134*1673e404SJohn Birrell 	Elf_Cmd cmd = ELF_C_READ;
135*1673e404SJohn Birrell 	Elf_Arhdr *arh;
136*1673e404SJohn Birrell 	int secnum = 1, found = 0;
137*1673e404SJohn Birrell 
138*1673e404SJohn Birrell 	while ((melf = elf_begin(fd, cmd, elf)) != NULL) {
139*1673e404SJohn Birrell 		int rc = 0;
140*1673e404SJohn Birrell 
141*1673e404SJohn Birrell 		if ((arh = elf_getarhdr(melf)) == NULL) {
142*1673e404SJohn Birrell 			elfterminate(file, "Can't get archive header for "
143*1673e404SJohn Birrell 			    "member %d", secnum);
144*1673e404SJohn Birrell 		}
145*1673e404SJohn Birrell 
146*1673e404SJohn Birrell 		/* skip special sections - their names begin with "/" */
147*1673e404SJohn Birrell 		if (*arh->ar_name != '/') {
148*1673e404SJohn Birrell 			size_t memlen = strlen(file) + 1 +
149*1673e404SJohn Birrell 			    strlen(arh->ar_name) + 1 + 1;
150*1673e404SJohn Birrell 			char *memname = xmalloc(memlen);
151*1673e404SJohn Birrell 
152*1673e404SJohn Birrell 			snprintf(memname, memlen, "%s(%s)", file, arh->ar_name);
153*1673e404SJohn Birrell 
154*1673e404SJohn Birrell 			switch (elf_kind(melf)) {
155*1673e404SJohn Birrell 			case ELF_K_AR:
156*1673e404SJohn Birrell 				rc = read_archive(fd, melf, memname, label,
157*1673e404SJohn Birrell 				    func, arg, require_ctf);
158*1673e404SJohn Birrell 				break;
159*1673e404SJohn Birrell 			case ELF_K_ELF:
160*1673e404SJohn Birrell 				rc = read_file(melf, memname, label,
161*1673e404SJohn Birrell 				    func, arg, require_ctf);
162*1673e404SJohn Birrell 				break;
163*1673e404SJohn Birrell 			default:
164*1673e404SJohn Birrell 				terminate("%s: Unknown elf kind %d\n",
165*1673e404SJohn Birrell 				    memname, elf_kind(melf));
166*1673e404SJohn Birrell 			}
167*1673e404SJohn Birrell 
168*1673e404SJohn Birrell 			free(memname);
169*1673e404SJohn Birrell 		}
170*1673e404SJohn Birrell 
171*1673e404SJohn Birrell 		cmd = elf_next(melf);
172*1673e404SJohn Birrell 		(void) elf_end(melf);
173*1673e404SJohn Birrell 		secnum++;
174*1673e404SJohn Birrell 
175*1673e404SJohn Birrell 		if (rc < 0)
176*1673e404SJohn Birrell 			return (rc);
177*1673e404SJohn Birrell 		else
178*1673e404SJohn Birrell 			found += rc;
179*1673e404SJohn Birrell 	}
180*1673e404SJohn Birrell 
181*1673e404SJohn Birrell 	return (found);
182*1673e404SJohn Birrell }
183*1673e404SJohn Birrell 
184*1673e404SJohn Birrell static int
185*1673e404SJohn Birrell read_ctf_common(char *file, char *label, read_cb_f *func, void *arg,
186*1673e404SJohn Birrell     int require_ctf)
187*1673e404SJohn Birrell {
188*1673e404SJohn Birrell 	Elf *elf;
189*1673e404SJohn Birrell 	int found = 0;
190*1673e404SJohn Birrell 	int fd;
191*1673e404SJohn Birrell 
192*1673e404SJohn Birrell 	debug(3, "Reading %s (label %s)\n", file, (label ? label : "NONE"));
193*1673e404SJohn Birrell 
194*1673e404SJohn Birrell 	(void) elf_version(EV_CURRENT);
195*1673e404SJohn Birrell 
196*1673e404SJohn Birrell 	if ((fd = open(file, O_RDONLY)) < 0)
197*1673e404SJohn Birrell 		terminate("%s: Cannot open for reading", file);
198*1673e404SJohn Birrell 	if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
199*1673e404SJohn Birrell 		elfterminate(file, "Cannot read");
200*1673e404SJohn Birrell 
201*1673e404SJohn Birrell 	switch (elf_kind(elf)) {
202*1673e404SJohn Birrell 	case ELF_K_AR:
203*1673e404SJohn Birrell 		found = read_archive(fd, elf, file, label,
204*1673e404SJohn Birrell 		    func, arg, require_ctf);
205*1673e404SJohn Birrell 		break;
206*1673e404SJohn Birrell 
207*1673e404SJohn Birrell 	case ELF_K_ELF:
208*1673e404SJohn Birrell 		found = read_file(elf, file, label,
209*1673e404SJohn Birrell 		    func, arg, require_ctf);
210*1673e404SJohn Birrell 		break;
211*1673e404SJohn Birrell 
212*1673e404SJohn Birrell 	default:
213*1673e404SJohn Birrell 		terminate("%s: Unknown elf kind %d\n", file, elf_kind(elf));
214*1673e404SJohn Birrell 	}
215*1673e404SJohn Birrell 
216*1673e404SJohn Birrell 	(void) elf_end(elf);
217*1673e404SJohn Birrell 	(void) close(fd);
218*1673e404SJohn Birrell 
219*1673e404SJohn Birrell 	return (found);
220*1673e404SJohn Birrell }
221*1673e404SJohn Birrell 
222*1673e404SJohn Birrell /*ARGSUSED*/
223*1673e404SJohn Birrell int
224*1673e404SJohn Birrell read_ctf_save_cb(tdata_t *td, char *name __unused, void *retp)
225*1673e404SJohn Birrell {
226*1673e404SJohn Birrell 	tdata_t **tdp = retp;
227*1673e404SJohn Birrell 
228*1673e404SJohn Birrell 	*tdp = td;
229*1673e404SJohn Birrell 
230*1673e404SJohn Birrell 	return (1);
231*1673e404SJohn Birrell }
232*1673e404SJohn Birrell 
233*1673e404SJohn Birrell int
234*1673e404SJohn Birrell read_ctf(char **files, int n, char *label, read_cb_f *func, void *private,
235*1673e404SJohn Birrell     int require_ctf)
236*1673e404SJohn Birrell {
237*1673e404SJohn Birrell 	int found;
238*1673e404SJohn Birrell 	int i, rc;
239*1673e404SJohn Birrell 
240*1673e404SJohn Birrell 	for (i = 0, found = 0; i < n; i++) {
241*1673e404SJohn Birrell 		if ((rc = read_ctf_common(files[i], label, func,
242*1673e404SJohn Birrell 		    private, require_ctf)) < 0)
243*1673e404SJohn Birrell 			return (rc);
244*1673e404SJohn Birrell 		found += rc;
245*1673e404SJohn Birrell 	}
246*1673e404SJohn Birrell 
247*1673e404SJohn Birrell 	return (found);
248*1673e404SJohn Birrell }
249*1673e404SJohn Birrell 
250*1673e404SJohn Birrell static int
251*1673e404SJohn Birrell count_archive(int fd, Elf *elf, char *file)
252*1673e404SJohn Birrell {
253*1673e404SJohn Birrell 	Elf *melf;
254*1673e404SJohn Birrell 	Elf_Cmd cmd = ELF_C_READ;
255*1673e404SJohn Birrell 	Elf_Arhdr *arh;
256*1673e404SJohn Birrell 	int nfiles = 0, err = 0;
257*1673e404SJohn Birrell 
258*1673e404SJohn Birrell 	while ((melf = elf_begin(fd, cmd, elf)) != NULL) {
259*1673e404SJohn Birrell 		if ((arh = elf_getarhdr(melf)) == NULL) {
260*1673e404SJohn Birrell 			warning("Can't process input archive %s\n",
261*1673e404SJohn Birrell 			    file);
262*1673e404SJohn Birrell 			err++;
263*1673e404SJohn Birrell 		}
264*1673e404SJohn Birrell 
265*1673e404SJohn Birrell 		if (*arh->ar_name != '/')
266*1673e404SJohn Birrell 			nfiles++;
267*1673e404SJohn Birrell 
268*1673e404SJohn Birrell 		cmd = elf_next(melf);
269*1673e404SJohn Birrell 		(void) elf_end(melf);
270*1673e404SJohn Birrell 	}
271*1673e404SJohn Birrell 
272*1673e404SJohn Birrell 	if (err > 0)
273*1673e404SJohn Birrell 		return (-1);
274*1673e404SJohn Birrell 
275*1673e404SJohn Birrell 	return (nfiles);
276*1673e404SJohn Birrell }
277*1673e404SJohn Birrell 
278*1673e404SJohn Birrell int
279*1673e404SJohn Birrell count_files(char **files, int n)
280*1673e404SJohn Birrell {
281*1673e404SJohn Birrell 	int nfiles = 0, err = 0;
282*1673e404SJohn Birrell 	Elf *elf;
283*1673e404SJohn Birrell 	int fd, rc, i;
284*1673e404SJohn Birrell 
285*1673e404SJohn Birrell 	(void) elf_version(EV_CURRENT);
286*1673e404SJohn Birrell 
287*1673e404SJohn Birrell 	for (i = 0; i < n; i++) {
288*1673e404SJohn Birrell 		char *file = files[i];
289*1673e404SJohn Birrell 
290*1673e404SJohn Birrell 		if ((fd = open(file, O_RDONLY)) < 0) {
291*1673e404SJohn Birrell 			warning("Can't read input file %s", file);
292*1673e404SJohn Birrell 			err++;
293*1673e404SJohn Birrell 			continue;
294*1673e404SJohn Birrell 		}
295*1673e404SJohn Birrell 
296*1673e404SJohn Birrell 		if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
297*1673e404SJohn Birrell 			warning("Can't open input file %s: %s\n", file,
298*1673e404SJohn Birrell 			    elf_errmsg(-1));
299*1673e404SJohn Birrell 			err++;
300*1673e404SJohn Birrell 			(void) close(fd);
301*1673e404SJohn Birrell 			continue;
302*1673e404SJohn Birrell 		}
303*1673e404SJohn Birrell 
304*1673e404SJohn Birrell 		switch (elf_kind(elf)) {
305*1673e404SJohn Birrell 		case ELF_K_AR:
306*1673e404SJohn Birrell 			if ((rc = count_archive(fd, elf, file)) < 0)
307*1673e404SJohn Birrell 				err++;
308*1673e404SJohn Birrell 			else
309*1673e404SJohn Birrell 				nfiles += rc;
310*1673e404SJohn Birrell 			break;
311*1673e404SJohn Birrell 		case ELF_K_ELF:
312*1673e404SJohn Birrell 			nfiles++;
313*1673e404SJohn Birrell 			break;
314*1673e404SJohn Birrell 		default:
315*1673e404SJohn Birrell 			warning("Input file %s is corrupt\n", file);
316*1673e404SJohn Birrell 			err++;
317*1673e404SJohn Birrell 		}
318*1673e404SJohn Birrell 
319*1673e404SJohn Birrell 		(void) elf_end(elf);
320*1673e404SJohn Birrell 		(void) close(fd);
321*1673e404SJohn Birrell 	}
322*1673e404SJohn Birrell 
323*1673e404SJohn Birrell 	if (err > 0)
324*1673e404SJohn Birrell 		return (-1);
325*1673e404SJohn Birrell 
326*1673e404SJohn Birrell 	debug(2, "Found %d files in %d input files\n", nfiles, n);
327*1673e404SJohn Birrell 
328*1673e404SJohn Birrell 	return (nfiles);
329*1673e404SJohn Birrell }
330*1673e404SJohn Birrell 
331*1673e404SJohn Birrell struct symit_data {
332*1673e404SJohn Birrell 	GElf_Shdr si_shdr;
333*1673e404SJohn Birrell 	Elf_Data *si_symd;
334*1673e404SJohn Birrell 	Elf_Data *si_strd;
335*1673e404SJohn Birrell 	GElf_Sym si_cursym;
336*1673e404SJohn Birrell 	char *si_curname;
337*1673e404SJohn Birrell 	char *si_curfile;
338*1673e404SJohn Birrell 	int si_nument;
339*1673e404SJohn Birrell 	int si_next;
340*1673e404SJohn Birrell };
341*1673e404SJohn Birrell 
342*1673e404SJohn Birrell symit_data_t *
343*1673e404SJohn Birrell symit_new(Elf *elf, const char *file)
344*1673e404SJohn Birrell {
345*1673e404SJohn Birrell 	symit_data_t *si;
346*1673e404SJohn Birrell 	Elf_Scn *scn;
347*1673e404SJohn Birrell 	int symtabidx;
348*1673e404SJohn Birrell 
349*1673e404SJohn Birrell 	if ((symtabidx = findelfsecidx(elf, file, ".symtab")) < 0)
350*1673e404SJohn Birrell 		return (NULL);
351*1673e404SJohn Birrell 
352*1673e404SJohn Birrell 	si = xcalloc(sizeof (symit_data_t));
353*1673e404SJohn Birrell 
354*1673e404SJohn Birrell 	if ((scn = elf_getscn(elf, symtabidx)) == NULL ||
355*1673e404SJohn Birrell 	    gelf_getshdr(scn, &si->si_shdr) == NULL ||
356*1673e404SJohn Birrell 	    (si->si_symd = elf_getdata(scn, NULL)) == NULL)
357*1673e404SJohn Birrell 		elfterminate(file, "Cannot read .symtab");
358*1673e404SJohn Birrell 
359*1673e404SJohn Birrell 	if ((scn = elf_getscn(elf, si->si_shdr.sh_link)) == NULL ||
360*1673e404SJohn Birrell 	    (si->si_strd = elf_getdata(scn, NULL)) == NULL)
361*1673e404SJohn Birrell 		elfterminate(file, "Cannot read strings for .symtab");
362*1673e404SJohn Birrell 
363*1673e404SJohn Birrell 	si->si_nument = si->si_shdr.sh_size / si->si_shdr.sh_entsize;
364*1673e404SJohn Birrell 
365*1673e404SJohn Birrell 	return (si);
366*1673e404SJohn Birrell }
367*1673e404SJohn Birrell 
368*1673e404SJohn Birrell void
369*1673e404SJohn Birrell symit_free(symit_data_t *si)
370*1673e404SJohn Birrell {
371*1673e404SJohn Birrell 	free(si);
372*1673e404SJohn Birrell }
373*1673e404SJohn Birrell 
374*1673e404SJohn Birrell void
375*1673e404SJohn Birrell symit_reset(symit_data_t *si)
376*1673e404SJohn Birrell {
377*1673e404SJohn Birrell 	si->si_next = 0;
378*1673e404SJohn Birrell }
379*1673e404SJohn Birrell 
380*1673e404SJohn Birrell char *
381*1673e404SJohn Birrell symit_curfile(symit_data_t *si)
382*1673e404SJohn Birrell {
383*1673e404SJohn Birrell 	return (si->si_curfile);
384*1673e404SJohn Birrell }
385*1673e404SJohn Birrell 
386*1673e404SJohn Birrell GElf_Sym *
387*1673e404SJohn Birrell symit_next(symit_data_t *si, int type)
388*1673e404SJohn Birrell {
389*1673e404SJohn Birrell 	GElf_Sym sym;
390*1673e404SJohn Birrell 	int check_sym = (type == STT_OBJECT || type == STT_FUNC);
391*1673e404SJohn Birrell 
392*1673e404SJohn Birrell 	for (; si->si_next < si->si_nument; si->si_next++) {
393*1673e404SJohn Birrell 		gelf_getsym(si->si_symd, si->si_next, &si->si_cursym);
394*1673e404SJohn Birrell 		gelf_getsym(si->si_symd, si->si_next, &sym);
395*1673e404SJohn Birrell 		si->si_curname = (caddr_t)si->si_strd->d_buf + sym.st_name;
396*1673e404SJohn Birrell 
397*1673e404SJohn Birrell 		if (GELF_ST_TYPE(sym.st_info) == STT_FILE)
398*1673e404SJohn Birrell 			si->si_curfile = si->si_curname;
399*1673e404SJohn Birrell 
400*1673e404SJohn Birrell 		if (GELF_ST_TYPE(sym.st_info) != type ||
401*1673e404SJohn Birrell 		    sym.st_shndx == SHN_UNDEF)
402*1673e404SJohn Birrell 			continue;
403*1673e404SJohn Birrell 
404*1673e404SJohn Birrell 		if (check_sym && ignore_symbol(&sym, si->si_curname))
405*1673e404SJohn Birrell 			continue;
406*1673e404SJohn Birrell 
407*1673e404SJohn Birrell 		si->si_next++;
408*1673e404SJohn Birrell 
409*1673e404SJohn Birrell 		return (&si->si_cursym);
410*1673e404SJohn Birrell 	}
411*1673e404SJohn Birrell 
412*1673e404SJohn Birrell 	return (NULL);
413*1673e404SJohn Birrell }
414*1673e404SJohn Birrell 
415*1673e404SJohn Birrell char *
416*1673e404SJohn Birrell symit_name(symit_data_t *si)
417*1673e404SJohn Birrell {
418*1673e404SJohn Birrell 	return (si->si_curname);
419*1673e404SJohn Birrell }
420