Commit 689f936f7ea68c0539f73246d582e5c85ae50f12

Authored by bellard
1 parent 6977fbfd

symbol fix


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@103 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 80 additions and 3 deletions
1   -#ifndef _ELF_H
2   -#define _ELF_H
  1 +#ifndef _QEMU_ELF_H
  2 +#define _QEMU_ELF_H
3 3  
4 4 #include <inttypes.h>
5 5  
... ... @@ -996,6 +996,7 @@ typedef struct elf64_note {
996 996 #define elf_phdr elf32_phdr
997 997 #define elf_note elf32_note
998 998 #define elf_shdr elf32_shdr
  999 +#define elf_sym elf32_sym
999 1000  
1000 1001 #ifdef ELF_USES_RELOCA
1001 1002 # define ELF_RELOC Elf32_Rela
... ... @@ -1009,6 +1010,7 @@ typedef struct elf64_note {
1009 1010 #define elf_phdr elf64_phdr
1010 1011 #define elf_note elf64_note
1011 1012 #define elf_shdr elf64_shdr
  1013 +#define elf_sym elf64_sym
1012 1014  
1013 1015 #ifdef ELF_USES_RELOCA
1014 1016 # define ELF_RELOC Elf64_Rela
... ... @@ -1029,4 +1031,4 @@ typedef struct elf64_note {
1029 1031 #endif
1030 1032  
1031 1033  
1032   -#endif /* _ELF_H */
  1034 +#endif /* _QEMU_ELF_H */
... ...
linux-user/elfload.c
... ... @@ -11,6 +11,7 @@
11 11 #include <string.h>
12 12  
13 13 #include "qemu.h"
  14 +#include "disas.h"
14 15  
15 16 #ifdef TARGET_I386
16 17  
... ... @@ -195,6 +196,28 @@ static void bswap_phdr(Elf32_Phdr *phdr)
195 196 bswap32s(&phdr->p_flags); /* Segment flags */
196 197 bswap32s(&phdr->p_align); /* Segment alignment */
197 198 }
  199 +
  200 +static void bswap_shdr(Elf32_Shdr *shdr)
  201 +{
  202 + bswap32s(&shdr->sh_name);
  203 + bswap32s(&shdr->sh_type);
  204 + bswap32s(&shdr->sh_flags);
  205 + bswap32s(&shdr->sh_addr);
  206 + bswap32s(&shdr->sh_offset);
  207 + bswap32s(&shdr->sh_size);
  208 + bswap32s(&shdr->sh_link);
  209 + bswap32s(&shdr->sh_info);
  210 + bswap32s(&shdr->sh_addralign);
  211 + bswap32s(&shdr->sh_entsize);
  212 +}
  213 +
  214 +static void bswap_sym(Elf32_Sym *sym)
  215 +{
  216 + bswap32s(&sym->st_name);
  217 + bswap32s(&sym->st_value);
  218 + bswap32s(&sym->st_size);
  219 + bswap16s(&sym->st_shndx);
  220 +}
198 221 #endif
199 222  
200 223 static void * get_free_page(void)
... ... @@ -656,7 +679,56 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
656 679 return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
657 680 }
658 681  
  682 +/* Best attempt to load symbols from this ELF object. */
  683 +static void load_symbols(struct elfhdr *hdr, int fd)
  684 +{
  685 + unsigned int i;
  686 + struct elf_shdr sechdr, symtab, strtab;
  687 + char *strings;
  688 +
  689 + lseek(fd, hdr->e_shoff, SEEK_SET);
  690 + for (i = 0; i < hdr->e_shnum; i++) {
  691 + if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
  692 + return;
  693 +#ifdef BSWAP_NEEDED
  694 + bswap_shdr(&sechdr);
  695 +#endif
  696 + if (sechdr.sh_type == SHT_SYMTAB) {
  697 + symtab = sechdr;
  698 + lseek(fd, hdr->e_shoff
  699 + + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
  700 + if (read(fd, &strtab, sizeof(strtab))
  701 + != sizeof(strtab))
  702 + return;
  703 +#ifdef BSWAP_NEEDED
  704 + bswap_shdr(&strtab);
  705 +#endif
  706 + goto found;
  707 + }
  708 + }
  709 + return; /* Shouldn't happen... */
  710 +
  711 + found:
  712 + /* Now know where the strtab and symtab are. Snarf them. */
  713 + disas_symtab = malloc(symtab.sh_size);
  714 + disas_strtab = strings = malloc(strtab.sh_size);
  715 + if (!disas_symtab || !disas_strtab)
  716 + return;
  717 +
  718 + lseek(fd, symtab.sh_offset, SEEK_SET);
  719 + if (read(fd, disas_symtab, symtab.sh_size) != symtab.sh_size)
  720 + return;
659 721  
  722 +#ifdef BSWAP_NEEDED
  723 + for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++)
  724 + bswap_sym(disas_symtab + sizeof(struct elf_sym)*i);
  725 +#endif
  726 +
  727 + lseek(fd, strtab.sh_offset, SEEK_SET);
  728 + if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
  729 + return;
  730 + disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
  731 +}
660 732  
661 733 static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
662 734 struct image_info * info)
... ... @@ -989,6 +1061,9 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r
989 1061  
990 1062 free(elf_phdata);
991 1063  
  1064 + if (loglevel)
  1065 + load_symbols(&elf_ex, bprm->fd);
  1066 +
992 1067 if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
993 1068 info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
994 1069  
... ...