static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,

                                   struct elfhdr *exec,

                                   struct image_info *info,

                                   struct image_info *interp_info)

{

    abi_ulong sp;

    abi_ulong u_argc, u_argv, u_envp, u_auxv;

    int size;

    int i;

    abi_ulong u_rand_bytes;

    uint8_t k_rand_bytes[16];

    abi_ulong u_platform;

    const char *k_platform;

    const int n = sizeof(elf_addr_t);



    sp = p;



#ifdef CONFIG_USE_FDPIC

    /* Needs to be before we load the env/argc/... */

    if (elf_is_fdpic(exec)) {

        /* Need 4 byte alignment for these structs */

        sp &= ~3;

        sp = loader_build_fdpic_loadmap(info, sp);

        info->other_info = interp_info;

        if (interp_info) {

            interp_info->other_info = info;

            sp = loader_build_fdpic_loadmap(interp_info, sp);

        }

    }

#endif



    u_platform = 0;

    k_platform = ELF_PLATFORM;

    if (k_platform) {

        size_t len = strlen(k_platform) + 1;

        if (STACK_GROWS_DOWN) {

            sp -= (len + n - 1) & ~(n - 1);

            u_platform = sp;

            /* FIXME - check return value of memcpy_to_target() for failure */

            memcpy_to_target(sp, k_platform, len);

        } else {

            memcpy_to_target(sp, k_platform, len);

            u_platform = sp;

            sp += len + 1;

        }

    }



    /* Provide 16 byte alignment for the PRNG, and basic alignment for

     * the argv and envp pointers.

     */

    if (STACK_GROWS_DOWN) {

        sp = QEMU_ALIGN_DOWN(sp, 16);

    } else {

        sp = QEMU_ALIGN_UP(sp, 16);

    }



    /*

     * Generate 16 random bytes for userspace PRNG seeding (not

     * cryptically secure but it's not the aim of QEMU).

     */

    for (i = 0; i < 16; i++) {

        k_rand_bytes[i] = rand();

    }

    if (STACK_GROWS_DOWN) {

        sp -= 16;

        u_rand_bytes = sp;

        /* FIXME - check return value of memcpy_to_target() for failure */

        memcpy_to_target(sp, k_rand_bytes, 16);

    } else {

        memcpy_to_target(sp, k_rand_bytes, 16);

        u_rand_bytes = sp;

        sp += 16;

    }



    size = (DLINFO_ITEMS + 1) * 2;

    if (k_platform)

        size += 2;

#ifdef DLINFO_ARCH_ITEMS

    size += DLINFO_ARCH_ITEMS * 2;

#endif

#ifdef ELF_HWCAP2

    size += 2;

#endif

    size += envc + argc + 2;

    size += 1;  /* argc itself */

    size *= n;



    /* Allocate space and finalize stack alignment for entry now.  */

    if (STACK_GROWS_DOWN) {

        u_argc = QEMU_ALIGN_DOWN(sp - size, STACK_ALIGNMENT);

        sp = u_argc;

    } else {

        u_argc = sp;

        sp = QEMU_ALIGN_UP(sp + size, STACK_ALIGNMENT);

    }



    u_argv = u_argc + n;

    u_envp = u_argv + (argc + 1) * n;

    u_auxv = u_envp + (envc + 1) * n;

    info->saved_auxv = u_auxv;

    info->arg_start = u_argv;

    info->arg_end = u_argv + argc * n;



    /* This is correct because Linux defines

     * elf_addr_t as Elf32_Off / Elf64_Off

     */

#define NEW_AUX_ENT(id, val) do {               \

        put_user_ual(id, u_auxv);  u_auxv += n; \

        put_user_ual(val, u_auxv); u_auxv += n; \

    } while(0)



    /* There must be exactly DLINFO_ITEMS entries here.  */

#ifdef ARCH_DLINFO

    /*

     * ARCH_DLINFO must come first so platform specific code can enforce

     * special alignment requirements on the AUXV if necessary (eg. PPC).

     */

    ARCH_DLINFO;

