static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex,

                                 int interpreter_fd,

                                 abi_ulong *interp_load_addr,

                                 char bprm_buf[BPRM_BUF_SIZE])

{

    struct elf_phdr *elf_phdata  =  NULL;

    abi_ulong load_addr, load_bias, loaddr, hiaddr;

    int retval;

    abi_ulong error;

    int i;



    bswap_ehdr(interp_elf_ex);

    /* First of all, some simple consistency checks */

    if ((interp_elf_ex->e_type != ET_EXEC &&

         interp_elf_ex->e_type != ET_DYN) ||

        !elf_check_arch(interp_elf_ex->e_machine)) {

        return ~((abi_ulong)0UL);

    }



    /* Now read in all of the header information */



    if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)

        return ~(abi_ulong)0UL;



    elf_phdata =  (struct elf_phdr *)

        malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);



    if (!elf_phdata)

        return ~((abi_ulong)0UL);



    /*

     * If the size of this structure has changed, then punt, since

     * we will be doing the wrong thing.

     */

    if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {

        free(elf_phdata);

        return ~((abi_ulong)0UL);

    }



    i = interp_elf_ex->e_phnum * sizeof(struct elf_phdr);

    if (interp_elf_ex->e_phoff + i <= BPRM_BUF_SIZE) {

        memcpy(elf_phdata, bprm_buf + interp_elf_ex->e_phoff, i);

    } else {

        retval = pread(interpreter_fd, elf_phdata, i, interp_elf_ex->e_phoff);

        if (retval != i) {

            perror("load_elf_interp");

            exit(-1);

        }

    }

    bswap_phdr(elf_phdata, interp_elf_ex->e_phnum);



    /* Find the maximum size of the image and allocate an appropriate

       amount of memory to handle that.  */

    loaddr = -1, hiaddr = 0;

    for (i = 0; i < interp_elf_ex->e_phnum; ++i) {

        if (elf_phdata[i].p_type == PT_LOAD) {

            abi_ulong a = elf_phdata[i].p_vaddr;

            if (a < loaddr) {

                loaddr = a;

            }

            a += elf_phdata[i].p_memsz;

            if (a > hiaddr) {

                hiaddr = a;

            }

        }

    }



    load_addr = loaddr;

    if (interp_elf_ex->e_type == ET_DYN) {

        /* The image indicates that it can be loaded anywhere.  Find a

           location that can hold the memory space required.  If the

           image is pre-linked, LOADDR will be non-zero.  Since we do

           not supply MAP_FIXED here we'll use that address if and

           only if it remains available.  */

        load_addr = target_mmap(loaddr, hiaddr - loaddr, PROT_NONE,

                                MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,

                                -1, 0);

        if (load_addr == -1) {

            perror("mmap");

            exit(-1);

        }

    }

    load_bias = load_addr - loaddr;



    for (i = 0; i < interp_elf_ex->e_phnum; i++) {

        struct elf_phdr *eppnt = elf_phdata + i;

        if (eppnt->p_type == PT_LOAD) {

            abi_ulong vaddr, vaddr_po, vaddr_ps, vaddr_ef, vaddr_em;

            int elf_prot = 0;



            if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;

            if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;

            if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;



            vaddr = load_bias + eppnt->p_vaddr;

            vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr);

            vaddr_ps = TARGET_ELF_PAGESTART(vaddr);



            error = target_mmap(vaddr_ps, eppnt->p_filesz + vaddr_po,

                                elf_prot, MAP_PRIVATE | MAP_FIXED,

                                interpreter_fd, eppnt->p_offset - vaddr_po);

            if (error == -1) {

                /* Real error */

                close(interpreter_fd);

                free(elf_phdata);

                return ~((abi_ulong)0UL);

            }



            vaddr_ef = vaddr + eppnt->p_filesz;

            vaddr_em = vaddr + eppnt->p_memsz;



            /* If the load segment requests extra zeros (e.g. bss), map it.  */

            if (vaddr_ef < vaddr_em) {

                zero_bss(vaddr_ef, vaddr_em, elf_prot);

            }

        }

    }



    if (qemu_log_enabled()) {

        load_symbols(interp_elf_ex, interpreter_fd, load_bias);

    }



    close(interpreter_fd);

    free(elf_phdata);



    *interp_load_addr = load_addr;

    return ((abi_ulong) interp_elf_ex->e_entry) + load_bias;

}

