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; |