Annotation of src/lib/libc/gen/nlist_ecoff.c, Revision 1.20
1.20 ! christos 1: /* $NetBSD: nlist_ecoff.c,v 1.19 2012/03/18 14:34:28 christos 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.20 ! christos 39: __RCSID("$NetBSD: nlist_ecoff.c,v 1.19 2012/03/18 14:34:28 christos 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>
1.18 he 53: #include <nlist.h>
1.1 cgd 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))
62:
63: int
64: __fdnlist_ecoff(fd, list)
1.6 perry 65: int fd;
66: struct nlist *list;
1.1 cgd 67: {
68: struct nlist *p;
69: struct ecoff_exechdr *exechdrp;
70: struct ecoff_symhdr *symhdrp;
71: struct ecoff_extsym *esyms;
72: struct stat st;
1.19 christos 73: void *mappedfile;
1.1 cgd 74: size_t mappedsize;
75: u_long symhdroff, extstroff;
76: u_int symhdrsize;
77: int rv, nent;
78: long i, nesyms;
1.9 lukem 79:
80: _DIAGASSERT(fd != -1);
81: _DIAGASSERT(list != NULL);
1.1 cgd 82:
1.3 cgd 83: rv = -1;
1.1 cgd 84:
1.3 cgd 85: /*
86: * If we can't fstat() the file, something bad is going on.
87: */
1.1 cgd 88: if (fstat(fd, &st) < 0)
1.19 christos 89: goto out;
1.3 cgd 90:
91: /*
92: * Map the file in its entirety.
93: */
1.17 lukem 94: if ((uintmax_t)st.st_size > (uintmax_t)SIZE_T_MAX) {
1.1 cgd 95: errno = EFBIG;
1.19 christos 96: goto out;
1.1 cgd 97: }
1.19 christos 98: mappedsize = (size_t)st.st_size;
1.8 thorpej 99: mappedfile = mmap(NULL, mappedsize, PROT_READ, MAP_PRIVATE|MAP_FILE,
1.5 mrg 100: fd, 0);
1.19 christos 101: if (mappedfile == MAP_FAILED)
102: goto out;
1.1 cgd 103:
1.3 cgd 104: /*
105: * Make sure we can access the executable's header
106: * directly, and make sure the recognize the executable
107: * as an ECOFF binary.
108: */
1.1 cgd 109: if (check(0, sizeof *exechdrp))
1.19 christos 110: goto unmap;
111: exechdrp = mappedfile;
1.1 cgd 112:
113: if (ECOFF_BADMAG(exechdrp))
1.19 christos 114: goto unmap;
1.1 cgd 115:
1.3 cgd 116: /*
117: * Find the symbol list.
118: */
1.1 cgd 119: symhdroff = exechdrp->f.f_symptr;
120: symhdrsize = exechdrp->f.f_nsyms;
121:
1.15 he 122: if ((symhdroff + sizeof *symhdrp) > mappedsize ||
1.1 cgd 123: sizeof *symhdrp != symhdrsize)
1.19 christos 124: goto unmap;
125: symhdrp = (void *)((char *)mappedfile + symhdroff);
1.1 cgd 126:
127: nesyms = symhdrp->esymMax;
128: if (check(symhdrp->cbExtOffset, nesyms * sizeof *esyms))
1.19 christos 129: goto unmap;
130: esyms = (void *)((char *)mappedfile + symhdrp->cbExtOffset);
1.1 cgd 131: extstroff = symhdrp->cbSsExtOffset;
132:
133: /*
1.3 cgd 134: * Clean out any left-over information for all valid entries.
135: * Type and value are defined to be 0 if not found; historical
1.1 cgd 136: * versions cleared other and desc as well.
137: *
1.3 cgd 138: * XXX Clearing anything other than n_type and n_value violates
1.1 cgd 139: * the semantics given in the man page.
140: */
141: nent = 0;
142: for (p = list; !ISLAST(p); ++p) {
143: p->n_type = 0;
144: p->n_other = 0;
145: p->n_desc = 0;
146: p->n_value = 0;
147: ++nent;
148: }
149:
150: for (i = 0; i < nesyms; i++) {
151: for (p = list; !ISLAST(p); p++) {
1.18 he 152: const char *nlistname;
1.1 cgd 153: char *symtabname;
154:
155: /* This may be incorrect */
1.18 he 156: nlistname = N_NAME(p);
1.1 cgd 157: if (*nlistname == '_')
158: nlistname++;
159:
1.20 ! christos 160: symtabname = (void *)((char *)
! 161: mappedfile + (extstroff + esyms[i].es_strindex));
1.1 cgd 162:
163: if (!strcmp(symtabname, nlistname)) {
1.3 cgd 164: /*
165: * Translate (roughly) from ECOFF to nlist
166: */
1.1 cgd 167: p->n_value = esyms[i].es_value;
168: p->n_type = N_EXT; /* XXX */
169: p->n_desc = 0; /* XXX */
170: p->n_other = 0; /* XXX */
1.3 cgd 171:
1.1 cgd 172: if (--nent <= 0)
1.3 cgd 173: goto done;
174: break; /* into next run of outer loop */
1.1 cgd 175: }
176: }
177: }
1.3 cgd 178:
179: done:
1.1 cgd 180: rv = nent;
181: unmap:
182: munmap(mappedfile, mappedsize);
183: out:
1.19 christos 184: return rv;
1.1 cgd 185: }
186:
187: #endif /* NLIST_ECOFF */
CVSweb <webmaster@jp.NetBSD.org>