static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex,

                                 int interpreter_fd,

                                 abi_ulong *interp_load_addr,

                                 char bprm_buf[BPRM_BUF_SIZE])

{

    struct elf_phdr *elf_phdata  =  NULL;

    abi_ulong load_addr, load_bias, loaddr, hiaddr;

    int retval;

    abi_ulong error;

    int i;



    bswap_ehdr(interp_elf_ex);

    

    if ((interp_elf_ex->e_type != ET_EXEC &&

         interp_elf_ex->e_type != ET_DYN) ||

        !elf_check_arch(interp_elf_ex->e_machine)) {

        return ~((abi_ulong)0UL);

    }



    



    if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)

        return ~(abi_ulong)0UL;



    elf_phdata =  (struct elf_phdr *)

        malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);



    if (!elf_phdata)

        return ~((abi_ulong)0UL);



    







    if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {

        free(elf_phdata);

        return ~((abi_ulong)0UL);

    }



    i = interp_elf_ex->e_phnum * sizeof(struct elf_phdr);

    if (interp_elf_ex->e_phoff + i <= BPRM_BUF_SIZE) {

        memcpy(elf_phdata, bprm_buf + interp_elf_ex->e_phoff, i);

    } else {

        retval = pread(interpreter_fd, elf_phdata, i, interp_elf_ex->e_phoff);

        if (retval != i) {

            perror("load_elf_interp");

            exit(-1);

        }

    }

    bswap_phdr(elf_phdata, interp_elf_ex->e_phnum);



    



    loaddr = -1, hiaddr = 0;

    for (i = 0; i < interp_elf_ex->e_phnum; ++i) {

        if (elf_phdata[i].p_type == PT_LOAD) {

            abi_ulong a = elf_phdata[i].p_vaddr;

            if (a < loaddr) {

                loaddr = a;

            }

            a += elf_phdata[i].p_memsz;

            if (a > hiaddr) {

                hiaddr = a;

            }

        }

    }



    load_addr = loaddr;

    if (interp_elf_ex->e_type == ET_DYN) {

        









        load_addr = target_mmap(loaddr, hiaddr - loaddr, PROT_NONE,

                                MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,

                                -1, 0);

        if (load_addr == -1) {

            perror("mmap");

            exit(-1);

        }

    }

    load_bias = load_addr - loaddr;



    for (i = 0; i < interp_elf_ex->e_phnum; i++) {

        struct elf_phdr *eppnt = elf_phdata + i;

        if (eppnt->p_type == PT_LOAD) {

            abi_ulong vaddr, vaddr_po, vaddr_ps, vaddr_ef, vaddr_em;

            int elf_prot = 0;



            if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;

            if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;

            if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;



            vaddr = load_bias + eppnt->p_vaddr;

            vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr);

            vaddr_ps = TARGET_ELF_PAGESTART(vaddr);



            error = target_mmap(vaddr_ps, eppnt->p_filesz + vaddr_po,

                                elf_prot, MAP_PRIVATE | MAP_FIXED,

                                interpreter_fd, eppnt->p_offset - vaddr_po);

            if (error == -1) {

                

                close(interpreter_fd);

                free(elf_phdata);

                return ~((abi_ulong)0UL);

            }



            vaddr_ef = vaddr + eppnt->p_filesz;

            vaddr_em = vaddr + eppnt->p_memsz;



            

            if (vaddr_ef < vaddr_em) {

                zero_bss(vaddr_ef, vaddr_em, elf_prot);

            }

        }

    }



    if (qemu_log_enabled()) {

        load_symbols(interp_elf_ex, interpreter_fd, load_bias);

    }



    close(interpreter_fd);

    free(elf_phdata);



    *interp_load_addr = load_addr;

    return ((abi_ulong) interp_elf_ex->e_entry) + load_bias;

}

