[BACK]Return to nlist_ecoff.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / gen

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>