#endif

    NEW_AUX_ENT(AT_PHDR, (abi_ulong)(info->load_addr + exec->e_phoff));

    NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr)));

    NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum));

    NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(MAX(TARGET_PAGE_SIZE, getpagesize())));

    NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_info ? interp_info->load_addr : 0));

    NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0);

    NEW_AUX_ENT(AT_ENTRY, info->entry);

    NEW_AUX_ENT(AT_UID, (abi_ulong) getuid());

    NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid());

    NEW_AUX_ENT(AT_GID, (abi_ulong) getgid());

    NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());

    NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);

    NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));

    NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);



#ifdef ELF_HWCAP2

    NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);

#endif



    if (u_platform) {

        NEW_AUX_ENT(AT_PLATFORM, u_platform);

    }

    NEW_AUX_ENT (AT_NULL, 0);

#undef NEW_AUX_ENT



    info->auxv_len = u_argv - info->saved_auxv;



    put_user_ual(argc, u_argc);



    p = info->arg_strings;

    for (i = 0; i < argc; ++i) {

        put_user_ual(p, u_argv);

        u_argv += n;

        p += target_strlen(p) + 1;

    }

    put_user_ual(0, u_argv);



    p = info->env_strings;

    for (i = 0; i < envc; ++i) {

        put_user_ual(p, u_envp);

        u_envp += n;

        p += target_strlen(p) + 1;

    }

    put_user_ual(0, u_envp);



    return sp;

}

static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,

                                   struct elfhdr *exec,

                                   struct image_info *info,

                                   struct image_info *interp_info)

{

    abi_ulong sp;

    abi_ulong u_argc, u_argv, u_envp, u_auxv;

    int size;

    int i;

    abi_ulong u_rand_bytes;

    uint8_t k_rand_bytes[16];

    abi_ulong u_platform;

    const char *k_platform;

    const int n = sizeof(elf_addr_t);



    sp = p;



#ifdef CONFIG_USE_FDPIC

    

    if (elf_is_fdpic(exec)) {

        

        sp &= ~3;

        sp = loader_build_fdpic_loadmap(info, sp);

        info->other_info = interp_info;

        if (interp_info) {

            interp_info->other_info = info;

            sp = loader_build_fdpic_loadmap(interp_info, sp);

        }

    }

#endif



    u_platform = 0;

    k_platform = ELF_PLATFORM;

    if (k_platform) {

        size_t len = strlen(k_platform) + 1;

        if (STACK_GROWS_DOWN) {

            sp -= (len + n - 1) & ~(n - 1);

            u_platform = sp;

            

            memcpy_to_target(sp, k_platform, len);

        } else {

            memcpy_to_target(sp, k_platform, len);

            u_platform = sp;

            sp += len + 1;

        }

    }



    





    if (STACK_GROWS_DOWN) {

        sp = QEMU_ALIGN_DOWN(sp, 16);

    } else {

        sp = QEMU_ALIGN_UP(sp, 16);

    }



    







    for (i = 0; i < 16; i++) {

        k_rand_bytes[i] = rand();

    }

    if (STACK_GROWS_DOWN) {

        sp -= 16;

        u_rand_bytes = sp;

        

        memcpy_to_target(sp, k_rand_bytes, 16);

    } else {

        memcpy_to_target(sp, k_rand_bytes, 16);

        u_rand_bytes = sp;

        sp += 16;

    }



    size = (DLINFO_ITEMS + 1) * 2;

    if (k_platform)

        size += 2;

#ifdef DLINFO_ARCH_ITEMS

    size += DLINFO_ARCH_ITEMS * 2;

#endif

#ifdef ELF_HWCAP2

    size += 2;

#endif

    size += envc + argc + 2;

    size += 1;  

    size *= n;



    

