static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)

{

    int i, shnum, nsyms, sym_idx = 0, str_idx = 0;

    struct elf_shdr *shdr;

    char *strings = NULL;

    struct syminfo *s = NULL;

    struct elf_sym *new_syms, *syms = NULL;



    shnum = hdr->e_shnum;

    i = shnum * sizeof(struct elf_shdr);

    shdr = (struct elf_shdr *)alloca(i);

    if (pread(fd, shdr, i, hdr->e_shoff) != i) {

        return;

    }



    bswap_shdr(shdr, shnum);

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

        if (shdr[i].sh_type == SHT_SYMTAB) {

            sym_idx = i;

            str_idx = shdr[i].sh_link;

            goto found;

        }

    }



    /* There will be no symbol table if the file was stripped.  */

    return;



 found:

    /* Now know where the strtab and symtab are.  Snarf them.  */

    s = g_try_new(struct syminfo, 1);

    if (!s) {

        goto give_up;

    }



    i = shdr[str_idx].sh_size;

    s->disas_strtab = strings = g_try_malloc(i);

    if (!strings || pread(fd, strings, i, shdr[str_idx].sh_offset) != i) {

        goto give_up;

    }



    i = shdr[sym_idx].sh_size;

    syms = g_try_malloc(i);

    if (!syms || pread(fd, syms, i, shdr[sym_idx].sh_offset) != i) {

        goto give_up;

    }



    nsyms = i / sizeof(struct elf_sym);

    for (i = 0; i < nsyms; ) {

        bswap_sym(syms + i);

        /* Throw away entries which we do not need.  */

        if (syms[i].st_shndx == SHN_UNDEF

            || syms[i].st_shndx >= SHN_LORESERVE

            || ELF_ST_TYPE(syms[i].st_info) != STT_FUNC) {

            if (i < --nsyms) {

                syms[i] = syms[nsyms];

            }

        } else {

#if defined(TARGET_ARM) || defined (TARGET_MIPS)

            /* The bottom address bit marks a Thumb or MIPS16 symbol.  */

            syms[i].st_value &= ~(target_ulong)1;

#endif

            syms[i].st_value += load_bias;

            i++;

        }

    }



    /* No "useful" symbol.  */

    if (nsyms == 0) {

        goto give_up;

    }



    /* Attempt to free the storage associated with the local symbols

       that we threw away.  Whether or not this has any effect on the

       memory allocation depends on the malloc implementation and how

       many symbols we managed to discard.  */

    new_syms = g_try_renew(struct elf_sym, syms, nsyms);

    if (new_syms == NULL) {

        goto give_up;

    }

    syms = new_syms;



    qsort(syms, nsyms, sizeof(*syms), symcmp);



    s->disas_num_syms = nsyms;

#if ELF_CLASS == ELFCLASS32

    s->disas_symtab.elf32 = syms;

#else

    s->disas_symtab.elf64 = syms;

#endif

    s->lookup_symbol = lookup_symbolxx;

    s->next = syminfos;

    syminfos = s;



    return;



give_up:

    g_free(s);

    g_free(strings);

    g_free(syms);

}

static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)

{

    int i, shnum, nsyms, sym_idx = 0, str_idx = 0;

    struct elf_shdr *shdr;

    char *strings = NULL;

    struct syminfo *s = NULL;

    struct elf_sym *new_syms, *syms = NULL;



    shnum = hdr->e_shnum;

    i = shnum * sizeof(struct elf_shdr);

    shdr = (struct elf_shdr *)alloca(i);

    if (pread(fd, shdr, i, hdr->e_shoff) != i) {

        return;

    }



    bswap_shdr(shdr, shnum);

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

        if (shdr[i].sh_type == SHT_SYMTAB) {

            sym_idx = i;

            str_idx = shdr[i].sh_link;

            goto found;

        }

    }



    

    return;



 found:

    

    s = g_try_new(struct syminfo, 1);

    if (!s) {

        goto give_up;

    }



    i = shdr[str_idx].sh_size;

    s->disas_strtab = strings = g_try_malloc(i);

    if (!strings || pread(fd, strings, i, shdr[str_idx].sh_offset) != i) {

        goto give_up;

    }



    i = shdr[sym_idx].sh_size;

    syms = g_try_malloc(i);

    if (!syms || pread(fd, syms, i, shdr[sym_idx].sh_offset) != i) {

        goto give_up;

    }



    nsyms = i / sizeof(struct elf_sym);

    for (i = 0; i < nsyms; ) {

        bswap_sym(syms + i);

        

        if (syms[i].st_shndx == SHN_UNDEF

            || syms[i].st_shndx >= SHN_LORESERVE

            || ELF_ST_TYPE(syms[i].st_info) != STT_FUNC) {

            if (i < --nsyms) {

                syms[i] = syms[nsyms];

            }

        } else {

#if defined(TARGET_ARM) || defined (TARGET_MIPS)

            

            syms[i].st_value &= ~(target_ulong)1;

#endif

            syms[i].st_value += load_bias;

            i++;

        }

    }



    

    if (nsyms == 0) {

        goto give_up;

    }



    







    new_syms = g_try_renew(struct elf_sym, syms, nsyms);

    if (new_syms == NULL) {

        goto give_up;

    }

    syms = new_syms;



    qsort(syms, nsyms, sizeof(*syms), symcmp);



    s->disas_num_syms = nsyms;

