Annotation of qemu/linux-user/elfload.c, revision 1.1.1.2

1.1       root        1: /* This is the Linux kernel elf-loading code, ported into user space */
                      2: 
                      3: #include <stdio.h>
                      4: #include <sys/types.h>
                      5: #include <fcntl.h>
                      6: #include <sys/stat.h>
                      7: #include <errno.h>
                      8: #include <unistd.h>
                      9: #include <sys/mman.h>
                     10: #include <stdlib.h>
                     11: #include <string.h>
                     12: 
                     13: #include "qemu.h"
                     14: #include "disas.h"
                     15: 
                     16: /* this flag is uneffective under linux too, should be deleted */
                     17: #ifndef MAP_DENYWRITE
                     18: #define MAP_DENYWRITE 0
                     19: #endif
                     20: 
                     21: /* should probably go in elf.h */
                     22: #ifndef ELIBBAD
                     23: #define ELIBBAD 80
                     24: #endif
                     25: 
                     26: #ifdef TARGET_I386
                     27: 
1.1.1.2 ! root       28: #define ELF_PLATFORM get_elf_platform()
        !            29: 
        !            30: static const char *get_elf_platform(void)
        !            31: {
        !            32:     static char elf_platform[] = "i386";
        !            33:     int family = (global_env->cpuid_version >> 8) & 0xff;
        !            34:     if (family > 6)
        !            35:         family = 6;
        !            36:     if (family >= 3)
        !            37:         elf_platform[1] = '0' + family;
        !            38:     return elf_platform;
        !            39: }
        !            40: 
        !            41: #define ELF_HWCAP get_elf_hwcap()
        !            42: 
        !            43: static uint32_t get_elf_hwcap(void)
        !            44: {
        !            45:   return global_env->cpuid_features;
        !            46: }
        !            47: 