    if (STACK_GROWS_DOWN) {

        u_argc = QEMU_ALIGN_DOWN(sp - size, STACK_ALIGNMENT);

        sp = u_argc;

    } else {

        u_argc = sp;

        sp = QEMU_ALIGN_UP(sp + size, STACK_ALIGNMENT);

    }



    u_argv = u_argc + n;

    u_envp = u_argv + (argc + 1) * n;

    u_auxv = u_envp + (envc + 1) * n;

    info->saved_auxv = u_auxv;

    info->arg_start = u_argv;

    info->arg_end = u_argv + argc * n;



    





#define NEW_AUX_ENT(id, val) do {               \

        put_user_ual(id, u_auxv);  u_auxv += n; \

        put_user_ual(val, u_auxv); u_auxv += n; \

    } while(0)



    

#ifdef ARCH_DLINFO

    







    ARCH_DLINFO;

#endif

    NEW_AUX_ENT(AT_PHDR, (abi_ulong)(info->load_addr + exec->e_phoff));

    NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr)));

    NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum));

    NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(MAX(TARGET_PAGE_SIZE, getpagesize())));

    NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_info ? interp_info->load_addr : 0));

    NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0);

    NEW_AUX_ENT(AT_ENTRY, info->entry);

    NEW_AUX_ENT(AT_UID, (abi_ulong) getuid());

    NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid());

    NEW_AUX_ENT(AT_GID, (abi_ulong) getgid());

    NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());

    NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);

    NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));

    NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);



#ifdef ELF_HWCAP2

    NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);

#endif



    if (u_platform) {

        NEW_AUX_ENT(AT_PLATFORM, u_platform);

    }

    NEW_AUX_ENT (AT_NULL, 0);

#undef NEW_AUX_ENT



    info->auxv_len = u_argv - info->saved_auxv;



    put_user_ual(argc, u_argc);



    p = info->arg_strings;

    for (i = 0; i < argc; ++i) {

        put_user_ual(p, u_argv);

        u_argv += n;

        p += target_strlen(p) + 1;

    }

    put_user_ual(0, u_argv);



    p = info->env_strings;

    for (i = 0; i < envc; ++i) {

        put_user_ual(p, u_envp);

        u_envp += n;

        p += target_strlen(p) + 1;

    }

    put_user_ual(0, u_envp);



    return sp;

}

    info->auxv_len = u_argv - info->saved_auxv;
static abi_ulong FUNC_0(abi_ulong p, int argc, int envc,

                                   struct elfhdr *exec,

                                   struct image_info *info,

                                   struct image_info *interp_info)

{

    abi_ulong sp;

    abi_ulong u_argc, u_argv, u_envp, u_auxv;

    int VAR_0;

    int VAR_1;

    abi_ulong u_rand_bytes;

    uint8_t k_rand_bytes[16];

    abi_ulong u_platform;

    const char *VAR_2;

    const int VAR_3 = sizeof(elf_addr_t);



    sp = p;



#ifdef CONFIG_USE_FDPIC

    

    if (elf_is_fdpic(exec)) {

        

        sp &= ~3;

        sp = loader_build_fdpic_loadmap(info, sp);

        info->other_info = interp_info;

        if (interp_info) {

            interp_info->other_info = info;

            sp = loader_build_fdpic_loadmap(interp_info, sp);

        }

    }

#endif



    u_platform = 0;

    VAR_2 = ELF_PLATFORM;

    if (VAR_2) {

        size_t len = strlen(VAR_2) + 1;

        if (STACK_GROWS_DOWN) {

            sp -= (len + VAR_3 - 1) & ~(VAR_3 - 1);

            u_platform = sp;

            

            memcpy_to_target(sp, VAR_2, len);

        } else {

            memcpy_to_target(sp, VAR_2, len);

            u_platform = sp;

            sp += len + 1;

        }

    }



    





    if (STACK_GROWS_DOWN) {

        sp = QEMU_ALIGN_DOWN(sp, 16);

    } else {

        sp = QEMU_ALIGN_UP(sp, 16);

    }



    