#if ELF_CLASS == ELFCLASS32

    s->disas_symtab.elf32 = syms;

#else

    s->disas_symtab.elf64 = syms;

#endif

    s->lookup_symbol = lookup_symbolxx;

    s->next = syminfos;

    syminfos = s;



    return;



give_up:

    g_free(s);

    g_free(strings);

    g_free(syms);

}

    i = shdr[str_idx].sh_size;     s->disas_strtab = strings = g_try_malloc(i);     if (!strings || pread(fd, strings, i, shdr[str_idx].sh_offset) != i) {     i = shdr[sym_idx].sh_size;     syms = g_try_malloc(i);     if (!syms || pread(fd, syms, i, shdr[sym_idx].sh_offset) != i) {     nsyms = i / sizeof(struct elf_sym);
static void FUNC_0(struct elfhdr *VAR_0, int VAR_1, abi_ulong VAR_2)

{

    int VAR_3, VAR_4, VAR_5, VAR_6 = 0, VAR_7 = 0;

    struct elf_shdr *VAR_8;

    char *VAR_9 = NULL;

    struct syminfo *VAR_10 = NULL;

    struct elf_sym *VAR_11, *VAR_12 = NULL;



    VAR_4 = VAR_0->e_shnum;

    VAR_3 = VAR_4 * sizeof(struct elf_shdr);

    VAR_8 = (struct elf_shdr *)alloca(VAR_3);

    if (pread(VAR_1, VAR_8, VAR_3, VAR_0->e_shoff) != VAR_3) {

        return;

    }



    bswap_shdr(VAR_8, VAR_4);

    for (VAR_3 = 0; VAR_3 < VAR_4; ++VAR_3) {

        if (VAR_8[VAR_3].sh_type == SHT_SYMTAB) {

            VAR_6 = VAR_3;

            VAR_7 = VAR_8[VAR_3].sh_link;

            goto found;

        }

    }



    

    return;



 found:

    

    VAR_10 = g_try_new(struct syminfo, 1);

    if (!VAR_10) {

        goto give_up;

    }



    VAR_3 = VAR_8[VAR_7].sh_size;

    VAR_10->disas_strtab = VAR_9 = g_try_malloc(VAR_3);

    if (!VAR_9 || pread(VAR_1, VAR_9, VAR_3, VAR_8[VAR_7].sh_offset) != VAR_3) {

        goto give_up;

    }



    VAR_3 = VAR_8[VAR_6].sh_size;

    VAR_12 = g_try_malloc(VAR_3);

    if (!VAR_12 || pread(VAR_1, VAR_12, VAR_3, VAR_8[VAR_6].sh_offset) != VAR_3) {

        goto give_up;

    }



    VAR_5 = VAR_3 / sizeof(struct elf_sym);

    for (VAR_3 = 0; VAR_3 < VAR_5; ) {

        bswap_sym(VAR_12 + VAR_3);

        

        if (VAR_12[VAR_3].st_shndx == SHN_UNDEF

            || VAR_12[VAR_3].st_shndx >= SHN_LORESERVE

            || ELF_ST_TYPE(VAR_12[VAR_3].st_info) != STT_FUNC) {

            if (VAR_3 < --VAR_5) {

                VAR_12[VAR_3] = VAR_12[VAR_5];

            }

        } else {

#if defined(TARGET_ARM) || defined (TARGET_MIPS)

            

            VAR_12[VAR_3].st_value &= ~(target_ulong)1;

#endif

            VAR_12[VAR_3].st_value += VAR_2;

            VAR_3++;

        }

    }



    

    if (VAR_5 == 0) {

        goto give_up;

    }



    







    VAR_11 = g_try_renew(struct elf_sym, VAR_12, VAR_5);

    if (VAR_11 == NULL) {

        goto give_up;

    }

    VAR_12 = VAR_11;



    qsort(VAR_12, VAR_5, sizeof(*VAR_12), symcmp);



    VAR_10->disas_num_syms = VAR_5;

#if ELF_CLASS == ELFCLASS32

    VAR_10->disas_symtab.elf32 = VAR_12;

#else

    VAR_10->disas_symtab.elf64 = VAR_12;

#endif

    VAR_10->lookup_symbol = lookup_symbolxx;

    VAR_10->next = syminfos;

    syminfos = VAR_10;



    return;



give_up:

    g_free(VAR_10);

    g_free(VAR_9);

    g_free(VAR_12);

}

static void FUNC_0(struct elfhdr *VAR_0, int VAR_1, abi_ulong VAR_2)
{ int VAR_3, VAR_4, VAR_5, VAR_6 = 0, VAR_7 = 0; struct elf_shdr *VAR_8; char *VAR_9 = NULL; struct syminfo *VAR_10 = NULL; struct elf_sym *VAR_11, *VAR_12 = NULL; VAR_4 = VAR_0->e_shnum; VAR_3 = VAR_4 * sizeof(struct elf_shdr); VAR_8 = (struct elf_shdr *)alloca(VAR_3); if (pread(VAR_1, VAR_8, VAR_3, VAR_0->e_shoff) != VAR_3) { return; } bswap_shdr(VAR_8, VAR_4); for (VAR_3 = 0; VAR_3 < VAR_4; ++VAR_3) { if (VAR_8[VAR_3].sh_type == SHT_SYMTAB) { VAR_6 = VAR_3; VAR_7 = VAR_8[VAR_3].sh_link; goto found; } } return; found:
VAR_10 = g_try_new(struct syminfo, 1); if (!VAR_10) { goto give_up; } VAR_3 = VAR_8[VAR_7].sh_size; VAR_10->disas_strtab = VAR_9 = g_try_malloc(VAR_3); if (!VAR_9 || pread(VAR_1, VAR_9, VAR_3, VAR_8[VAR_7].sh_offset) != VAR_3) { goto give_up; } VAR_3 = VAR_8[VAR_6].sh_size; VAR_12 = g_try_malloc(VAR_3); if (!VAR_12 || pread(VAR_1, VAR_12, VAR_3, VAR_8[VAR_6].sh_offset) != VAR_3) { goto give_up; } VAR_5 = VAR_3 / sizeof(struct elf_sym); for (VAR_3 = 0; VAR_3 < VAR_5; ) { bswap_sym(VAR_12 + VAR_3); if (VAR_12[VAR_3].st_shndx == SHN_UNDEF
|| VAR_12[VAR_3].st_shndx >= SHN_LORESERVE
|| ELF_ST_TYPE(VAR_12[VAR_3].st_info) != STT_FUNC) { if (VAR_3 < --VAR_5) { VAR_12[VAR_3] = VAR_12[VAR_5]; } } else { #if defined(TARGET_ARM) || defined (TARGET_MIPS)
VAR_12[VAR_3].st_value &= ~(target_ulong)1; #endif
VAR_12[VAR_3].st_value += VAR_2; VAR_3++; } } if (VAR_5 == 0) { goto give_up; } VAR_11 = g_try_renew(struct elf_sym, VAR_12, VAR_5); if (VAR_11 == NULL) { goto give_up; } VAR_12 = VAR_11; qsort(VAR_12, VAR_5, sizeof(*VAR_12), symcmp); VAR_10->disas_num_syms = VAR_5; #if ELF_CLASS == ELFCLASS32
VAR_10->disas_symtab.elf32 = VAR_12; #else
VAR_10->disas_symtab.elf64 = VAR_12; #endif
VAR_10->lookup_symbol = lookup_symbolxx; VAR_10->next = syminfos; syminfos = VAR_10; return; give_up:
g_free(VAR_10); g_free(VAR_9); g_free(VAR_12); }