/[qemu]/qemu/hw/magic-load.c
ViewVC logotype

Diff of /qemu/hw/magic-load.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by bellard, Sun Dec 19 23:18:01 2004 UTC revision 1.4 by bellard, Sat Jul 2 14:31:34 2005 UTC
# Line 56  static void bswap_ahdr(struct exec *e) Line 56  static void bswap_ahdr(struct exec *e)
56    
57  #include "elf.h"  #include "elf.h"
58    
59  #ifdef BSWAP_NEEDED  #ifndef BSWAP_NEEDED
60  static void bswap_ehdr(Elf32_Ehdr *ehdr)  #define bswap_ehdr32(e) do { } while (0)
61  {  #define bswap_phdr32(e) do { } while (0)
62      bswap16s(&ehdr->e_type);                    /* Object file type */  #define bswap_shdr32(e) do { } while (0)
63      bswap16s(&ehdr->e_machine);         /* Architecture */  #define bswap_sym32(e) do { } while (0)
64      bswap32s(&ehdr->e_version);         /* Object file version */  #ifdef TARGET_SPARC64
65      bswap32s(&ehdr->e_entry);           /* Entry point virtual address */  #define bswap_ehdr64(e) do { } while (0)
66      bswap32s(&ehdr->e_phoff);           /* Program header table file offset */  #define bswap_phdr64(e) do { } while (0)
67      bswap32s(&ehdr->e_shoff);           /* Section header table file offset */  #define bswap_shdr64(e) do { } while (0)
68      bswap32s(&ehdr->e_flags);           /* Processor-specific flags */  #define bswap_sym64(e) do { } while (0)
69      bswap16s(&ehdr->e_ehsize);          /* ELF header size in bytes */  #endif
     bswap16s(&ehdr->e_phentsize);               /* Program header table entry size */  
     bswap16s(&ehdr->e_phnum);           /* Program header table entry count */  
     bswap16s(&ehdr->e_shentsize);               /* Section header table entry size */  
     bswap16s(&ehdr->e_shnum);           /* Section header table entry count */  
     bswap16s(&ehdr->e_shstrndx);                /* Section header string table index */  
 }  
   
 static void bswap_phdr(Elf32_Phdr *phdr)  
 {  
     bswap32s(&phdr->p_type);                    /* Segment type */  
     bswap32s(&phdr->p_offset);          /* Segment file offset */  
     bswap32s(&phdr->p_vaddr);           /* Segment virtual address */  
     bswap32s(&phdr->p_paddr);           /* Segment physical address */  
     bswap32s(&phdr->p_filesz);          /* Segment size in file */  
     bswap32s(&phdr->p_memsz);           /* Segment size in memory */  
     bswap32s(&phdr->p_flags);           /* Segment flags */  
     bswap32s(&phdr->p_align);           /* Segment alignment */  
 }  
   
 static void bswap_shdr(Elf32_Shdr *shdr)  
 {  
     bswap32s(&shdr->sh_name);  
     bswap32s(&shdr->sh_type);  
     bswap32s(&shdr->sh_flags);  
     bswap32s(&shdr->sh_addr);  
     bswap32s(&shdr->sh_offset);  
     bswap32s(&shdr->sh_size);  
     bswap32s(&shdr->sh_link);  
     bswap32s(&shdr->sh_info);  
     bswap32s(&shdr->sh_addralign);  
     bswap32s(&shdr->sh_entsize);  
 }  
   
 static void bswap_sym(Elf32_Sym *sym)  
 {  
     bswap32s(&sym->st_name);  
     bswap32s(&sym->st_value);  
     bswap32s(&sym->st_size);  
     bswap16s(&sym->st_shndx);  
 }  
 #else  
 #define bswap_ehdr(e) do { } while (0)  
 #define bswap_phdr(e) do { } while (0)  
 #define bswap_shdr(e) do { } while (0)  
 #define bswap_sym(e) do { } while (0)  