    for (VAR_1 = 0; VAR_1 < 16; VAR_1++) {

        k_rand_bytes[VAR_1] = rand();

    }

    if (STACK_GROWS_DOWN) {

        sp -= 16;

        u_rand_bytes = sp;

        

        memcpy_to_target(sp, k_rand_bytes, 16);

    } else {

        memcpy_to_target(sp, k_rand_bytes, 16);

        u_rand_bytes = sp;

        sp += 16;

    }



    VAR_0 = (DLINFO_ITEMS + 1) * 2;

    if (VAR_2)

        VAR_0 += 2;

#ifdef DLINFO_ARCH_ITEMS

    VAR_0 += DLINFO_ARCH_ITEMS * 2;

#endif

#ifdef ELF_HWCAP2

    VAR_0 += 2;

#endif

    VAR_0 += envc + argc + 2;

    VAR_0 += 1;  

    VAR_0 *= VAR_3;



    

    if (STACK_GROWS_DOWN) {

        u_argc = QEMU_ALIGN_DOWN(sp - VAR_0, STACK_ALIGNMENT);

        sp = u_argc;

    } else {

        u_argc = sp;

        sp = QEMU_ALIGN_UP(sp + VAR_0, STACK_ALIGNMENT);

    }



    u_argv = u_argc + VAR_3;

    u_envp = u_argv + (argc + 1) * VAR_3;

    u_auxv = u_envp + (envc + 1) * VAR_3;

    info->saved_auxv = u_auxv;

    info->arg_start = u_argv;

    info->arg_end = u_argv + argc * VAR_3;



    





#define NEW_AUX_ENT(id, val) do {               \

        put_user_ual(id, u_auxv);  u_auxv += VAR_3; \

        put_user_ual(val, u_auxv); u_auxv += VAR_3; \

    } while(0)



    

#ifdef ARCH_DLINFO

    







    ARCH_DLINFO;

#endif

    NEW_AUX_ENT(AT_PHDR, (abi_ulong)(info->load_addr + exec->e_phoff));

    NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr)));

    NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum));

    NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(MAX(TARGET_PAGE_SIZE, getpagesize())));

    NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_info ? interp_info->load_addr : 0));

    NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0);

    NEW_AUX_ENT(AT_ENTRY, info->entry);

    NEW_AUX_ENT(AT_UID, (abi_ulong) getuid());

    NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid());

    NEW_AUX_ENT(AT_GID, (abi_ulong) getgid());

    NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());

    NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);

    NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));

    NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);



#ifdef ELF_HWCAP2

    NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);

#endif



    if (u_platform) {

        NEW_AUX_ENT(AT_PLATFORM, u_platform);

    }

    NEW_AUX_ENT (AT_NULL, 0);

#undef NEW_AUX_ENT



    info->auxv_len = u_argv - info->saved_auxv;



    put_user_ual(argc, u_argc);



    p = info->arg_strings;

    for (VAR_1 = 0; VAR_1 < argc; ++VAR_1) {

        put_user_ual(p, u_argv);

        u_argv += VAR_3;

        p += target_strlen(p) + 1;

    }

    put_user_ual(0, u_argv);



    p = info->env_strings;

    for (VAR_1 = 0; VAR_1 < envc; ++VAR_1) {

        put_user_ual(p, u_envp);

        u_envp += VAR_3;

        p += target_strlen(p) + 1;

    }

    put_user_ual(0, u_envp);



    return sp;

}