static abi_ulong FUNC_0(struct elfhdr * interp_elf_ex,

                                 int interpreter_fd,

                                 abi_ulong *interp_load_addr,

                                 char bprm_buf[BPRM_BUF_SIZE])

{

    struct elf_phdr *VAR_0  =  NULL;

    abi_ulong load_addr, load_bias, loaddr, hiaddr;

    int VAR_1;

    abi_ulong error;

    int VAR_2;



    bswap_ehdr(interp_elf_ex);

    

    if ((interp_elf_ex->e_type != ET_EXEC &&

         interp_elf_ex->e_type != ET_DYN) ||

        !elf_check_arch(interp_elf_ex->e_machine)) {

        return ~((abi_ulong)0UL);

    }



    



    if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)

        return ~(abi_ulong)0UL;



    VAR_0 =  (struct elf_phdr *)

        malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);



    if (!VAR_0)

        return ~((abi_ulong)0UL);



    







    if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {

        free(VAR_0);

        return ~((abi_ulong)0UL);

    }



    VAR_2 = interp_elf_ex->e_phnum * sizeof(struct elf_phdr);

    if (interp_elf_ex->e_phoff + VAR_2 <= BPRM_BUF_SIZE) {

        memcpy(VAR_0, bprm_buf + interp_elf_ex->e_phoff, VAR_2);

    } else {

        VAR_1 = pread(interpreter_fd, VAR_0, VAR_2, interp_elf_ex->e_phoff);

        if (VAR_1 != VAR_2) {

            perror("FUNC_0");

            exit(-1);

        }

    }

    bswap_phdr(VAR_0, interp_elf_ex->e_phnum);



    



    loaddr = -1, hiaddr = 0;

    for (VAR_2 = 0; VAR_2 < interp_elf_ex->e_phnum; ++VAR_2) {

        if (VAR_0[VAR_2].p_type == PT_LOAD) {

            abi_ulong a = VAR_0[VAR_2].p_vaddr;

            if (a < loaddr) {

                loaddr = a;

            }

            a += VAR_0[VAR_2].p_memsz;

            if (a > hiaddr) {

                hiaddr = a;

            }

        }

    }



    load_addr = loaddr;

    if (interp_elf_ex->e_type == ET_DYN) {

        









        load_addr = target_mmap(loaddr, hiaddr - loaddr, PROT_NONE,

                                MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,

                                -1, 0);

        if (load_addr == -1) {

            perror("mmap");

            exit(-1);

        }

    }

    load_bias = load_addr - loaddr;



    for (VAR_2 = 0; VAR_2 < interp_elf_ex->e_phnum; VAR_2++) {

        struct elf_phdr *VAR_3 = VAR_0 + VAR_2;

        if (VAR_3->p_type == PT_LOAD) {

            abi_ulong vaddr, vaddr_po, vaddr_ps, vaddr_ef, vaddr_em;

            int VAR_4 = 0;



            if (VAR_3->p_flags & PF_R) VAR_4 =  PROT_READ;

            if (VAR_3->p_flags & PF_W) VAR_4 |= PROT_WRITE;

            if (VAR_3->p_flags & PF_X) VAR_4 |= PROT_EXEC;



            vaddr = load_bias + VAR_3->p_vaddr;

            vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr);

            vaddr_ps = TARGET_ELF_PAGESTART(vaddr);



            error = target_mmap(vaddr_ps, VAR_3->p_filesz + vaddr_po,

                                VAR_4, MAP_PRIVATE | MAP_FIXED,

                                interpreter_fd, VAR_3->p_offset - vaddr_po);

            if (error == -1) {

                

                close(interpreter_fd);

                free(VAR_0);

                return ~((abi_ulong)0UL);

            }



            vaddr_ef = vaddr + VAR_3->p_filesz;

            vaddr_em = vaddr + VAR_3->p_memsz;



            

            if (vaddr_ef < vaddr_em) {

                zero_bss(vaddr_ef, vaddr_em, VAR_4);

            }

        }

    }



    if (qemu_log_enabled()) {

        load_symbols(interp_elf_ex, interpreter_fd, load_bias);

    }



    close(interpreter_fd);

    free(VAR_0);



    *interp_load_addr = load_addr;

    return ((abi_ulong) interp_elf_ex->e_entry) + load_bias;

}

