Commit 0774bed18046c4f01a2cd64185d57b57fc06fb2f
1 parent
46d38ba8
Fix 64 bit ELF file symbol lookup
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3046 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
24 additions
and
1 deletions
linux-user/elfload.c
| ... | ... | @@ -893,6 +893,11 @@ static void load_symbols(struct elfhdr *hdr, int fd) |
| 893 | 893 | struct elf_shdr sechdr, symtab, strtab; |
| 894 | 894 | char *strings; |
| 895 | 895 | struct syminfo *s; |
| 896 | +#if (ELF_CLASS == ELFCLASS64) | |
| 897 | + // Disas uses 32 bit symbols | |
| 898 | + struct elf32_sym *syms32 = NULL; | |
| 899 | + struct elf_sym *sym; | |
| 900 | +#endif | |
| 896 | 901 | |
| 897 | 902 | lseek(fd, hdr->e_shoff, SEEK_SET); |
| 898 | 903 | for (i = 0; i < hdr->e_shnum; i++) { |
| ... | ... | @@ -920,6 +925,10 @@ static void load_symbols(struct elfhdr *hdr, int fd) |
| 920 | 925 | /* Now know where the strtab and symtab are. Snarf them. */ |
| 921 | 926 | s = malloc(sizeof(*s)); |
| 922 | 927 | s->disas_symtab = malloc(symtab.sh_size); |
| 928 | +#if (ELF_CLASS == ELFCLASS64) | |
| 929 | + syms32 = malloc(symtab.sh_size / sizeof(struct elf_sym) | |
| 930 | + * sizeof(struct elf32_sym)); | |
| 931 | +#endif | |
| 923 | 932 | s->disas_strtab = strings = malloc(strtab.sh_size); |
| 924 | 933 | if (!s->disas_symtab || !s->disas_strtab) |
| 925 | 934 | return; |
| ... | ... | @@ -928,11 +937,25 @@ static void load_symbols(struct elfhdr *hdr, int fd) |
| 928 | 937 | if (read(fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size) |
| 929 | 938 | return; |
| 930 | 939 | |
| 940 | + for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++) { | |
| 931 | 941 | #ifdef BSWAP_NEEDED |
| 932 | - for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++) | |
| 933 | 942 | bswap_sym(s->disas_symtab + sizeof(struct elf_sym)*i); |
| 934 | 943 | #endif |
| 944 | +#if (ELF_CLASS == ELFCLASS64) | |
| 945 | + sym = s->disas_symtab + sizeof(struct elf_sym)*i; | |
| 946 | + syms32[i].st_name = sym->st_name; | |
| 947 | + syms32[i].st_info = sym->st_info; | |
| 948 | + syms32[i].st_other = sym->st_other; | |
| 949 | + syms32[i].st_shndx = sym->st_shndx; | |
| 950 | + syms32[i].st_value = sym->st_value & 0xffffffff; | |
| 951 | + syms32[i].st_size = sym->st_size & 0xffffffff; | |
| 952 | +#endif | |
| 953 | + } | |
| 935 | 954 | |
| 955 | +#if (ELF_CLASS == ELFCLASS64) | |
| 956 | + free(s->disas_symtab); | |
| 957 | + s->disas_symtab = syms32; | |
| 958 | +#endif | |
| 936 | 959 | lseek(fd, strtab.sh_offset, SEEK_SET); |
| 937 | 960 | if (read(fd, strings, strtab.sh_size) != strtab.sh_size) |
| 938 | 961 | return; | ... | ... |