static abi_ulong FUNC_0(abi_ulong p, int argc, int envc,
struct elfhdr *exec,
struct image_info *info,
struct image_info *interp_info)
{ abi_ulong sp; abi_ulong u_argc, u_argv, u_envp, u_auxv; int VAR_0; int VAR_1; abi_ulong u_rand_bytes; uint8_t k_rand_bytes[16]; abi_ulong u_platform; const char *VAR_2; const int VAR_3 = sizeof(elf_addr_t); sp = p; #ifdef CONFIG_USE_FDPIC
if (elf_is_fdpic(exec)) { sp &= ~3; sp = loader_build_fdpic_loadmap(info, sp); info->other_info = interp_info; if (interp_info) { interp_info->other_info = info; sp = loader_build_fdpic_loadmap(interp_info, sp); } } #endif
u_platform = 0; VAR_2 = ELF_PLATFORM; if (VAR_2) { size_t len = strlen(VAR_2) + 1; if (STACK_GROWS_DOWN) { sp -= (len + VAR_3 - 1) & ~(VAR_3 - 1); u_platform = sp; memcpy_to_target(sp, VAR_2, len); } else { memcpy_to_target(sp, VAR_2, len); u_platform = sp; sp += len + 1; } } if (STACK_GROWS_DOWN) { sp = QEMU_ALIGN_DOWN(sp, 16); } else { sp = QEMU_ALIGN_UP(sp, 16); } for (VAR_1 = 0; VAR_1 < 16; VAR_1++) { k_rand_bytes[VAR_1] = rand(); } if (STACK_GROWS_DOWN) { sp -= 16; u_rand_bytes = sp; memcpy_to_target(sp, k_rand_bytes, 16); } else { memcpy_to_target(sp, k_rand_bytes, 16); u_rand_bytes = sp; sp += 16; } VAR_0 = (DLINFO_ITEMS + 1) * 2; if (VAR_2)
VAR_0 += 2; #ifdef DLINFO_ARCH_ITEMS
VAR_0 += DLINFO_ARCH_ITEMS * 2; #endif
#ifdef ELF_HWCAP2
VAR_0 += 2; #endif
VAR_0 += envc + argc + 2; VAR_0 += 1; VAR_0 *= VAR_3; if (STACK_GROWS_DOWN) { u_argc = QEMU_ALIGN_DOWN(sp - VAR_0, STACK_ALIGNMENT); sp = u_argc; } else { u_argc = sp; sp = QEMU_ALIGN_UP(sp + VAR_0, STACK_ALIGNMENT); } u_argv = u_argc + VAR_3; u_envp = u_argv + (argc + 1) * VAR_3; u_auxv = u_envp + (envc + 1) * VAR_3; info->saved_auxv = u_auxv; info->arg_start = u_argv; info->arg_end = u_argv + argc * VAR_3; #define NEW_AUX_ENT(id, val) do {               \ put_user_ual(id, u_auxv);  u_auxv += VAR_3; \ put_user_ual(val, u_auxv); u_auxv += VAR_3; \ } while(0) #ifdef ARCH_DLINFO
ARCH_DLINFO; #endif
NEW_AUX_ENT(AT_PHDR, (abi_ulong)(info->load_addr + exec->e_phoff)); NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr))); NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum)); NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(MAX(TARGET_PAGE_SIZE, getpagesize()))); NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_info ? interp_info->load_addr : 0)); NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0); NEW_AUX_ENT(AT_ENTRY, info->entry); NEW_AUX_ENT(AT_UID, (abi_ulong) getuid()); NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid()); NEW_AUX_ENT(AT_GID, (abi_ulong) getgid()); NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid()); NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP); NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK)); NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes); #ifdef ELF_HWCAP2
NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2); #endif
if (u_platform) { NEW_AUX_ENT(AT_PLATFORM, u_platform); } NEW_AUX_ENT (AT_NULL, 0); #undef NEW_AUX_ENT
info->auxv_len = u_argv - info->saved_auxv; put_user_ual(argc, u_argc); p = info->arg_strings; for (VAR_1 = 0; VAR_1 < argc; ++VAR_1) { put_user_ual(p, u_argv); u_argv += VAR_3; p += target_strlen(p) + 1; } put_user_ual(0, u_argv); p = info->env_strings; for (VAR_1 = 0; VAR_1 < envc; ++VAR_1) { put_user_ual(p, u_envp); u_envp += VAR_3; p += target_strlen(p) + 1; } put_user_ual(0, u_envp); return sp; }