/[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.2 by bellard, Mon Oct 4 21:23:09 2004 UTC revision 1.3 by bellard, Sun Dec 19 23:18:01 2004 UTC
# Line 1  Line 1 
1  #include "vl.h"  #include "vl.h"
2  #include "disas.h"  #include "disas.h"
3    #include "exec-all.h"
4    
5    struct exec
6    {
7      uint32_t a_info;   /* Use macros N_MAGIC, etc for access */
8      uint32_t a_text;   /* length of text, in bytes */
9      uint32_t a_data;   /* length of data, in bytes */
10      uint32_t a_bss;    /* length of uninitialized data area, in bytes */
11      uint32_t a_syms;   /* length of symbol table data in file, in bytes */
12      uint32_t a_entry;  /* start address */
13      uint32_t a_trsize; /* length of relocation info for text, in bytes */
14      uint32_t a_drsize; /* length of relocation info for data, in bytes */
15    };
16    
17    #ifdef BSWAP_NEEDED
18    static void bswap_ahdr(struct exec *e)
19    {
20        bswap32s(&e->a_info);
21        bswap32s(&e->a_text);
22        bswap32s(&e->a_data);
23        bswap32s(&e->a_bss);
24        bswap32s(&e->a_syms);
25        bswap32s(&e->a_entry);
26        bswap32s(&e->a_trsize);
27        bswap32s(&e->a_drsize);
28    }
29    #else
30    #define bswap_ahdr(x) do { } while (0)
31    #endif
32    
33    #define N_MAGIC(exec) ((exec).a_info & 0xffff)
34    #define OMAGIC 0407
35    #define NMAGIC 0410
36    #define ZMAGIC 0413
37    #define QMAGIC 0314
38    #define _N_HDROFF(x) (1024 - sizeof (struct exec))
39    #define N_TXTOFF(x)                                                     \
40        (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) :     \
41         (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
42    #define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? TARGET_PAGE_SIZE : 0)
43    #define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
44    #define _N_SEGMENT_ROUND(x) (((x) + TARGET_PAGE_SIZE - 1) & ~(TARGET_PAGE_SIZE - 1))
45    
46    #define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
47    
48    #define N_DATADDR(x) \
49        (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
50         : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
51    
52    
53  #define ELF_CLASS   ELFCLASS32  #define ELF_CLASS   ELFCLASS32
54  #define ELF_DATA    ELFDATA2MSB  #define ELF_DATA    ELFDATA2MSB
# Line 103  static void *find_shdr(struct elfhdr *eh Line 152  static void *find_shdr(struct elfhdr *eh
152      return NULL;      return NULL;
153  }  }
154    
155  static int find_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)  static void *find_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)
156  {  {
157      int retval;      int retval;
158    
159      retval = lseek(fd, ehdr->e_shoff + sizeof(struct elf_shdr) * symtab->sh_link, SEEK_SET);      retval = lseek(fd, ehdr->e_shoff + sizeof(struct elf_shdr) * symtab->sh_link, SEEK_SET);
160      if (retval < 0)      if (retval < 0)
161          return -1;          return NULL;
162    
163      retval = read(fd, shdr, sizeof(*shdr));      retval = read(fd, shdr, sizeof(*shdr));
164      if (retval < 0)      if (retval < 0)
165          return -1;          return NULL;
166      bswap_shdr(shdr);      bswap_shdr(shdr);
167      if (shdr->sh_type == SHT_STRTAB)      if (shdr->sh_type == SHT_STRTAB)
168          return qemu_malloc(shdr->sh_size);;          return qemu_malloc(shdr->sh_size);;
169      return 0;      return NULL;
170  }  }
171    
172  static int read_program(int fd, struct elf_phdr *phdr, void *dst)  static int read_program(int fd, struct elf_phdr *phdr, void *dst, uint32_t entry)
173  {  {
174      int retval;      int retval;
175      retval = lseek(fd, 0x4000, SEEK_SET);      retval = lseek(fd, phdr->p_offset + entry - phdr->p_vaddr, SEEK_SET);
176      if (retval < 0)      if (retval < 0)
177          return -1;          return -1;
178      return read(fd, dst, phdr->p_filesz);      return read(fd, dst, phdr->p_filesz);
# Line 178  static void load_symbols(struct elfhdr * Line 227  static void load_symbols(struct elfhdr *
227  {  {
228      struct elf_shdr symtab, strtab;      struct elf_shdr symtab, strtab;
229      struct elf_sym *syms;      struct elf_sym *syms;
230        struct syminfo *s;
231      int nsyms, i;      int nsyms, i;
232      char *str;      char *str;
233    
# Line 196  static void load_symbols(struct elfhdr * Line 246  static void load_symbols(struct elfhdr *
246          goto error_freesyms;          goto error_freesyms;
247    
248      /* Commit */      /* Commit */
249      if (disas_symtab)      s = qemu_mallocz(sizeof(*s));
250          qemu_free(disas_symtab); /* XXX Merge with old symbols? */      s->disas_symtab = syms;
251      if (disas_strtab)      s->disas_num_syms = nsyms;
252          qemu_free(disas_strtab);      s->disas_strtab = str;
253      disas_symtab = syms;      s->next = syminfos;
254      disas_num_syms = nsyms;      syminfos = s;
     disas_strtab = str;  
255      return;      return;
256   error_freesyms:   error_freesyms:
257      qemu_free(syms);      qemu_free(syms);
258      return;      return;
259  }  }
260    
261  int load_elf(const char * filename, uint8_t *addr)  int load_elf(const char *filename, uint8_t *addr)
262  {  {
263      struct elfhdr ehdr;      struct elfhdr ehdr;
264      struct elf_phdr phdr;      struct elf_phdr phdr;
# Line 227  int load_elf(const char * filename, uint Line 276  int load_elf(const char * filename, uint
276    
277      if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E'      if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E'
278          || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F'          || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F'
279          || ehdr.e_machine != EM_SPARC)          || (ehdr.e_machine != EM_SPARC
280                && ehdr.e_machine != EM_SPARC32PLUS))
281          goto error;          goto error;
282    
283      if (find_phdr(&ehdr, fd, &phdr, PT_LOAD))      if (find_phdr(&ehdr, fd, &phdr, PT_LOAD))
284          goto error;          goto error;
285      retval = read_program(fd, &phdr, addr);      retval = read_program(fd, &phdr, addr, ehdr.e_entry);
286      if (retval < 0)      if (retval < 0)
287          goto error;          goto error;
288    
# Line 245  int load_elf(const char * filename, uint Line 295  int load_elf(const char * filename, uint
295      return -1;      return -1;
296  }  }
297    
298  int load_kernel(const char *filename, uint8_t *addr)  int load_aout(const char *filename, uint8_t *addr)
299  {  {
300      int fd, size;      int fd, size, ret;
301        struct exec e;
302        uint32_t magic;
303    
304      fd = open(filename, O_RDONLY | O_BINARY);      fd = open(filename, O_RDONLY | O_BINARY);
305      if (fd < 0)      if (fd < 0)
306          return -1;          return -1;
307      /* load 32 bit code */  
308      size = read(fd, addr, 16 * 1024 * 1024);      size = read(fd, &e, sizeof(e));
309      if (size < 0)      if (size < 0)
310          goto fail;          goto fail;
311    
312        bswap_ahdr(&e);
313    
314        magic = N_MAGIC(e);
315        switch (magic) {
316        case ZMAGIC:
317        case QMAGIC:
318        case OMAGIC:
319            lseek(fd, N_TXTOFF(e), SEEK_SET);
320            size = read(fd, addr, e.a_text + e.a_data);
321            if (size < 0)
322                goto fail;
323            break;
324        case NMAGIC:
325            lseek(fd, N_TXTOFF(e), SEEK_SET);
326            size = read(fd, addr, e.a_text);
327            if (size < 0)
328                goto fail;
329            ret = read(fd, addr + N_DATADDR(e), e.a_data);
330            if (ret < 0)
331                goto fail;
332            size += ret;
333            break;
334        default:
335            goto fail;
336        }
337      close(fd);      close(fd);
338      return size;      return size;
339   fail:   fail:
# Line 263  int load_kernel(const char *filename, ui Line 341  int load_kernel(const char *filename, ui
341      return -1;      return -1;
342  }  }
343    
 typedef struct MAGICState {  
     uint32_t addr;  
     uint32_t saved_addr;  
     int magic_state;  
     char saved_kfn[1024];  
 } MAGICState;  
   
 static uint32_t magic_mem_readl(void *opaque, target_phys_addr_t addr)  
 {  
     int ret;  
     MAGICState *s = opaque;  
   
     if (s->magic_state == 0) {  
         ret = load_elf(s->saved_kfn, (uint8_t *)s->saved_addr);  
         if (ret < 0)  
             ret = load_kernel(s->saved_kfn, (uint8_t *)s->saved_addr);  
         if (ret < 0) {  
             fprintf(stderr, "qemu: could not load kernel '%s'\n",  
                     s->saved_kfn);  
         }  
         s->magic_state = 1; /* No more magic */  
         tb_flush();  
         return bswap32(ret);  
     }  
     return 0;  
 }  
   
 static void magic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)  
 {  
 }  
   
   
 static CPUReadMemoryFunc *magic_mem_read[3] = {  
     magic_mem_readl,  
     magic_mem_readl,  
     magic_mem_readl,  
 };  
   
 static CPUWriteMemoryFunc *magic_mem_write[3] = {  
     magic_mem_writel,  
     magic_mem_writel,  
     magic_mem_writel,  
 };  
   
 void magic_init(const char *kfn, int kloadaddr, uint32_t addr)  
 {  
     int magic_io_memory;  
     MAGICState *s;  
   
     s = qemu_mallocz(sizeof(MAGICState));  
     if (!s)  
         return;  
   
     strcpy(s->saved_kfn, kfn);  
     s->saved_addr = kloadaddr;  
     s->magic_state = 0;  
     s->addr = addr;  
     magic_io_memory = cpu_register_io_memory(0, magic_mem_read, magic_mem_write, s);  
     cpu_register_physical_memory(addr, 4, magic_io_memory);  
 }  
   

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

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