[BACK]Return to loadfile_elf.c CVS log [TXT][DIR] Up to [local] / sys / lib / libsa

Annotation of sys/lib/libsa/loadfile_elf.c, Revision 1.1

1.1     ! nbrk        1: /* $NetBSD: loadfile.c,v 1.10 2000/12/03 02:53:04 tsutsui Exp $ */
        !             2: /* $OpenBSD: loadfile_elf.c,v 1.1 2007/05/30 01:25:43 tom Exp $ */
        !             3:
        !             4: /*-
        !             5:  * Copyright (c) 1997 The NetBSD Foundation, Inc.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * This code is derived from software contributed to The NetBSD Foundation
        !             9:  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
        !            10:  * NASA Ames Research Center and by Christos Zoulas.
        !            11:  *
        !            12:  * Redistribution and use in source and binary forms, with or without
        !            13:  * modification, are permitted provided that the following conditions
        !            14:  * are met:
        !            15:  * 1. Redistributions of source code must retain the above copyright
        !            16:  *    notice, this list of conditions and the following disclaimer.
        !            17:  * 2. Redistributions in binary form must reproduce the above copyright
        !            18:  *    notice, this list of conditions and the following disclaimer in the
        !            19:  *    documentation and/or other materials provided with the distribution.
        !            20:  * 3. All advertising materials mentioning features or use of this software
        !            21:  *    must display the following acknowledgement:
        !            22:  *     This product includes software developed by the NetBSD
        !            23:  *     Foundation, Inc. and its contributors.
        !            24:  * 4. Neither the name of The NetBSD Foundation nor the names of its
        !            25:  *    contributors may be used to endorse or promote products derived
        !            26:  *    from this software without specific prior written permission.
        !            27:  *
        !            28:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
        !            29:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            30:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            31:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            32:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            33:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            34:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            35:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            36:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            37:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            38:  * POSSIBILITY OF SUCH DAMAGE.
        !            39:  */
        !            40:
        !            41: /*
        !            42:  * Copyright (c) 1992, 1993
        !            43:  *     The Regents of the University of California.  All rights reserved.
        !            44:  *
        !            45:  * This code is derived from software contributed to Berkeley by
        !            46:  * Ralph Campbell.
        !            47:  *
        !            48:  * Redistribution and use in source and binary forms, with or without
        !            49:  * modification, are permitted provided that the following conditions
        !            50:  * are met:
        !            51:  * 1. Redistributions of source code must retain the above copyright
        !            52:  *    notice, this list of conditions and the following disclaimer.
        !            53:  * 2. Redistributions in binary form must reproduce the above copyright
        !            54:  *    notice, this list of conditions and the following disclaimer in the
        !            55:  *    documentation and/or other materials provided with the distribution.
        !            56:  * 3. Neither the name of the University nor the names of its contributors
        !            57:  *    may be used to endorse or promote products derived from this software
        !            58:  *    without specific prior written permission.
        !            59:  *
        !            60:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            61:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            62:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            63:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            64:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            65:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            66:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            67:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            68:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            69:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            70:  * SUCH DAMAGE.
        !            71:  *
        !            72:  *     @(#)boot.c      8.1 (Berkeley) 6/10/93
        !            73:  */
        !            74:
        !            75: int ELFNAME(exec)(int, Elf_Ehdr *, u_long *, int);
        !            76:
        !            77: int
        !            78: ELFNAME(exec)(int fd, Elf_Ehdr *elf, u_long *marks, int flags)
        !            79: {
        !            80:        Elf_Shdr *shp;
        !            81:        Elf_Phdr *phdr;
        !            82:        Elf_Off off;
        !            83:        int i;
        !            84:        size_t sz;
        !            85:        int first;
        !            86:        int havesyms;
        !            87:        paddr_t minp = ~0, maxp = 0, pos = 0;
        !            88:        paddr_t offset = marks[MARK_START], shpp, elfp;
        !            89:
        !            90:        sz = elf->e_phnum * sizeof(Elf_Phdr);
        !            91:        phdr = ALLOC(sz);
        !            92:
        !            93:        if (lseek(fd, (off_t)elf->e_phoff, SEEK_SET) == -1)  {
        !            94:                WARN(("lseek phdr"));
        !            95:                FREE(phdr, sz);
        !            96:                return 1;
        !            97:        }
        !            98:        if (read(fd, phdr, sz) != sz) {
        !            99:                WARN(("read program headers"));
        !           100:                FREE(phdr, sz);
        !           101:                return 1;
        !           102:        }
        !           103:
        !           104:        for (first = 1, i = 0; i < elf->e_phnum; i++) {
        !           105:
        !           106:                if (phdr[i].p_type != PT_LOAD ||
        !           107:                    (phdr[i].p_flags & (PF_W|PF_R|PF_X)) == 0)
        !           108:                        continue;
        !           109:
        !           110: #define IS_TEXT(p)     (p.p_flags & PF_X)
        !           111: #define IS_DATA(p)     ((p.p_flags & PF_X) == 0)
        !           112: #define IS_BSS(p)      (p.p_filesz < p.p_memsz)
        !           113:                /*
        !           114:                 * XXX: Assume first address is lowest
        !           115:                 */
        !           116:                if ((IS_TEXT(phdr[i]) && (flags & LOAD_TEXT)) ||
        !           117:                    (IS_DATA(phdr[i]) && (flags & LOAD_DATA))) {
        !           118:
        !           119:                        /* Read in segment. */
        !           120:                        PROGRESS(("%s%lu", first ? "" : "+",
        !           121:                            (u_long)phdr[i].p_filesz));
        !           122:
        !           123:                        if (lseek(fd, (off_t)phdr[i].p_offset, SEEK_SET) == -1)  {
        !           124:                                WARN(("lseek text"));
        !           125:                                FREE(phdr, sz);
        !           126:                                return 1;
        !           127:                        }
        !           128:                        if (READ(fd, phdr[i].p_vaddr, phdr[i].p_filesz) !=
        !           129:                            phdr[i].p_filesz) {
        !           130:                                WARN(("read text"));
        !           131:                                FREE(phdr, sz);
        !           132:                                return 1;
        !           133:                        }
        !           134:                        first = 0;
        !           135:
        !           136:                }
        !           137:                if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT|COUNT_TEXT))) ||
        !           138:                    (IS_DATA(phdr[i]) && (flags & (LOAD_DATA|COUNT_TEXT)))) {
        !           139:                        pos = phdr[i].p_vaddr;
        !           140:                        if (minp > pos)
        !           141:                                minp = pos;
        !           142:                        pos += phdr[i].p_filesz;
        !           143:                        if (maxp < pos)
        !           144:                                maxp = pos;
        !           145:                }
        !           146:
        !           147:                /* Zero out bss. */
        !           148:                if (IS_BSS(phdr[i]) && (flags & LOAD_BSS)) {
        !           149:                        PROGRESS(("+%lu",
        !           150:                            (u_long)(phdr[i].p_memsz - phdr[i].p_filesz)));
        !           151:                        BZERO((phdr[i].p_vaddr + phdr[i].p_filesz),
        !           152:                            phdr[i].p_memsz - phdr[i].p_filesz);
        !           153:                }
        !           154:                if (IS_BSS(phdr[i]) && (flags & (LOAD_BSS|COUNT_BSS))) {
        !           155:                        pos += phdr[i].p_memsz - phdr[i].p_filesz;
        !           156:                        if (maxp < pos)
        !           157:                                maxp = pos;
        !           158:                }
        !           159:        }
        !           160:        FREE(phdr, sz);
        !           161:
        !           162:        /*
        !           163:         * Copy the ELF and section headers.
        !           164:         */
        !           165:        elfp = maxp = roundup(maxp, sizeof(long));
        !           166:        if (flags & (LOAD_HDR|COUNT_HDR))
        !           167:                maxp += sizeof(Elf_Ehdr);
        !           168:
        !           169:        if (flags & (LOAD_SYM|COUNT_SYM)) {
        !           170:                if (lseek(fd, (off_t)elf->e_shoff, SEEK_SET) == -1)  {
        !           171:                        WARN(("lseek section headers"));
        !           172:                        return 1;
        !           173:                }
        !           174:                sz = elf->e_shnum * sizeof(Elf_Shdr);
        !           175:                shp = ALLOC(sz);
        !           176:
        !           177:                if (read(fd, shp, sz) != sz) {
        !           178:                        WARN(("read section headers"));
        !           179:                        FREE(shp, sz);
        !           180:                        return 1;
        !           181:                }
        !           182:
        !           183:                shpp = maxp;
        !           184:                maxp += roundup(sz, sizeof(long));
        !           185:
        !           186:                /*
        !           187:                 * Now load the symbol sections themselves.  Make sure the
        !           188:                 * sections are aligned. Don't bother with string tables if
        !           189:                 * there are no symbol sections.
        !           190:                 */
        !           191:                off = roundup((sizeof(Elf_Ehdr) + sz), sizeof(long));
        !           192:
        !           193:                for (havesyms = i = 0; i < elf->e_shnum; i++)
        !           194:                        if (shp[i].sh_type == SHT_SYMTAB)
        !           195:                                havesyms = 1;
        !           196:
        !           197:                for (first = 1, i = 0; i < elf->e_shnum; i++) {
        !           198:                        if (shp[i].sh_type == SHT_SYMTAB ||
        !           199:                            shp[i].sh_type == SHT_STRTAB) {
        !           200:                                if (havesyms && (flags & LOAD_SYM)) {
        !           201:                                        PROGRESS(("%s%ld", first ? " [" : "+",
        !           202:                                            (u_long)shp[i].sh_size));
        !           203:                                        if (lseek(fd, (off_t)shp[i].sh_offset,
        !           204:                                            SEEK_SET) == -1) {
        !           205:                                                WARN(("lseek symbols"));
        !           206:                                                FREE(shp, sz);
        !           207:                                                return 1;
        !           208:                                        }
        !           209:                                        if (READ(fd, maxp, shp[i].sh_size) !=
        !           210:                                            shp[i].sh_size) {
        !           211:                                                WARN(("read symbols"));
        !           212:                                                FREE(shp, sz);
        !           213:                                                return 1;
        !           214:                                        }
        !           215:                                }
        !           216:                                maxp += roundup(shp[i].sh_size,
        !           217:                                    sizeof(long));
        !           218:                                shp[i].sh_offset = off;
        !           219:                                off += roundup(shp[i].sh_size, sizeof(long));
        !           220:                                first = 0;
        !           221:                        }
        !           222:                }
        !           223:                if (flags & LOAD_SYM) {
        !           224:                        BCOPY(shp, shpp, sz);
        !           225:
        !           226:                        if (havesyms && first == 0)
        !           227:                                PROGRESS(("]"));
        !           228:                }
        !           229:                FREE(shp, sz);
        !           230:        }
        !           231:
        !           232:        /*
        !           233:         * Frob the copied ELF header to give information relative
        !           234:         * to elfp.
        !           235:         */
        !           236:        if (flags & LOAD_HDR) {
        !           237:                elf->e_phoff = 0;
        !           238:                elf->e_shoff = sizeof(Elf_Ehdr);
        !           239:                elf->e_phentsize = 0;
        !           240:                elf->e_phnum = 0;
        !           241:                BCOPY(elf, elfp, sizeof(*elf));
        !           242:        }
        !           243:
        !           244:        marks[MARK_START] = LOADADDR(minp);
        !           245:        marks[MARK_ENTRY] = LOADADDR(elf->e_entry);
        !           246:        marks[MARK_NSYM] = 1;   /* XXX: Kernel needs >= 0 */
        !           247:        marks[MARK_SYM] = LOADADDR(elfp);
        !           248:        marks[MARK_END] = LOADADDR(maxp);
        !           249:        return 0;
        !           250: }

CVSweb