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,6 +893,11 @@ static void load_symbols(struct elfhdr *hdr, int fd) | ||
| 893 | struct elf_shdr sechdr, symtab, strtab; | 893 | struct elf_shdr sechdr, symtab, strtab; |
| 894 | char *strings; | 894 | char *strings; |
| 895 | struct syminfo *s; | 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 | lseek(fd, hdr->e_shoff, SEEK_SET); | 902 | lseek(fd, hdr->e_shoff, SEEK_SET); |
| 898 | for (i = 0; i < hdr->e_shnum; i++) { | 903 | for (i = 0; i < hdr->e_shnum; i++) { |
| @@ -920,6 +925,10 @@ static void load_symbols(struct elfhdr *hdr, int fd) | @@ -920,6 +925,10 @@ static void load_symbols(struct elfhdr *hdr, int fd) | ||
| 920 | /* Now know where the strtab and symtab are. Snarf them. */ | 925 | /* Now know where the strtab and symtab are. Snarf them. */ |
| 921 | s = malloc(sizeof(*s)); | 926 | s = malloc(sizeof(*s)); |
| 922 | s->disas_symtab = malloc(symtab.sh_size); | 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 | s->disas_strtab = strings = malloc(strtab.sh_size); | 932 | s->disas_strtab = strings = malloc(strtab.sh_size); |
| 924 | if (!s->disas_symtab || !s->disas_strtab) | 933 | if (!s->disas_symtab || !s->disas_strtab) |
| 925 | return; | 934 | return; |
| @@ -928,11 +937,25 @@ static void load_symbols(struct elfhdr *hdr, int fd) | @@ -928,11 +937,25 @@ static void load_symbols(struct elfhdr *hdr, int fd) | ||
| 928 | if (read(fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size) | 937 | if (read(fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size) |
| 929 | return; | 938 | return; |
| 930 | 939 | ||
| 940 | + for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++) { | ||
| 931 | #ifdef BSWAP_NEEDED | 941 | #ifdef BSWAP_NEEDED |
| 932 | - for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++) | ||
| 933 | bswap_sym(s->disas_symtab + sizeof(struct elf_sym)*i); | 942 | bswap_sym(s->disas_symtab + sizeof(struct elf_sym)*i); |
| 934 | #endif | 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 | lseek(fd, strtab.sh_offset, SEEK_SET); | 959 | lseek(fd, strtab.sh_offset, SEEK_SET); |
| 937 | if (read(fd, strings, strtab.sh_size) != strtab.sh_size) | 960 | if (read(fd, strings, strtab.sh_size) != strtab.sh_size) |
| 938 | return; | 961 | return; |