summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2007-07-05 13:23:29 +0000
committerblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2007-07-05 13:23:29 +0000
commit0774bed18046c4f01a2cd64185d57b57fc06fb2f (patch)
treed21ad50675caf7bfbf1982278a99d8d067a34c4d
parent46d38ba89d37561a6fbf58a7ff567d0931b7c602 (diff)
downloadqemu-0774bed18046c4f01a2cd64185d57b57fc06fb2f.tar.gz
Fix 64 bit ELF file symbol lookup
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3046 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--linux-user/elfload.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index f844eff508..2a7bd703c5 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -893,6 +893,11 @@ static void load_symbols(struct elfhdr *hdr, int fd)
struct elf_shdr sechdr, symtab, strtab;
char *strings;
struct syminfo *s;
+#if (ELF_CLASS == ELFCLASS64)
+ // Disas uses 32 bit symbols
+ struct elf32_sym *syms32 = NULL;
+ struct elf_sym *sym;
+#endif
lseek(fd, hdr->e_shoff, SEEK_SET);
for (i = 0; i < hdr->e_shnum; i++) {
@@ -920,6 +925,10 @@ static void load_symbols(struct elfhdr *hdr, int fd)
/* Now know where the strtab and symtab are. Snarf them. */
s = malloc(sizeof(*s));
s->disas_symtab = malloc(symtab.sh_size);
+#if (ELF_CLASS == ELFCLASS64)
+ syms32 = malloc(symtab.sh_size / sizeof(struct elf_sym)
+ * sizeof(struct elf32_sym));
+#endif
s->disas_strtab = strings = malloc(strtab.sh_size);
if (!s->disas_symtab || !s->disas_strtab)
return;
@@ -928,11 +937,25 @@ static void load_symbols(struct elfhdr *hdr, int fd)
if (read(fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size)
return;
+ for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++) {
#ifdef BSWAP_NEEDED
- for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++)
bswap_sym(s->disas_symtab + sizeof(struct elf_sym)*i);
#endif
+#if (ELF_CLASS == ELFCLASS64)
+ sym = s->disas_symtab + sizeof(struct elf_sym)*i;
+ syms32[i].st_name = sym->st_name;
+ syms32[i].st_info = sym->st_info;
+ syms32[i].st_other = sym->st_other;
+ syms32[i].st_shndx = sym->st_shndx;
+ syms32[i].st_value = sym->st_value & 0xffffffff;
+ syms32[i].st_size = sym->st_size & 0xffffffff;
+#endif
+ }
+#if (ELF_CLASS == ELFCLASS64)
+ free(s->disas_symtab);
+ s->disas_symtab = syms32;
+#endif
lseek(fd, strtab.sh_offset, SEEK_SET);
if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
return;