static abi_ulong FUNC_0(struct elfhdr * interp_elf_ex,
int interpreter_fd,
abi_ulong *interp_load_addr,
char bprm_buf[BPRM_BUF_SIZE])
{ struct elf_phdr *VAR_0  =  NULL; abi_ulong load_addr, load_bias, loaddr, hiaddr; int VAR_1; abi_ulong error; int VAR_2; bswap_ehdr(interp_elf_ex); if ((interp_elf_ex->e_type != ET_EXEC &&
interp_elf_ex->e_type != ET_DYN) ||
!elf_check_arch(interp_elf_ex->e_machine)) { return ~((abi_ulong)0UL); } if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
return ~(abi_ulong)0UL; VAR_0 =  (struct elf_phdr *)
malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum); if (!VAR_0)
return ~((abi_ulong)0UL); if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) { free(VAR_0); return ~((abi_ulong)0UL); } VAR_2 = interp_elf_ex->e_phnum * sizeof(struct elf_phdr); if (interp_elf_ex->e_phoff + VAR_2 <= BPRM_BUF_SIZE) { memcpy(VAR_0, bprm_buf + interp_elf_ex->e_phoff, VAR_2); } else { VAR_1 = pread(interpreter_fd, VAR_0, VAR_2, interp_elf_ex->e_phoff); if (VAR_1 != VAR_2) { perror("FUNC_0"); exit(-1); } } bswap_phdr(VAR_0, interp_elf_ex->e_phnum); loaddr = -1, hiaddr = 0; for (VAR_2 = 0; VAR_2 < interp_elf_ex->e_phnum; ++VAR_2) { if (VAR_0[VAR_2].p_type == PT_LOAD) { abi_ulong a = VAR_0[VAR_2].p_vaddr; if (a < loaddr) { loaddr = a; } a += VAR_0[VAR_2].p_memsz; if (a > hiaddr) { hiaddr = a; } } } load_addr = loaddr; if (interp_elf_ex->e_type == ET_DYN) { load_addr = target_mmap(loaddr, hiaddr - loaddr, PROT_NONE,
MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
-1, 0); if (load_addr == -1) { perror("mmap"); exit(-1); } } load_bias = load_addr - loaddr; for (VAR_2 = 0; VAR_2 < interp_elf_ex->e_phnum; VAR_2++) { struct elf_phdr *VAR_3 = VAR_0 + VAR_2; if (VAR_3->p_type == PT_LOAD) { abi_ulong vaddr, vaddr_po, vaddr_ps, vaddr_ef, vaddr_em; int VAR_4 = 0; if (VAR_3->p_flags & PF_R) VAR_4 =  PROT_READ; if (VAR_3->p_flags & PF_W) VAR_4 |= PROT_WRITE; if (VAR_3->p_flags & PF_X) VAR_4 |= PROT_EXEC; vaddr = load_bias + VAR_3->p_vaddr; vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr); vaddr_ps = TARGET_ELF_PAGESTART(vaddr); error = target_mmap(vaddr_ps, VAR_3->p_filesz + vaddr_po,
VAR_4, MAP_PRIVATE | MAP_FIXED,
interpreter_fd, VAR_3->p_offset - vaddr_po); if (error == -1) { close(interpreter_fd); free(VAR_0); return ~((abi_ulong)0UL); } vaddr_ef = vaddr + VAR_3->p_filesz; vaddr_em = vaddr + VAR_3->p_memsz; if (vaddr_ef < vaddr_em) { zero_bss(vaddr_ef, vaddr_em, VAR_4); } } } if (qemu_log_enabled()) { load_symbols(interp_elf_ex, interpreter_fd, load_bias); } close(interpreter_fd); free(VAR_0); *interp_load_addr = load_addr; return ((abi_ulong) interp_elf_ex->e_entry) + load_bias; }