70  #endif  #endif
71    
72  static int find_phdr(struct elfhdr *ehdr, int fd, struct elf_phdr *phdr, uint32_t type)  #define SZ              32
73  {  #define elf_word        uint32_t
74      int i, retval;  #define bswapSZs        bswap32s
75    #include "elf_ops.h"
76      retval = lseek(fd, ehdr->e_phoff, SEEK_SET);  
77      if (retval < 0)  #ifdef TARGET_SPARC64
78          return -1;  #undef elfhdr
79    #undef elf_phdr
80      for (i = 0; i < ehdr->e_phnum; i++) {  #undef elf_shdr
81          retval = read(fd, phdr, sizeof(*phdr));  #undef elf_sym
82          if (retval < 0)  #undef elf_note
83              return -1;  #undef elf_word
84          bswap_phdr(phdr);  #undef bswapSZs
85          if (phdr->p_type == type)  #undef SZ
86              return 0;  #define elfhdr          elf64_hdr
87      }  #define elf_phdr        elf64_phdr
88      return -1;  #define elf_note        elf64_note
89  }  #define elf_shdr        elf64_shdr
90    #define elf_sym         elf64_sym
91  static void *find_shdr(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint32_t type)  #define elf_word        uint64_t
92  {  #define bswapSZs        bswap64s
93      int i, retval;  #define SZ              64
94    #include "elf_ops.h"
95      retval = lseek(fd, ehdr->e_shoff, SEEK_SET);  #endif
     if (retval < 0)  
         return NULL;  
   
     for (i = 0; i < ehdr->e_shnum; i++) {  
         retval = read(fd, shdr, sizeof(*shdr));  
         if (retval < 0)  
             return NULL;  
         bswap_shdr(shdr);  
         if (shdr->sh_type == type)  
             return qemu_malloc(shdr->sh_size);  
     }  
     return NULL;  
 }  
   
 static void *find_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)  
 {  
     int retval;  
   
     retval = lseek(fd, ehdr->e_shoff + sizeof(struct elf_shdr) * symtab->sh_link, SEEK_SET);  
     if (retval < 0)  
         return NULL;  
   
     retval = read(fd, shdr, sizeof(*shdr));  
     if (retval < 0)  
         return NULL;  
     bswap_shdr(shdr);  
     if (shdr->sh_type == SHT_STRTAB)  
         return qemu_malloc(shdr->sh_size);;  
     return NULL;  
 }  
   
 static int read_program(int fd, struct elf_phdr *phdr, void *dst, uint32_t entry)  
 {  
     int retval;  
     retval = lseek(fd, phdr->p_offset + entry - phdr->p_vaddr, SEEK_SET);  
     if (retval < 0)  
         return -1;  
     return read(fd, dst, phdr->p_filesz);  
 }  
   
 static int read_section(int fd, struct elf_shdr *s, void *dst)  
 {  
     int retval;  
   
     retval = lseek(fd, s->sh_offset, SEEK_SET);  
     if (retval < 0)  
         return -1;  
     retval = read(fd, dst, s->sh_size);  
     if (retval < 0)  
         return -1;  
     return 0;  
 }  
   
 static void *process_section(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint32_t type)  
 {  
     void *dst;  
   
     dst = find_shdr(ehdr, fd, shdr, type);  
     if (!dst)  
         goto error;  
   
     if (read_section(fd, shdr, dst))  
         goto error;  
     return dst;  
  error:  
     qemu_free(dst);  
     return NULL;  
 }  
   
 static void *process_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)  
 {  
     void *dst;  
   
     dst = find_strtab(ehdr, fd, shdr, symtab);  
     if (!dst)  
         goto error;  
   
     if (read_section(fd, shdr, dst))  
         goto error;  
     return dst;  
  error:  
     qemu_free(dst);  
     return NULL;  
 }  
   
 static void load_symbols(struct elfhdr *ehdr, int fd)  
 {  
     struct elf_shdr symtab, strtab;  
     struct elf_sym *syms;  
     struct syminfo *s;  
     int nsyms, i;  
     char *str;  
   
     /* Symbol table */  
     syms = process_section(ehdr, fd, &symtab, SHT_SYMTAB);  
     if (!syms)  
         return;  
   
     nsyms = symtab.sh_size / sizeof(struct elf_sym);  
     for (i = 0; i < nsyms; i++)  
         bswap_sym(&syms[i]);  
   
     /* String table */  
     str = process_strtab(ehdr, fd, &strtab, &symtab);  
     if (!str)  
         goto error_freesyms;  
   
     /* Commit */  
     s = qemu_mallocz(sizeof(*s));  
     s->disas_symtab = syms;  
     s->disas_num_syms = nsyms;  
     s->disas_strtab = str;  
     s->next = syminfos;  
     syminfos = s;  
     return;  
  error_freesyms:  
     qemu_free(syms);  
     return;  
 }  
96    
97  int load_elf(const char *filename, uint8_t *addr)  int load_elf(const char *filename, uint8_t *addr)
98  {  {
99      struct elfhdr ehdr;      struct elf32_hdr ehdr;
     struct elf_phdr phdr;  
100      int retval, fd;      int retval, fd;
101        Elf32_Half machine;
102    
103      fd = open(filename, O_RDONLY | O_BINARY);      fd = open(filename, O_RDONLY | O_BINARY);
104      if (fd < 0)      if (fd < 0)
# Line 272  int load_elf(const char *filename, uint8 Line 108  int load_elf(const char *filename, uint8
108      if (retval < 0)      if (retval < 0)
109          goto error;          goto error;
110    
     bswap_ehdr(&ehdr);  
   
111      if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E'      if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E'
112          || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F'          || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F')
         || (ehdr.e_machine != EM_SPARC  
             && ehdr.e_machine != EM_SPARC32PLUS))  
113          goto error;          goto error;
114        machine = tswap16(ehdr.e_machine);
115        if (machine == EM_SPARC || machine == EM_SPARC32PLUS) {
116            struct elf32_phdr phdr;
117    
118      if (find_phdr(&ehdr, fd, &phdr, PT_LOAD))          bswap_ehdr32(&ehdr);
119          goto error;  
120      retval = read_program(fd, &phdr, addr, ehdr.e_entry);          if (find_phdr32(&ehdr, fd, &phdr, PT_LOAD))
121      if (retval < 0)              goto error;
122          goto error;          retval = read_program32(fd, &phdr, addr, ehdr.e_entry);
123            if (retval < 0)
124                goto error;
125            load_symbols32(&ehdr, fd);
126        }
127    #ifdef TARGET_SPARC64
128        else if (machine == EM_SPARCV9) {
129            struct elf64_hdr ehdr64;
130            struct elf64_phdr phdr;
131    
132            lseek(fd, 0, SEEK_SET);
133    
134            retval = read(fd, &ehdr64, sizeof(ehdr64));
135            if (retval < 0)
136                goto error;
137    
138      load_symbols(&ehdr, fd);          bswap_ehdr64(&ehdr64);
139    
140            if (find_phdr64(&ehdr64, fd, &phdr, PT_LOAD))
141                goto error;
142            retval = read_program64(fd, &phdr, addr, ehdr64.e_entry);
143            if (retval < 0)
144                goto error;
145            load_symbols64(&ehdr64, fd);
146        }
147    #endif
148    
149      close(fd);      close(fd);
150      return retval;      return retval;

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26