1.1       root       48: #define ELF_START_MMAP 0x80000000
                     49: 
                     50: /*
                     51:  * This is used to ensure we don't load something for the wrong architecture.
                     52:  */
                     53: #define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
                     54: 
                     55: /*
                     56:  * These are used to set parameters in the core dumps.
                     57:  */
                     58: #define ELF_CLASS      ELFCLASS32
                     59: #define ELF_DATA       ELFDATA2LSB
                     60: #define ELF_ARCH       EM_386
                     61: 
                     62:        /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
                     63:           starts %edx contains a pointer to a function which might be
                     64:           registered using `atexit'.  This provides a mean for the
                     65:           dynamic linker to call DT_FINI functions for shared libraries
                     66:           that have been loaded before the code runs.
                     67: 
                     68:           A value of 0 tells we have no such handler.  */
                     69: #define ELF_PLAT_INIT(_r)      _r->edx = 0
                     70: 
                     71: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
                     72: {
                     73:     regs->esp = infop->start_stack;
                     74:     regs->eip = infop->entry;
                     75: }
                     76: 
                     77: #define USE_ELF_CORE_DUMP
                     78: #define ELF_EXEC_PAGESIZE      4096
                     79: 
                     80: #endif
                     81: 
                     82: #ifdef TARGET_ARM
                     83: 
                     84: #define ELF_START_MMAP 0x80000000
                     85: 
                     86: #define elf_check_arch(x) ( (x) == EM_ARM )
                     87: 
                     88: #define ELF_CLASS      ELFCLASS32
                     89: #ifdef TARGET_WORDS_BIGENDIAN
                     90: #define ELF_DATA       ELFDATA2MSB
                     91: #else
                     92: #define ELF_DATA       ELFDATA2LSB
                     93: #endif
                     94: #define ELF_ARCH       EM_ARM
                     95: 
                     96: #define ELF_PLAT_INIT(_r)      _r->ARM_r0 = 0
                     97: 
                     98: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
                     99: {
                    100:     target_long *stack = (void *)infop->start_stack;
                    101:     memset(regs, 0, sizeof(*regs));
                    102:     regs->ARM_cpsr = 0x10;
                    103:     regs->ARM_pc = infop->entry;
                    104:     regs->ARM_sp = infop->start_stack;
                    105:     regs->ARM_r2 = tswapl(stack[2]); /* envp */
                    106:     regs->ARM_r1 = tswapl(stack[1]); /* argv */
                    107:     /* XXX: it seems that r0 is zeroed after ! */
                    108:     //    regs->ARM_r0 = tswapl(stack[0]); /* argc */
                    109: }
                    110: 
                    111: #define USE_ELF_CORE_DUMP
                    112: #define ELF_EXEC_PAGESIZE      4096
                    113: 
1.1.1.2 ! root      114: enum
        !           115: {
        !           116:   ARM_HWCAP_ARM_SWP       = 1 << 0,
        !           117:   ARM_HWCAP_ARM_HALF      = 1 << 1,
        !           118:   ARM_HWCAP_ARM_THUMB     = 1 << 2,
        !           119:   ARM_HWCAP_ARM_26BIT     = 1 << 3,
        !           120:   ARM_HWCAP_ARM_FAST_MULT = 1 << 4,
        !           121:   ARM_HWCAP_ARM_FPA       = 1 << 5,
        !           122:   ARM_HWCAP_ARM_VFP       = 1 << 6,
        !           123:   ARM_HWCAP_ARM_EDSP      = 1 << 7,
        !           124: };
        !           125: 
        !           126: #define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF              \
        !           127:                     | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT     \
        !           128:                     | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP)
        !           129: 
1.1       root      130: #endif
                    131: 
                    132: #ifdef TARGET_SPARC
                    133: #ifdef TARGET_SPARC64
                    134: 
                    135: #define ELF_START_MMAP 0x80000000
                    136: 
                    137: #define elf_check_arch(x) ( (x) == EM_SPARC )
                    138: 
                    139: #define ELF_CLASS   ELFCLASS64
                    140: #define ELF_DATA    ELFDATA2MSB
                    141: #define ELF_ARCH    EM_SPARC
                    142: 
                    143: /*XXX*/
                    144: #define ELF_PLAT_INIT(_r)
                    145: 
                    146: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
                    147: {
                    148:     regs->tstate = 0;
                    149:     regs->pc = infop->entry;
                    150:     regs->npc = regs->pc + 4;
                    151:     regs->y = 0;
                    152:     regs->u_regs[14] = infop->start_stack - 16 * 4;
                    153: }
                    154: 
                    155: #else
                    156: #define ELF_START_MMAP 0x80000000
                    157: 
                    158: #define elf_check_arch(x) ( (x) == EM_SPARC )
                    159: 
                    160: #define ELF_CLASS   ELFCLASS32
                    161: #define ELF_DATA    ELFDATA2MSB
                    162: #define ELF_ARCH    EM_SPARC
                    163: 
                    164: /*XXX*/
                    165: #define ELF_PLAT_INIT(_r)
                    166: 
                    167: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
                    168: {
                    169:     regs->psr = 0;
                    170:     regs->pc = infop->entry;
                    171:     regs->npc = regs->pc + 4;
                    172:     regs->y = 0;
                    173:     regs->u_regs[14] = infop->start_stack - 16 * 4;
                    174: }
                    175: 
                    176: #endif
                    177: #endif
                    178: 
                    179: #ifdef TARGET_PPC
                    180: 
                    181: #define ELF_START_MMAP 0x80000000
                    182: 
                    183: #define elf_check_arch(x) ( (x) == EM_PPC )
                    184: 
                    185: #define ELF_CLASS      ELFCLASS32
                    186: #ifdef TARGET_WORDS_BIGENDIAN
                    187: #define ELF_DATA       ELFDATA2MSB
                    188: #else
                    189: #define ELF_DATA       ELFDATA2LSB
                    190: #endif
                    191: #define ELF_ARCH       EM_PPC
                    192: 
                    193: /* Note that isn't exactly what regular kernel does
                    194:  * but this is what the ABI wants and is needed to allow
                    195:  * execution of PPC BSD programs.
                    196:  */
                    197: #define ELF_PLAT_INIT(_r)                                  \
                    198: do {                                                       \
                    199:     target_ulong *pos = (target_ulong *)bprm->p, tmp = 1;  \
                    200:     _r->gpr[3] = bprm->argc;                               \
                    201:     _r->gpr[4] = (unsigned long)++pos;                     \
                    202:     for (; tmp != 0; pos++)                                \
                    203:         tmp = *pos;                                        \
                    204:     _r->gpr[5] = (unsigned long)pos;                       \
                    205: } while (0)
                    206: 
                    207: /*
                    208:  * We need to put in some extra aux table entries to tell glibc what
                    209:  * the cache block size is, so it can use the dcbz instruction safely.
                    210:  */
                    211: #define AT_DCACHEBSIZE          19
                    212: #define AT_ICACHEBSIZE          20
                    213: #define AT_UCACHEBSIZE          21
                    214: /* A special ignored type value for PPC, for glibc compatibility.  */
                    215: #define AT_IGNOREPPC            22
                    216: /*
                    217:  * The requirements here are:
                    218:  * - keep the final alignment of sp (sp & 0xf)
                    219:  * - make sure the 32-bit value at the first 16 byte aligned position of
                    220:  *   AUXV is greater than 16 for glibc compatibility.
                    221:  *   AT_IGNOREPPC is used for that.
                    222:  * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
                    223:  *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
                    224:  */
                    225: #define DLINFO_ARCH_ITEMS       5
                    226: #define ARCH_DLINFO                                                     \
                    227: do {                                                                    \
                    228:         NEW_AUX_ENT(AT_DCACHEBSIZE, 0x20);                              \
                    229:         NEW_AUX_ENT(AT_ICACHEBSIZE, 0x20);                              \
                    230:         NEW_AUX_ENT(AT_UCACHEBSIZE, 0);                                 \
                    231:         /*                                                              \
                    232:          * Now handle glibc compatibility.                              \
                    233:          */                                                             \
                    234:        NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);                        \
                    235:        NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);                        \
                    236:  } while (0)
                    237: 
                    238: static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
                    239: {
                    240:     _regs->msr = 1 << MSR_PR; /* Set user mode */
                    241:     _regs->gpr[1] = infop->start_stack;
                    242:     _regs->nip = infop->entry;
                    243: }
                    244: 
                    245: #define USE_ELF_CORE_DUMP
                    246: #define ELF_EXEC_PAGESIZE      4096
                    247: 
                    248: #endif
                    249: 
1.1.1.2 ! root      250: #ifdef TARGET_MIPS
        !           251: 
        !           252: #define ELF_START_MMAP 0x80000000
        !           253: 
        !           254: #define elf_check_arch(x) ( (x) == EM_MIPS )
        !           255: 
        !           256: #define ELF_CLASS   ELFCLASS32
        !           257: #ifdef TARGET_WORDS_BIGENDIAN
        !           258: #define ELF_DATA       ELFDATA2MSB
        !           259: #else
        !           260: #define ELF_DATA       ELFDATA2LSB
        !           261: #endif
        !           262: #define ELF_ARCH    EM_MIPS
        !           263: 
        !           264: #define ELF_PLAT_INIT(_r) 
        !           265: 
        !           266: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
        !           267: {
        !           268:     regs->cp0_status = CP0St_UM;
        !           269:     regs->cp0_epc = infop->entry;
        !           270:     regs->regs[29] = infop->start_stack;
        !           271: }
        !           272: 
        !           273: #endif /* TARGET_MIPS */
        !           274: 
        !           275: #ifndef ELF_PLATFORM
        !           276: #define ELF_PLATFORM (NULL)
        !           277: #endif
        !           278: 
        !           279: #ifndef ELF_HWCAP
        !           280: #define ELF_HWCAP 0
        !           281: #endif
        !           282: 
1.1       root      283: #include "elf.h"
                    284: 
                    285: /*
                    286:  * MAX_ARG_PAGES defines the number of pages allocated for arguments
                    287:  * and envelope for the new program. 32 should suffice, this gives
                    288:  * a maximum env+arg of 128kB w/4KB pages!
                    289:  */
                    290: #define MAX_ARG_PAGES 32
                    291: 
                    292: /*
                    293:  * This structure is used to hold the arguments that are 
                    294:  * used when loading binaries.
                    295:  */
                    296: struct linux_binprm {
                    297:         char buf[128];
                    298:         unsigned long page[MAX_ARG_PAGES];
                    299:         unsigned long p;
                    300:         int sh_bang;
                    301:        int fd;
                    302:         int e_uid, e_gid;
                    303:         int argc, envc;
                    304:         char * filename;        /* Name of binary */
                    305:         unsigned long loader, exec;
                    306:         int dont_iput;          /* binfmt handler has put inode */
                    307: };
                    308: 
                    309: struct exec
                    310: {
                    311:   unsigned int a_info;   /* Use macros N_MAGIC, etc for access */
                    312:   unsigned int a_text;   /* length of text, in bytes */
                    313:   unsigned int a_data;   /* length of data, in bytes */
                    314:   unsigned int a_bss;    /* length of uninitialized data area, in bytes */
                    315:   unsigned int a_syms;   /* length of symbol table data in file, in bytes */
                    316:   unsigned int a_entry;  /* start address */
                    317:   unsigned int a_trsize; /* length of relocation info for text, in bytes */
                    318:   unsigned int a_drsize; /* length of relocation info for data, in bytes */
                    319: };
                    320: 
                    321: 
                    322: #define N_MAGIC(exec) ((exec).a_info & 0xffff)
                    323: #define OMAGIC 0407
                    324: #define NMAGIC 0410
                    325: #define ZMAGIC 0413
                    326: #define QMAGIC 0314
                    327: 
                    328: /* max code+data+bss space allocated to elf interpreter */
                    329: #define INTERP_MAP_SIZE (32 * 1024 * 1024)
                    330: 
                    331: /* max code+data+bss+brk space allocated to ET_DYN executables */
                    332: #define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
                    333: 
                    334: /* from personality.h */
                    335: 
                    336: /* Flags for bug emulation. These occupy the top three bytes. */
                    337: #define STICKY_TIMEOUTS                0x4000000
                    338: #define WHOLE_SECONDS          0x2000000
                    339: 
                    340: /* Personality types. These go in the low byte. Avoid using the top bit,
                    341:  * it will conflict with error returns.
                    342:  */
                    343: #define PER_MASK               (0x00ff)
                    344: #define PER_LINUX              (0x0000)
                    345: #define PER_SVR4               (0x0001 | STICKY_TIMEOUTS)
                    346: #define PER_SVR3               (0x0002 | STICKY_TIMEOUTS)
                    347: #define PER_SCOSVR3            (0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS)
                    348: #define PER_WYSEV386           (0x0004 | STICKY_TIMEOUTS)
                    349: #define PER_ISCR4              (0x0005 | STICKY_TIMEOUTS)
                    350: #define PER_BSD                        (0x0006)
                    351: #define PER_XENIX              (0x0007 | STICKY_TIMEOUTS)
                    352: 
                    353: /* Necessary parameters */
                    354: #define NGROUPS 32
                    355: 
                    356: #define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
                    357: #define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
                    358: #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
                    359: 
                    360: #define INTERPRETER_NONE 0
                    361: #define INTERPRETER_AOUT 1
                    362: #define INTERPRETER_ELF 2
                    363: 
1.1.1.2 ! root      364: #define DLINFO_ITEMS 12
1.1       root      365: 
                    366: static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
                    367: {
                    368:        memcpy(to, from, n);
                    369: }
                    370: 
                    371: extern unsigned long x86_stack_size;
                    372: 
                    373: static int load_aout_interp(void * exptr, int interp_fd);
                    374: 
                    375: #ifdef BSWAP_NEEDED
                    376: static void bswap_ehdr(struct elfhdr *ehdr)
                    377: {
                    378:     bswap16s(&ehdr->e_type);                   /* Object file type */
                    379:     bswap16s(&ehdr->e_machine);                /* Architecture */
                    380:     bswap32s(&ehdr->e_version);                /* Object file version */
                    381:     bswaptls(&ehdr->e_entry);          /* Entry point virtual address */
                    382:     bswaptls(&ehdr->e_phoff);          /* Program header table file offset */
                    383:     bswaptls(&ehdr->e_shoff);          /* Section header table file offset */
                    384:     bswap32s(&ehdr->e_flags);          /* Processor-specific flags */
                    385:     bswap16s(&ehdr->e_ehsize);         /* ELF header size in bytes */
                    386:     bswap16s(&ehdr->e_phentsize);              /* Program header table entry size */
                    387:     bswap16s(&ehdr->e_phnum);          /* Program header table entry count */
                    388:     bswap16s(&ehdr->e_shentsize);              /* Section header table entry size */
                    389:     bswap16s(&ehdr->e_shnum);          /* Section header table entry count */
                    390:     bswap16s(&ehdr->e_shstrndx);               /* Section header string table index */
                    391: }
                    392: 
                    393: static void bswap_phdr(struct elf_phdr *phdr)
                    394: {
                    395:     bswap32s(&phdr->p_type);                   /* Segment type */
                    396:     bswaptls(&phdr->p_offset);         /* Segment file offset */
                    397:     bswaptls(&phdr->p_vaddr);          /* Segment virtual address */
                    398:     bswaptls(&phdr->p_paddr);          /* Segment physical address */
                    399:     bswaptls(&phdr->p_filesz);         /* Segment size in file */
                    400:     bswaptls(&phdr->p_memsz);          /* Segment size in memory */
                    401:     bswap32s(&phdr->p_flags);          /* Segment flags */
                    402:     bswaptls(&phdr->p_align);          /* Segment alignment */
                    403: }
                    404: 
                    405: static void bswap_shdr(struct elf_shdr *shdr)
                    406: {
                    407:     bswap32s(&shdr->sh_name);
                    408:     bswap32s(&shdr->sh_type);
                    409:     bswaptls(&shdr->sh_flags);
                    410:     bswaptls(&shdr->sh_addr);
                    411:     bswaptls(&shdr->sh_offset);
                    412:     bswaptls(&shdr->sh_size);
                    413:     bswap32s(&shdr->sh_link);
                    414:     bswap32s(&shdr->sh_info);
                    415:     bswaptls(&shdr->sh_addralign);
                    416:     bswaptls(&shdr->sh_entsize);
                    417: }
                    418: 
                    419: static void bswap_sym(Elf32_Sym *sym)
                    420: {
                    421:     bswap32s(&sym->st_name);
                    422:     bswap32s(&sym->st_value);
                    423:     bswap32s(&sym->st_size);
                    424:     bswap16s(&sym->st_shndx);
                    425: }
                    426: #endif
                    427: 
                    428: static void * get_free_page(void)
                    429: {
                    430:     void *     retval;
                    431: 
                    432:     /* User-space version of kernel get_free_page.  Returns a page-aligned
                    433:      * page-sized chunk of memory.
                    434:      */
                    435:     retval = (void *)target_mmap(0, qemu_host_page_size, PROT_READ|PROT_WRITE, 
                    436:                                  MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
                    437: 
                    438:     if((long)retval == -1) {
                    439:        perror("get_free_page");
                    440:        exit(-1);
                    441:     }
                    442:     else {
                    443:        return(retval);
                    444:     }
                    445: }
                    446: 
                    447: static void free_page(void * pageaddr)
                    448: {
                    449:     target_munmap((unsigned long)pageaddr, qemu_host_page_size);
                    450: }
                    451: 
                    452: /*
                    453:  * 'copy_string()' copies argument/envelope strings from user
                    454:  * memory to free pages in kernel mem. These are in a format ready
                    455:  * to be put directly into the top of new user memory.
                    456:  *
                    457:  */
                    458: static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
                    459:                 unsigned long p)
                    460: {
                    461:     char *tmp, *tmp1, *pag = NULL;
                    462:     int len, offset = 0;
                    463: 
                    464:     if (!p) {
                    465:        return 0;       /* bullet-proofing */
                    466:     }
                    467:     while (argc-- > 0) {
                    468:         tmp = argv[argc];
                    469:         if (!tmp) {
                    470:            fprintf(stderr, "VFS: argc is wrong");
                    471:            exit(-1);
                    472:        }
                    473:         tmp1 = tmp;
                    474:        while (*tmp++);
                    475:        len = tmp - tmp1;
                    476:        if (p < len) {  /* this shouldn't happen - 128kB */
                    477:                return 0;
                    478:        }
                    479:        while (len) {
                    480:            --p; --tmp; --len;
                    481:            if (--offset < 0) {
                    482:                offset = p % TARGET_PAGE_SIZE;
                    483:                 pag = (char *) page[p/TARGET_PAGE_SIZE];
                    484:                 if (!pag) {
                    485:                     pag = (char *)get_free_page();
                    486:                     page[p/TARGET_PAGE_SIZE] = (unsigned long)pag;
                    487:                     if (!pag)
                    488:                         return 0;
                    489:                }
                    490:            }
                    491:            if (len == 0 || offset == 0) {
                    492:                *(pag + offset) = *tmp;
                    493:            }
                    494:            else {
                    495:              int bytes_to_copy = (len > offset) ? offset : len;
                    496:              tmp -= bytes_to_copy;
                    497:              p -= bytes_to_copy;
                    498:              offset -= bytes_to_copy;
                    499:              len -= bytes_to_copy;
                    500:              memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
                    501:            }
                    502:        }
                    503:     }
                    504:     return p;
                    505: }
                    506: 
                    507: static int in_group_p(gid_t g)
                    508: {
                    509:     /* return TRUE if we're in the specified group, FALSE otherwise */
                    510:     int                ngroup;
                    511:     int                i;
                    512:     gid_t      grouplist[NGROUPS];
                    513: 
                    514:     ngroup = getgroups(NGROUPS, grouplist);
                    515:     for(i = 0; i < ngroup; i++) {
                    516:        if(grouplist[i] == g) {
                    517:            return 1;
                    518:        }
                    519:     }
                    520:     return 0;
                    521: }
                    522: 
                    523: static int count(char ** vec)
                    524: {
                    525:     int                i;
                    526: 
                    527:     for(i = 0; *vec; i++) {
                    528:         vec++;
                    529:     }
                    530: 
                    531:     return(i);
                    532: }
                    533: 
                    534: static int prepare_binprm(struct linux_binprm *bprm)
                    535: {
                    536:     struct stat                st;
                    537:     int mode;
                    538:     int retval, id_change;
                    539: 
                    540:     if(fstat(bprm->fd, &st) < 0) {
                    541:        return(-errno);
                    542:     }
                    543: 
                    544:     mode = st.st_mode;
                    545:     if(!S_ISREG(mode)) {       /* Must be regular file */
                    546:        return(-EACCES);
                    547:     }
                    548:     if(!(mode & 0111)) {       /* Must have at least one execute bit set */
                    549:        return(-EACCES);
                    550:     }
                    551: 
                    552:     bprm->e_uid = geteuid();
                    553:     bprm->e_gid = getegid();
                    554:     id_change = 0;
                    555: 
                    556:     /* Set-uid? */
                    557:     if(mode & S_ISUID) {
                    558:        bprm->e_uid = st.st_uid;
                    559:        if(bprm->e_uid != geteuid()) {
                    560:            id_change = 1;
                    561:        }
                    562:     }
                    563: 
                    564:     /* Set-gid? */
                    565:     /*
                    566:      * If setgid is set but no group execute bit then this
                    567:      * is a candidate for mandatory locking, not a setgid
                    568:      * executable.
                    569:      */
                    570:     if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
                    571:        bprm->e_gid = st.st_gid;
                    572:        if (!in_group_p(bprm->e_gid)) {
                    573:                id_change = 1;
                    574:        }
                    575:     }
                    576: 
                    577:     memset(bprm->buf, 0, sizeof(bprm->buf));
                    578:     retval = lseek(bprm->fd, 0L, SEEK_SET);
                    579:     if(retval >= 0) {
                    580:         retval = read(bprm->fd, bprm->buf, 128);
                    581:     }
                    582:     if(retval < 0) {
                    583:        perror("prepare_binprm");
                    584:        exit(-1);
                    585:        /* return(-errno); */
                    586:     }
                    587:     else {
                    588:        return(retval);
                    589:     }
                    590: }
                    591: 
                    592: unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
                    593:                                                struct image_info * info)
                    594: {
                    595:     unsigned long stack_base, size, error;
                    596:     int i;
                    597: 
                    598:     /* Create enough stack to hold everything.  If we don't use
                    599:      * it for args, we'll use it for something else...
                    600:      */
                    601:     size = x86_stack_size;
                    602:     if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
                    603:         size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
                    604:     error = target_mmap(0, 
                    605:                         size + qemu_host_page_size,
                    606:                         PROT_READ | PROT_WRITE,
                    607:                         MAP_PRIVATE | MAP_ANONYMOUS,
                    608:                         -1, 0);
                    609:     if (error == -1) {
                    610:         perror("stk mmap");
                    611:         exit(-1);
                    612:     }
                    613:     /* we reserve one extra page at the top of the stack as guard */
                    614:     target_mprotect(error + size, qemu_host_page_size, PROT_NONE);
                    615: 
                    616:     stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;
                    617:     p += stack_base;
                    618: 
                    619:     if (bprm->loader) {
                    620:        bprm->loader += stack_base;
                    621:     }
                    622:     bprm->exec += stack_base;
                    623: 
                    624:     for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
                    625:        if (bprm->page[i]) {
                    626:            info->rss++;
                    627: 
                    628:            memcpy((void *)stack_base, (void *)bprm->page[i], TARGET_PAGE_SIZE);
                    629:            free_page((void *)bprm->page[i]);
                    630:        }
                    631:        stack_base += TARGET_PAGE_SIZE;
                    632:     }
                    633:     return p;
                    634: }
                    635: 
                    636: static void set_brk(unsigned long start, unsigned long end)
                    637: {
                    638:        /* page-align the start and end addresses... */
                    639:         start = HOST_PAGE_ALIGN(start);
                    640:         end = HOST_PAGE_ALIGN(end);
                    641:         if (end <= start)
                    642:                 return;
                    643:         if(target_mmap(start, end - start,
                    644:                        PROT_READ | PROT_WRITE | PROT_EXEC,
                    645:                        MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
                    646:            perror("cannot mmap brk");
                    647:            exit(-1);
                    648:        }
                    649: }
                    650: 
                    651: 
                    652: /* We need to explicitly zero any fractional pages after the data
                    653:    section (i.e. bss).  This would contain the junk from the file that
                    654:    should not be in memory. */
                    655: static void padzero(unsigned long elf_bss)
                    656: {
                    657:         unsigned long nbyte;
                    658:         char * fpnt;
                    659: 
                    660:         /* XXX: this is really a hack : if the real host page size is
                    661:            smaller than the target page size, some pages after the end
                    662:            of the file may not be mapped. A better fix would be to
                    663:            patch target_mmap(), but it is more complicated as the file
                    664:            size must be known */
                    665:         if (qemu_real_host_page_size < qemu_host_page_size) {
                    666:             unsigned long end_addr, end_addr1;
                    667:             end_addr1 = (elf_bss + qemu_real_host_page_size - 1) & 
                    668:                 ~(qemu_real_host_page_size - 1);
                    669:             end_addr = HOST_PAGE_ALIGN(elf_bss);
                    670:             if (end_addr1 < end_addr) {
                    671:                 mmap((void *)end_addr1, end_addr - end_addr1,
                    672:                      PROT_READ|PROT_WRITE|PROT_EXEC,
                    673:                      MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
                    674:             }
                    675:         }
                    676: 
                    677:         nbyte = elf_bss & (qemu_host_page_size-1);
                    678:         if (nbyte) {
                    679:            nbyte = qemu_host_page_size - nbyte;
                    680:            fpnt = (char *) elf_bss;
                    681:            do {
                    682:                *fpnt++ = 0;
                    683:            } while (--nbyte);
                    684:         }
                    685: }
                    686: 
                    687: static unsigned int * create_elf_tables(char *p, int argc, int envc,
                    688:                                         struct elfhdr * exec,
                    689:                                         unsigned long load_addr,
                    690:                                         unsigned long load_bias,
                    691:                                         unsigned long interp_load_addr, int ibcs,
                    692:                                         struct image_info *info)
                    693: {
                    694:         target_ulong *argv, *envp;
                    695:         target_ulong *sp, *csp;
1.1.1.2 ! root      696:         target_ulong *u_platform;
        !           697:         const char *k_platform;
1.1       root      698:         int v;
                    699: 
                    700:        /*
                    701:         * Force 16 byte _final_ alignment here for generality.
                    702:         */
                    703:         sp = (unsigned int *) (~15UL & (unsigned long) p);
1.1.1.2 ! root      704:         u_platform = NULL;
        !           705:         k_platform = ELF_PLATFORM;
        !           706:         if (k_platform) {
        !           707:             size_t len = strlen(k_platform) + 1;
        !           708:             sp -= (len + sizeof(target_ulong) - 1) / sizeof(target_ulong);
        !           709:             u_platform = (target_ulong *)sp;
        !           710:             __copy_to_user(u_platform, k_platform, len);
        !           711:         }
1.1       root      712:         csp = sp;
                    713:         csp -= (DLINFO_ITEMS + 1) * 2;
1.1.1.2 ! root      714:         if (k_platform)
        !           715:           csp -= 2;
1.1       root      716: #ifdef DLINFO_ARCH_ITEMS
                    717:        csp -= DLINFO_ARCH_ITEMS*2;
                    718: #endif
                    719:         csp -= envc+1;
                    720:         csp -= argc+1;
                    721:        csp -= (!ibcs ? 3 : 1); /* argc itself */
                    722:         if ((unsigned long)csp & 15UL)
                    723:             sp -= ((unsigned long)csp & 15UL) / sizeof(*sp);
                    724:         
                    725: #define NEW_AUX_ENT(id, val) \
                    726:           sp -= 2; \
                    727:           put_user (id, sp); \
                    728:           put_user (val, sp + 1)
                    729:         NEW_AUX_ENT (AT_NULL, 0);
                    730: 
                    731:         /* There must be exactly DLINFO_ITEMS entries here.  */
                    732:         NEW_AUX_ENT(AT_PHDR, (target_ulong)(load_addr + exec->e_phoff));
                    733:         NEW_AUX_ENT(AT_PHENT, (target_ulong)(sizeof (struct elf_phdr)));
                    734:         NEW_AUX_ENT(AT_PHNUM, (target_ulong)(exec->e_phnum));
                    735:         NEW_AUX_ENT(AT_PAGESZ, (target_ulong)(TARGET_PAGE_SIZE));
                    736:         NEW_AUX_ENT(AT_BASE, (target_ulong)(interp_load_addr));
                    737:         NEW_AUX_ENT(AT_FLAGS, (target_ulong)0);
                    738:         NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry);
                    739:         NEW_AUX_ENT(AT_UID, (target_ulong) getuid());
                    740:         NEW_AUX_ENT(AT_EUID, (target_ulong) geteuid());
                    741:         NEW_AUX_ENT(AT_GID, (target_ulong) getgid());
                    742:         NEW_AUX_ENT(AT_EGID, (target_ulong) getegid());
1.1.1.2 ! root      743:         NEW_AUX_ENT(AT_HWCAP, (target_ulong) ELF_HWCAP);
        !           744:         if (k_platform)
        !           745:             NEW_AUX_ENT(AT_PLATFORM, (target_ulong) u_platform);
1.1       root      746: #ifdef ARCH_DLINFO
                    747:        /* 
                    748:         * ARCH_DLINFO must come last so platform specific code can enforce
                    749:         * special alignment requirements on the AUXV if necessary (eg. PPC).
                    750:         */
                    751:         ARCH_DLINFO;
                    752: #endif
                    753: #undef NEW_AUX_ENT
                    754: 
                    755:         sp -= envc+1;
                    756:         envp = sp;
                    757:         sp -= argc+1;
                    758:         argv = sp;
                    759:         if (!ibcs) {
                    760:                 put_user((target_ulong)envp,--sp);
                    761:                 put_user((target_ulong)argv,--sp);
                    762:         }
                    763:         put_user(argc,--sp);
                    764:         info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
                    765:         while (argc-->0) {
                    766:                 put_user((target_ulong)p,argv++);
                    767:                 do {
                    768:                     get_user(v, p);
                    769:                     p++;
                    770:                 } while (v != 0);
                    771:         }
                    772:         put_user(0,argv);
                    773:         info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff);
                    774:         while (envc-->0) {
                    775:                 put_user((target_ulong)p,envp++);
                    776:                 do {
                    777:                     get_user(v, p);
                    778:                     p++;
                    779:                 } while (v != 0);
                    780:         }
                    781:         put_user(0,envp);
                    782:         info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
                    783:         return sp;
                    784: }
                    785: 
                    786: 
                    787: 
                    788: static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
                    789:                                     int interpreter_fd,
                    790:                                     unsigned long *interp_load_addr)
                    791: {
                    792:        struct elf_phdr *elf_phdata  =  NULL;
                    793:        struct elf_phdr *eppnt;
                    794:        unsigned long load_addr = 0;
                    795:        int load_addr_set = 0;
                    796:        int retval;
                    797:        unsigned long last_bss, elf_bss;
                    798:        unsigned long error;
                    799:        int i;
                    800:        
                    801:        elf_bss = 0;
                    802:        last_bss = 0;
                    803:        error = 0;
                    804: 
                    805: #ifdef BSWAP_NEEDED
                    806:         bswap_ehdr(interp_elf_ex);
                    807: #endif
                    808:        /* First of all, some simple consistency checks */
                    809:        if ((interp_elf_ex->e_type != ET_EXEC && 
                    810:              interp_elf_ex->e_type != ET_DYN) || 
                    811:           !elf_check_arch(interp_elf_ex->e_machine)) {
                    812:                return ~0UL;
                    813:        }
                    814:        
                    815: 
                    816:        /* Now read in all of the header information */
                    817:        
                    818:        if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
                    819:            return ~0UL;
                    820:        
                    821:        elf_phdata =  (struct elf_phdr *) 
                    822:                malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
                    823: 
                    824:        if (!elf_phdata)
                    825:          return ~0UL;
                    826:        
                    827:        /*
                    828:         * If the size of this structure has changed, then punt, since
                    829:         * we will be doing the wrong thing.
                    830:         */
                    831:        if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
                    832:            free(elf_phdata);
                    833:            return ~0UL;
                    834:         }
                    835: 
                    836:        retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
                    837:        if(retval >= 0) {
                    838:            retval = read(interpreter_fd,
                    839:                           (char *) elf_phdata,
                    840:                           sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
                    841:        }
                    842:        if (retval < 0) {
                    843:                perror("load_elf_interp");
                    844:                exit(-1);
                    845:                free (elf_phdata);
                    846:                return retval;
                    847:        }
                    848: #ifdef BSWAP_NEEDED
                    849:        eppnt = elf_phdata;
                    850:        for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
                    851:             bswap_phdr(eppnt);
                    852:         }
                    853: #endif
                    854: 
                    855:         if (interp_elf_ex->e_type == ET_DYN) {
                    856:             /* in order to avoid harcoding the interpreter load
                    857:                address in qemu, we allocate a big enough memory zone */
                    858:             error = target_mmap(0, INTERP_MAP_SIZE,
                    859:                                 PROT_NONE, MAP_PRIVATE | MAP_ANON, 
                    860:                                 -1, 0);
                    861:             if (error == -1) {
                    862:                 perror("mmap");
                    863:                 exit(-1);
                    864:             }
                    865:             load_addr = error;
                    866:             load_addr_set = 1;
                    867:         }
                    868: 
                    869:        eppnt = elf_phdata;
                    870:        for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
                    871:          if (eppnt->p_type == PT_LOAD) {
                    872:            int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
                    873:            int elf_prot = 0;
                    874:            unsigned long vaddr = 0;
                    875:            unsigned long k;
                    876: 
                    877:            if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
                    878:            if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
                    879:            if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
                    880:            if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
                    881:                elf_type |= MAP_FIXED;
                    882:                vaddr = eppnt->p_vaddr;
                    883:            }
                    884:            error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr),
                    885:                 eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
                    886:                 elf_prot,
                    887:                 elf_type,
                    888:                 interpreter_fd,
                    889:                 eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
                    890:            
                    891:            if (error > -1024UL) {
                    892:              /* Real error */
                    893:              close(interpreter_fd);
                    894:              free(elf_phdata);
                    895:              return ~0UL;
                    896:            }
                    897: 
                    898:            if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
                    899:              load_addr = error;
                    900:              load_addr_set = 1;
                    901:            }
                    902: 
                    903:            /*
                    904:             * Find the end of the file  mapping for this phdr, and keep
                    905:             * track of the largest address we see for this.
                    906:             */
                    907:            k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
                    908:            if (k > elf_bss) elf_bss = k;
                    909: 
                    910:            /*
                    911:             * Do the same thing for the memory mapping - between
                    912:             * elf_bss and last_bss is the bss section.
                    913:             */
                    914:            k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
                    915:            if (k > last_bss) last_bss = k;
                    916:          }
                    917:        
                    918:        /* Now use mmap to map the library into memory. */
                    919: 
                    920:        close(interpreter_fd);
                    921: 
                    922:        /*
                    923:         * Now fill out the bss section.  First pad the last page up
                    924:         * to the page boundary, and then perform a mmap to make sure
                    925:         * that there are zeromapped pages up to and including the last
                    926:         * bss page.
                    927:         */
                    928:        padzero(elf_bss);
                    929:        elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What we have mapped so far */
                    930: 
                    931:        /* Map the last of the bss segment */
                    932:        if (last_bss > elf_bss) {
                    933:             target_mmap(elf_bss, last_bss-elf_bss,
                    934:                         PROT_READ|PROT_WRITE|PROT_EXEC,
                    935:                         MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
                    936:        }
                    937:        free(elf_phdata);
                    938: 
                    939:        *interp_load_addr = load_addr;
                    940:        return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
                    941: }
                    942: 
                    943: /* Best attempt to load symbols from this ELF object. */
                    944: static void load_symbols(struct elfhdr *hdr, int fd)
                    945: {
                    946:     unsigned int i;
                    947:     struct elf_shdr sechdr, symtab, strtab;
                    948:     char *strings;
                    949:     struct syminfo *s;
                    950: 
                    951:     lseek(fd, hdr->e_shoff, SEEK_SET);
                    952:     for (i = 0; i < hdr->e_shnum; i++) {
                    953:        if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
                    954:            return;
                    955: #ifdef BSWAP_NEEDED
                    956:        bswap_shdr(&sechdr);
                    957: #endif
                    958:        if (sechdr.sh_type == SHT_SYMTAB) {
                    959:            symtab = sechdr;
                    960:            lseek(fd, hdr->e_shoff
                    961:                  + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
                    962:            if (read(fd, &strtab, sizeof(strtab))
                    963:                != sizeof(strtab))
                    964:                return;
                    965: #ifdef BSWAP_NEEDED
                    966:            bswap_shdr(&strtab);
                    967: #endif
                    968:            goto found;
                    969:        }
                    970:     }
                    971:     return; /* Shouldn't happen... */
                    972: 
                    973:  found:
                    974:     /* Now know where the strtab and symtab are.  Snarf them. */
                    975:     s = malloc(sizeof(*s));
                    976:     s->disas_symtab = malloc(symtab.sh_size);
                    977:     s->disas_strtab = strings = malloc(strtab.sh_size);
                    978:     if (!s->disas_symtab || !s->disas_strtab)
                    979:        return;
                    980:        
                    981:     lseek(fd, symtab.sh_offset, SEEK_SET);
                    982:     if (read(fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size)
                    983:        return;
                    984: 
                    985: #ifdef BSWAP_NEEDED
                    986:     for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++)
                    987:        bswap_sym(s->disas_symtab + sizeof(struct elf_sym)*i);
                    988: #endif
                    989: 
                    990:     lseek(fd, strtab.sh_offset, SEEK_SET);
                    991:     if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
                    992:        return;
                    993:     s->disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
                    994:     s->next = syminfos;
                    995:     syminfos = s;
                    996: }
                    997: 
                    998: static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
                    999:                            struct image_info * info)
                   1000: {
                   1001:     struct elfhdr elf_ex;
                   1002:     struct elfhdr interp_elf_ex;
                   1003:     struct exec interp_ex;
                   1004:     int interpreter_fd = -1; /* avoid warning */
                   1005:     unsigned long load_addr, load_bias;
                   1006:     int load_addr_set = 0;
                   1007:     unsigned int interpreter_type = INTERPRETER_NONE;
                   1008:     unsigned char ibcs2_interpreter;
                   1009:     int i;
                   1010:     unsigned long mapped_addr;
                   1011:     struct elf_phdr * elf_ppnt;
                   1012:     struct elf_phdr *elf_phdata;
                   1013:     unsigned long elf_bss, k, elf_brk;
                   1014:     int retval;
                   1015:     char * elf_interpreter;
                   1016:     unsigned long elf_entry, interp_load_addr = 0;
                   1017:     int status;
                   1018:     unsigned long start_code, end_code, end_data;
                   1019:     unsigned long elf_stack;
                   1020:     char passed_fileno[6];
                   1021: 
                   1022:     ibcs2_interpreter = 0;
                   1023:     status = 0;
                   1024:     load_addr = 0;
                   1025:     load_bias = 0;
                   1026:     elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
                   1027: #ifdef BSWAP_NEEDED
                   1028:     bswap_ehdr(&elf_ex);
                   1029: #endif
                   1030: 
                   1031:     if (elf_ex.e_ident[0] != 0x7f ||
                   1032:        strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
                   1033:            return  -ENOEXEC;
                   1034:     }
                   1035: 
                   1036:     /* First of all, some simple consistency checks */
                   1037:     if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
                   1038:                                        (! elf_check_arch(elf_ex.e_machine))) {
                   1039:            return -ENOEXEC;
                   1040:     }
                   1041: 
                   1042:     /* Now read in all of the header information */
                   1043:     elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
                   1044:     if (elf_phdata == NULL) {
                   1045:        return -ENOMEM;
                   1046:     }
                   1047: 
                   1048:     retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
                   1049:     if(retval > 0) {
                   1050:        retval = read(bprm->fd, (char *) elf_phdata, 
                   1051:                                elf_ex.e_phentsize * elf_ex.e_phnum);
                   1052:     }
                   1053: 
                   1054:     if (retval < 0) {
                   1055:        perror("load_elf_binary");
                   1056:        exit(-1);
                   1057:        free (elf_phdata);
                   1058:        return -errno;
                   1059:     }
                   1060: 
                   1061: #ifdef BSWAP_NEEDED
                   1062:     elf_ppnt = elf_phdata;
                   1063:     for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
                   1064:         bswap_phdr(elf_ppnt);
                   1065:     }
                   1066: #endif
                   1067:     elf_ppnt = elf_phdata;
                   1068: 
                   1069:     elf_bss = 0;
                   1070:     elf_brk = 0;
                   1071: 
                   1072: 
                   1073:     elf_stack = ~0UL;
                   1074:     elf_interpreter = NULL;
                   1075:     start_code = ~0UL;
                   1076:     end_code = 0;
                   1077:     end_data = 0;
                   1078: 
                   1079:     for(i=0;i < elf_ex.e_phnum; i++) {
                   1080:        if (elf_ppnt->p_type == PT_INTERP) {
                   1081:            if ( elf_interpreter != NULL )
                   1082:            {
                   1083:                free (elf_phdata);
                   1084:                free(elf_interpreter);
                   1085:                close(bprm->fd);
                   1086:                return -EINVAL;
                   1087:            }
                   1088: 
                   1089:            /* This is the program interpreter used for
                   1090:             * shared libraries - for now assume that this
                   1091:             * is an a.out format binary
                   1092:             */
                   1093: 
                   1094:            elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
                   1095: 
                   1096:            if (elf_interpreter == NULL) {
                   1097:                free (elf_phdata);
                   1098:                close(bprm->fd);
                   1099:                return -ENOMEM;
                   1100:            }
                   1101: 
                   1102:            retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
                   1103:            if(retval >= 0) {
                   1104:                retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
                   1105:            }
                   1106:            if(retval < 0) {
                   1107:                perror("load_elf_binary2");
                   1108:                exit(-1);
                   1109:            }   
                   1110: 
                   1111:            /* If the program interpreter is one of these two,
                   1112:               then assume an iBCS2 image. Otherwise assume
                   1113:               a native linux image. */
                   1114: 
                   1115:            /* JRP - Need to add X86 lib dir stuff here... */
                   1116: 
                   1117:            if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
                   1118:                strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
                   1119:              ibcs2_interpreter = 1;
                   1120:            }
                   1121: 
                   1122: #if 0
                   1123:            printf("Using ELF interpreter %s\n", elf_interpreter);
                   1124: #endif
                   1125:            if (retval >= 0) {
                   1126:                retval = open(path(elf_interpreter), O_RDONLY);
                   1127:                if(retval >= 0) {
                   1128:                    interpreter_fd = retval;
                   1129:                }
                   1130:                else {
                   1131:                    perror(elf_interpreter);
                   1132:                    exit(-1);
                   1133:                    /* retval = -errno; */
                   1134:                }
                   1135:            }
                   1136: 
                   1137:            if (retval >= 0) {
                   1138:                retval = lseek(interpreter_fd, 0, SEEK_SET);
                   1139:                if(retval >= 0) {
                   1140:                    retval = read(interpreter_fd,bprm->buf,128);
                   1141:                }
                   1142:            }
                   1143:            if (retval >= 0) {
                   1144:                interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
                   1145:                interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */
                   1146:            }
                   1147:            if (retval < 0) {
                   1148:                perror("load_elf_binary3");
                   1149:                exit(-1);
                   1150:                free (elf_phdata);
                   1151:                free(elf_interpreter);
                   1152:                close(bprm->fd);
                   1153:                return retval;
                   1154:            }
                   1155:        }
                   1156:        elf_ppnt++;
                   1157:     }
                   1158: 
                   1159:     /* Some simple consistency checks for the interpreter */
                   1160:     if (elf_interpreter){
                   1161:        interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
                   1162: 
                   1163:        /* Now figure out which format our binary is */
                   1164:        if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
                   1165:                (N_MAGIC(interp_ex) != QMAGIC)) {
                   1166:          interpreter_type = INTERPRETER_ELF;
                   1167:        }
                   1168: 
                   1169:        if (interp_elf_ex.e_ident[0] != 0x7f ||
                   1170:                strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
                   1171:            interpreter_type &= ~INTERPRETER_ELF;
                   1172:        }
                   1173: 
                   1174:        if (!interpreter_type) {
                   1175:            free(elf_interpreter);
                   1176:            free(elf_phdata);
                   1177:            close(bprm->fd);
                   1178:            return -ELIBBAD;
                   1179:        }
                   1180:     }
                   1181: 
                   1182:     /* OK, we are done with that, now set up the arg stuff,
                   1183:        and then start this sucker up */
                   1184: 
                   1185:     if (!bprm->sh_bang) {
                   1186:        char * passed_p;
                   1187: 
                   1188:        if (interpreter_type == INTERPRETER_AOUT) {
                   1189:            snprintf(passed_fileno, sizeof(passed_fileno), "%d", bprm->fd);
                   1190:            passed_p = passed_fileno;
                   1191: 
                   1192:            if (elf_interpreter) {
                   1193:                bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p);
                   1194:                bprm->argc++;
                   1195:            }
                   1196:        }
                   1197:        if (!bprm->p) {
                   1198:            if (elf_interpreter) {
                   1199:                free(elf_interpreter);
                   1200:            }
                   1201:            free (elf_phdata);
                   1202:            close(bprm->fd);
                   1203:            return -E2BIG;
                   1204:        }
                   1205:     }
                   1206: 
                   1207:     /* OK, This is the point of no return */
                   1208:     info->end_data = 0;
                   1209:     info->end_code = 0;
                   1210:     info->start_mmap = (unsigned long)ELF_START_MMAP;
                   1211:     info->mmap = 0;
                   1212:     elf_entry = (unsigned long) elf_ex.e_entry;
                   1213: 
                   1214:     /* Do this so that we can load the interpreter, if need be.  We will
                   1215:        change some of these later */
                   1216:     info->rss = 0;
                   1217:     bprm->p = setup_arg_pages(bprm->p, bprm, info);
                   1218:     info->start_stack = bprm->p;
                   1219: 
                   1220:     /* Now we do a little grungy work by mmaping the ELF image into
                   1221:      * the correct location in memory.  At this point, we assume that
                   1222:      * the image should be loaded at fixed address, not at a variable
                   1223:      * address.
                   1224:      */
                   1225: 
                   1226:     for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
                   1227:         int elf_prot = 0;
                   1228:         int elf_flags = 0;
                   1229:         unsigned long error;
                   1230:         
                   1231:        if (elf_ppnt->p_type != PT_LOAD)
                   1232:             continue;
                   1233:         
                   1234:         if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
                   1235:         if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
                   1236:         if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
                   1237:         elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
                   1238:         if (elf_ex.e_type == ET_EXEC || load_addr_set) {
                   1239:             elf_flags |= MAP_FIXED;
                   1240:         } else if (elf_ex.e_type == ET_DYN) {
                   1241:             /* Try and get dynamic programs out of the way of the default mmap
                   1242:                base, as well as whatever program they might try to exec.  This
                   1243:                is because the brk will follow the loader, and is not movable.  */
                   1244:             /* NOTE: for qemu, we do a big mmap to get enough space
                   1245:                without harcoding any address */
                   1246:             error = target_mmap(0, ET_DYN_MAP_SIZE,
                   1247:                                 PROT_NONE, MAP_PRIVATE | MAP_ANON, 
                   1248:                                 -1, 0);
                   1249:             if (error == -1) {
                   1250:                 perror("mmap");
                   1251:                 exit(-1);
                   1252:             }
                   1253:             load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
                   1254:         }
                   1255:         
                   1256:         error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
                   1257:                             (elf_ppnt->p_filesz +
                   1258:                              TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
                   1259:                             elf_prot,
                   1260:                             (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
                   1261:                             bprm->fd,
                   1262:                             (elf_ppnt->p_offset - 
                   1263:                              TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
                   1264:         if (error == -1) {
                   1265:             perror("mmap");
                   1266:             exit(-1);
                   1267:         }
                   1268: 
                   1269: #ifdef LOW_ELF_STACK
                   1270:         if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
                   1271:             elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);
                   1272: #endif
                   1273:         
                   1274:         if (!load_addr_set) {
                   1275:             load_addr_set = 1;
                   1276:             load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
                   1277:             if (elf_ex.e_type == ET_DYN) {
                   1278:                 load_bias += error -
                   1279:                     TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
                   1280:                 load_addr += load_bias;
                   1281:             }
                   1282:         }
                   1283:         k = elf_ppnt->p_vaddr;
                   1284:         if (k < start_code) 
                   1285:             start_code = k;
                   1286:         k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
                   1287:         if (k > elf_bss) 
                   1288:             elf_bss = k;
                   1289:         if ((elf_ppnt->p_flags & PF_X) && end_code <  k)
                   1290:             end_code = k;
                   1291:         if (end_data < k) 
                   1292:             end_data = k;
                   1293:         k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
                   1294:         if (k > elf_brk) elf_brk = k;
                   1295:     }
                   1296: 
                   1297:     elf_entry += load_bias;
                   1298:     elf_bss += load_bias;
                   1299:     elf_brk += load_bias;
                   1300:     start_code += load_bias;
                   1301:     end_code += load_bias;
                   1302:     //    start_data += load_bias;
                   1303:     end_data += load_bias;
                   1304: 
                   1305:     if (elf_interpreter) {
                   1306:        if (interpreter_type & 1) {
                   1307:            elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
                   1308:        }
                   1309:        else if (interpreter_type & 2) {
                   1310:            elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
                   1311:                                            &interp_load_addr);
                   1312:        }
                   1313: 
                   1314:        close(interpreter_fd);
                   1315:        free(elf_interpreter);
                   1316: 
                   1317:        if (elf_entry == ~0UL) {
                   1318:            printf("Unable to load interpreter\n");
                   1319:            free(elf_phdata);
                   1320:            exit(-1);
                   1321:            return 0;
                   1322:        }
                   1323:     }
                   1324: 
                   1325:     free(elf_phdata);
                   1326: 
                   1327:     if (loglevel)
                   1328:        load_symbols(&elf_ex, bprm->fd);
                   1329: 
                   1330:     if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
                   1331:     info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
                   1332: 
                   1333: #ifdef LOW_ELF_STACK
                   1334:     info->start_stack = bprm->p = elf_stack - 4;
                   1335: #endif
                   1336:     bprm->p = (unsigned long)
                   1337:       create_elf_tables((char *)bprm->p,
                   1338:                    bprm->argc,
                   1339:                    bprm->envc,
                   1340:                     &elf_ex,
                   1341:                     load_addr, load_bias,
                   1342:                    interp_load_addr,
                   1343:                    (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
                   1344:                    info);
                   1345:     if (interpreter_type == INTERPRETER_AOUT)
                   1346:       info->arg_start += strlen(passed_fileno) + 1;
                   1347:     info->start_brk = info->brk = elf_brk;
                   1348:     info->end_code = end_code;
                   1349:     info->start_code = start_code;
                   1350:     info->end_data = end_data;
                   1351:     info->start_stack = bprm->p;
                   1352: 
                   1353:     /* Calling set_brk effectively mmaps the pages that we need for the bss and break
                   1354:        sections */
                   1355:     set_brk(elf_bss, elf_brk);
                   1356: 
                   1357:     padzero(elf_bss);
                   1358: 
                   1359: #if 0
                   1360:     printf("(start_brk) %x\n" , info->start_brk);
                   1361:     printf("(end_code) %x\n" , info->end_code);
                   1362:     printf("(start_code) %x\n" , info->start_code);
                   1363:     printf("(end_data) %x\n" , info->end_data);
                   1364:     printf("(start_stack) %x\n" , info->start_stack);
                   1365:     printf("(brk) %x\n" , info->brk);
                   1366: #endif
                   1367: 
                   1368:     if ( info->personality == PER_SVR4 )
                   1369:     {
                   1370:            /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
                   1371:               and some applications "depend" upon this behavior.
                   1372:               Since we do not have the power to recompile these, we
                   1373:               emulate the SVr4 behavior.  Sigh.  */
                   1374:            mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC,
                   1375:                                       MAP_FIXED | MAP_PRIVATE, -1, 0);
                   1376:     }
                   1377: 
                   1378: #ifdef ELF_PLAT_INIT
                   1379:     /*
                   1380:      * The ABI may specify that certain registers be set up in special
                   1381:      * ways (on i386 %edx is the address of a DT_FINI function, for
                   1382:      * example.  This macro performs whatever initialization to
                   1383:      * the regs structure is required.
                   1384:      */
                   1385:     ELF_PLAT_INIT(regs);
                   1386: #endif
                   1387: 
                   1388: 
                   1389:     info->entry = elf_entry;
                   1390: 
                   1391:     return 0;
                   1392: }
                   1393: 
                   1394: 
                   1395: 
                   1396: int elf_exec(const char * filename, char ** argv, char ** envp, 
                   1397:              struct target_pt_regs * regs, struct image_info *infop)
                   1398: {
                   1399:         struct linux_binprm bprm;
                   1400:         int retval;
                   1401:         int i;
                   1402: 
                   1403:         bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
                   1404:         for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
                   1405:                 bprm.page[i] = 0;
                   1406:         retval = open(filename, O_RDONLY);
                   1407:         if (retval < 0)
                   1408:             return retval;
                   1409:         bprm.fd = retval;
                   1410:         bprm.filename = (char *)filename;
                   1411:         bprm.sh_bang = 0;
                   1412:         bprm.loader = 0;
                   1413:         bprm.exec = 0;
                   1414:         bprm.dont_iput = 0;
                   1415:        bprm.argc = count(argv);
                   1416:        bprm.envc = count(envp);
                   1417: 
                   1418:         retval = prepare_binprm(&bprm);
                   1419: 
                   1420:         if(retval>=0) {
                   1421:            bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p);
                   1422:            bprm.exec = bprm.p;
                   1423:            bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p);
                   1424:            bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p);
                   1425:            if (!bprm.p) {
                   1426:                retval = -E2BIG;
                   1427:            }
                   1428:         }
                   1429: 
                   1430:         if(retval>=0) {
                   1431:            retval = load_elf_binary(&bprm,regs,infop);
                   1432:        }
                   1433:         if(retval>=0) {
                   1434:            /* success.  Initialize important registers */
                   1435:             init_thread(regs, infop);
                   1436:            return retval;
                   1437:        }
                   1438: 
                   1439:         /* Something went wrong, return the inode and free the argument pages*/
                   1440:         for (i=0 ; i<MAX_ARG_PAGES ; i++) {
                   1441:            free_page((void *)bprm.page[i]);
                   1442:        }
                   1443:         return(retval);
                   1444: }
                   1445: 
                   1446: 
                   1447: static int load_aout_interp(void * exptr, int interp_fd)
                   1448: {
                   1449:     printf("a.out interpreter not yet supported\n");
                   1450:     return(0);
                   1451: }
                   1452: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.