Annotation of src/lib/libc/gen/nlist_ecoff.c, Revision 1.15
1.15 ! he 1: /* $NetBSD: nlist_ecoff.c,v 1.14 2003/07/26 19:24:43 salo Exp $ */
1.1 cgd 2:
3: /*
1.13 cgd 4: * Copyright (c) 1996 Christopher G. Demetriou
5: * All rights reserved.
6: *
1.1 cgd 7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
1.13 cgd 17: * This product includes software developed for the
1.14 salo 18: * NetBSD Project. See http://www.NetBSD.org/ for
1.13 cgd 19: * information about NetBSD.
1.3 cgd 20: * 4. The name of the author may not be used to endorse or promote products
1.13 cgd 21: * derived from this software without specific prior written permission.
22: *
1.3 cgd 23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.13 cgd 33: *
34: * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
1.1 cgd 35: */
36:
1.4 christos 37: #include <sys/cdefs.h>
1.1 cgd 38: #if defined(LIBC_SCCS) && !defined(lint)
1.15 ! he 39: __RCSID("$NetBSD: nlist_ecoff.c,v 1.14 2003/07/26 19:24:43 salo Exp $");
1.1 cgd 40: #endif /* LIBC_SCCS and not lint */
41:
1.7 kleink 42: #include "namespace.h"
1.1 cgd 43: #include <sys/param.h>
44: #include <sys/mman.h>
45: #include <sys/stat.h>
46: #include <sys/file.h>
47:
1.9 lukem 48: #include <assert.h>
1.1 cgd 49: #include <errno.h>
50: #include <stdio.h>
51: #include <string.h>
52: #include <unistd.h>
53: #include <a.out.h> /* for 'struct nlist' declaration */
54:
55: #include "nlist_private.h"
56: #ifdef NLIST_ECOFF
57: #include <sys/exec_ecoff.h>
58: #endif
59:
60: #ifdef NLIST_ECOFF
61: #define check(off, size) ((off < 0) || (off + size > mappedsize))
1.11 simonb 62: #define BAD do { rv = -1; goto out; } while (/*CONSTCOND*/0)
63: #define BADUNMAP do { rv = -1; goto unmap; } while (/*CONSTCOND*/0)
1.1 cgd 64:
65: int
66: __fdnlist_ecoff(fd, list)
1.6 perry 67: int fd;
68: struct nlist *list;
1.1 cgd 69: {
70: struct nlist *p;
71: struct ecoff_exechdr *exechdrp;
72: struct ecoff_symhdr *symhdrp;
73: struct ecoff_extsym *esyms;
74: struct stat st;
75: char *mappedfile;
76: size_t mappedsize;
77: u_long symhdroff, extstroff;
78: u_int symhdrsize;
79: int rv, nent;
80: long i, nesyms;
1.9 lukem 81:
82: _DIAGASSERT(fd != -1);
83: _DIAGASSERT(list != NULL);
1.1 cgd 84:
1.3 cgd 85: rv = -1;
1.1 cgd 86:
1.3 cgd 87: /*
88: * If we can't fstat() the file, something bad is going on.
89: */
1.1 cgd 90: if (fstat(fd, &st) < 0)
91: BAD;
1.3 cgd 92:
93: /*
94: * Map the file in its entirety.
95: */
1.1 cgd 96: if (st.st_size > SIZE_T_MAX) {
97: errno = EFBIG;
98: BAD;
99: }
100: mappedsize = st.st_size;
1.8 thorpej 101: mappedfile = mmap(NULL, mappedsize, PROT_READ, MAP_PRIVATE|MAP_FILE,
1.5 mrg 102: fd, 0);
1.1 cgd 103: if (mappedfile == (char *)-1)
104: BAD;
105:
1.3 cgd 106: /*
107: * Make sure we can access the executable's header
108: * directly, and make sure the recognize the executable
109: * as an ECOFF binary.
110: */
1.1 cgd 111: if (check(0, sizeof *exechdrp))
112: BADUNMAP;
113: exechdrp = (struct ecoff_exechdr *)&mappedfile[0];
114:
115: if (ECOFF_BADMAG(exechdrp))
116: BADUNMAP;
117:
1.3 cgd 118: /*
119: * Find the symbol list.
120: */
1.1 cgd 121: symhdroff = exechdrp->f.f_symptr;
122: symhdrsize = exechdrp->f.f_nsyms;
123:
1.15 ! he 124: if ((symhdroff + sizeof *symhdrp) > mappedsize ||
1.1 cgd 125: sizeof *symhdrp != symhdrsize)
126: BADUNMAP;
127: symhdrp = (struct ecoff_symhdr *)&mappedfile[symhdroff];
128:
129: nesyms = symhdrp->esymMax;
130: if (check(symhdrp->cbExtOffset, nesyms * sizeof *esyms))
131: BADUNMAP;
132: esyms = (struct ecoff_extsym *)&mappedfile[symhdrp->cbExtOffset];
133: extstroff = symhdrp->cbSsExtOffset;
134:
135: /*
1.3 cgd 136: * Clean out any left-over information for all valid entries.
137: * Type and value are defined to be 0 if not found; historical
1.1 cgd 138: * versions cleared other and desc as well.
139: *
1.3 cgd 140: * XXX Clearing anything other than n_type and n_value violates
1.1 cgd 141: * the semantics given in the man page.
142: */
143: nent = 0;
144: for (p = list; !ISLAST(p); ++p) {
145: p->n_type = 0;
146: p->n_other = 0;
147: p->n_desc = 0;
148: p->n_value = 0;
149: ++nent;
150: }
151:
152: for (i = 0; i < nesyms; i++) {
153: for (p = list; !ISLAST(p); p++) {
154: char *nlistname;
155: char *symtabname;
156:
157: /* This may be incorrect */
158: nlistname = p->n_un.n_name;
159: if (*nlistname == '_')
160: nlistname++;
161:
162: symtabname =
163: &mappedfile[extstroff + esyms[i].es_strindex];
164:
165: if (!strcmp(symtabname, nlistname)) {
1.3 cgd 166: /*
167: * Translate (roughly) from ECOFF to nlist
168: */
1.1 cgd 169: p->n_value = esyms[i].es_value;
170: p->n_type = N_EXT; /* XXX */
171: p->n_desc = 0; /* XXX */
172: p->n_other = 0; /* XXX */
1.3 cgd 173:
1.1 cgd 174: if (--nent <= 0)
1.3 cgd 175: goto done;
176: break; /* into next run of outer loop */
1.1 cgd 177: }
178: }
179: }
1.3 cgd 180:
181: done:
1.1 cgd 182: rv = nent;
183: unmap:
184: munmap(mappedfile, mappedsize);
185: out:
186: return (rv);
187: }
188:
189: #endif /* NLIST_ECOFF */
CVSweb <webmaster@jp.NetBSD.org>