use generic ELF loader
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 23 Apr 2006 17:14:05 +0000 (17:14 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 23 Apr 2006 17:14:05 +0000 (17:14 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1832 c046a42c-6fe2-441c-8c8c-71466251a162

hw/elf_ops.h [deleted file]
hw/magic-load.c [deleted file]
hw/sun4m.c
hw/sun4u.c

diff --git a/hw/elf_ops.h b/hw/elf_ops.h
deleted file mode 100644 (file)
index 1f3232d..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-#ifdef BSWAP_NEEDED
-static void glue(bswap_ehdr, SZ)(struct elfhdr *ehdr)
-{
-    bswap16s(&ehdr->e_type);                   /* Object file type */
-    bswap16s(&ehdr->e_machine);                /* Architecture */
-    bswap32s(&ehdr->e_version);                /* Object file version */
-    bswapSZs(&ehdr->e_entry);          /* Entry point virtual address */
-    bswapSZs(&ehdr->e_phoff);          /* Program header table file offset */
-    bswapSZs(&ehdr->e_shoff);          /* Section header table file offset */
-    bswap32s(&ehdr->e_flags);          /* Processor-specific flags */
-    bswap16s(&ehdr->e_ehsize);         /* ELF header size in bytes */
-    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 glue(bswap_phdr, SZ)(struct elf_phdr *phdr)
-{
-    bswap32s(&phdr->p_type);                   /* Segment type */
-    bswapSZs(&phdr->p_offset);         /* Segment file offset */
-    bswapSZs(&phdr->p_vaddr);          /* Segment virtual address */
-    bswapSZs(&phdr->p_paddr);          /* Segment physical address */
-    bswapSZs(&phdr->p_filesz);         /* Segment size in file */
-    bswapSZs(&phdr->p_memsz);          /* Segment size in memory */
-    bswap32s(&phdr->p_flags);          /* Segment flags */
-    bswapSZs(&phdr->p_align);          /* Segment alignment */
-}
-
-static void glue(bswap_shdr, SZ)(struct elf_shdr *shdr)
-{
-    bswap32s(&shdr->sh_name);
-    bswap32s(&shdr->sh_type);
-    bswapSZs(&shdr->sh_flags);
-    bswapSZs(&shdr->sh_addr);
-    bswapSZs(&shdr->sh_offset);
-    bswapSZs(&shdr->sh_size);
-    bswap32s(&shdr->sh_link);
-    bswap32s(&shdr->sh_info);
-    bswapSZs(&shdr->sh_addralign);
-    bswapSZs(&shdr->sh_entsize);
-}
-
-static void glue(bswap_sym, SZ)(struct elf_sym *sym)
-{
-    bswap32s(&sym->st_name);
-    bswapSZs(&sym->st_value);
-    bswapSZs(&sym->st_size);
-    bswap16s(&sym->st_shndx);
-}
-#endif
-
-static int glue(find_phdr, SZ)(struct elfhdr *ehdr, int fd, struct elf_phdr *phdr, elf_word type)
-{
-    int i, retval;
-
-    retval = lseek(fd, ehdr->e_phoff, SEEK_SET);
-    if (retval < 0)
-       return -1;
-
-    for (i = 0; i < ehdr->e_phnum; i++) {
-       retval = read(fd, phdr, sizeof(*phdr));
-       if (retval < 0)
-           return -1;
-       glue(bswap_phdr, SZ)(phdr);
-       if (phdr->p_type == type)
-           return 0;
-    }
-    return -1;
-}
-
-static void * glue(find_shdr, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, elf_word type)
-{
-    int i, retval;
-
-    retval = lseek(fd, ehdr->e_shoff, SEEK_SET);
-    if (retval < 0)
-       return NULL;
-
-    for (i = 0; i < ehdr->e_shnum; i++) {
-       retval = read(fd, shdr, sizeof(*shdr));
-       if (retval < 0)
-           return NULL;
-       glue(bswap_shdr, SZ)(shdr);
-       if (shdr->sh_type == type)
-           return qemu_malloc(shdr->sh_size);
-    }
-    return NULL;
-}
-
-static void * glue(find_strtab, SZ)(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;
-    glue(bswap_shdr, SZ)(shdr);
-    if (shdr->sh_type == SHT_STRTAB)
-       return qemu_malloc(shdr->sh_size);;
-    return NULL;
-}
-
-static int glue(read_program, SZ)(int fd, struct elf_phdr *phdr, void *dst, elf_word 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 glue(read_section, SZ)(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 * glue(process_section, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, elf_word type)
-{
-    void *dst;
-
-    dst = glue(find_shdr, SZ)(ehdr, fd, shdr, type);
-    if (!dst)
-       goto error;
-
-    if (glue(read_section, SZ)(fd, shdr, dst))
-       goto error;
-    return dst;
- error:
-    qemu_free(dst);
-    return NULL;
-}
-
-static void * glue(process_strtab, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)
-{
-    void *dst;
-
-    dst = glue(find_strtab, SZ)(ehdr, fd, shdr, symtab);
-    if (!dst)
-       goto error;
-
-    if (glue(read_section, SZ)(fd, shdr, dst))
-       goto error;
-    return dst;
- error:
-    qemu_free(dst);
-    return NULL;
-}
-
-static void glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd)
-{
-    struct elf_shdr symtab, strtab;
-    struct elf_sym *syms;
-#if (SZ == 64)
-    struct elf32_sym *syms32;
-#endif
-    struct syminfo *s;
-    int nsyms, i;
-    char *str;
-
-    /* Symbol table */
-    syms = glue(process_section, SZ)(ehdr, fd, &symtab, SHT_SYMTAB);
-    if (!syms)
-       return;
-
-    nsyms = symtab.sh_size / sizeof(struct elf_sym);
-#if (SZ == 64)
-    syms32 = qemu_mallocz(nsyms * sizeof(struct elf32_sym));
-#endif
-    for (i = 0; i < nsyms; i++) {
-       glue(bswap_sym, SZ)(&syms[i]);
-#if (SZ == 64)
-       syms32[i].st_name = syms[i].st_name;
-       syms32[i].st_info = syms[i].st_info;
-       syms32[i].st_other = syms[i].st_other;
-       syms32[i].st_shndx = syms[i].st_shndx;
-       syms32[i].st_value = syms[i].st_value & 0xffffffff;
-       syms32[i].st_size = syms[i].st_size & 0xffffffff;
-#endif
-    }
-    /* String table */
-    str = glue(process_strtab, SZ)(ehdr, fd, &strtab, &symtab);
-    if (!str)
-       goto error_freesyms;
-
-    /* Commit */
-    s = qemu_mallocz(sizeof(*s));
-#if (SZ == 64)
-    s->disas_symtab = syms32;
-    qemu_free(syms);
-#else
-    s->disas_symtab = syms;
-#endif
-    s->disas_num_syms = nsyms;
-    s->disas_strtab = str;
-    s->next = syminfos;
-    syminfos = s;
-    return;
- error_freesyms:
-#if (SZ == 64)
-    qemu_free(syms32);
-#endif
-    qemu_free(syms);
-    return;
-}
diff --git a/hw/magic-load.c b/hw/magic-load.c
deleted file mode 100644 (file)
index d5c098f..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-#include "vl.h"
-#include "disas.h"
-#include "exec-all.h"
-
-struct exec
-{
-  uint32_t a_info;   /* Use macros N_MAGIC, etc for access */
-  uint32_t a_text;   /* length of text, in bytes */
-  uint32_t a_data;   /* length of data, in bytes */
-  uint32_t a_bss;    /* length of uninitialized data area, in bytes */
-  uint32_t a_syms;   /* length of symbol table data in file, in bytes */
-  uint32_t a_entry;  /* start address */
-  uint32_t a_trsize; /* length of relocation info for text, in bytes */
-  uint32_t a_drsize; /* length of relocation info for data, in bytes */
-};
-
-#ifdef BSWAP_NEEDED
-static void bswap_ahdr(struct exec *e)
-{
-    bswap32s(&e->a_info);
-    bswap32s(&e->a_text);
-    bswap32s(&e->a_data);
-    bswap32s(&e->a_bss);
-    bswap32s(&e->a_syms);
-    bswap32s(&e->a_entry);
-    bswap32s(&e->a_trsize);
-    bswap32s(&e->a_drsize);
-}
-#else
-#define bswap_ahdr(x) do { } while (0)
-#endif
-
-#define N_MAGIC(exec) ((exec).a_info & 0xffff)
-#define OMAGIC 0407
-#define NMAGIC 0410
-#define ZMAGIC 0413
-#define QMAGIC 0314
-#define _N_HDROFF(x) (1024 - sizeof (struct exec))
-#define N_TXTOFF(x)                                                    \
-    (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) :    \
-     (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
-#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? TARGET_PAGE_SIZE : 0)
-#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
-#define _N_SEGMENT_ROUND(x) (((x) + TARGET_PAGE_SIZE - 1) & ~(TARGET_PAGE_SIZE - 1))
-
-#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
-
-#define N_DATADDR(x) \
-    (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
-     : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
-
-
-#define ELF_CLASS   ELFCLASS32
-#define ELF_DATA    ELFDATA2MSB
-#define ELF_ARCH    EM_SPARC
-
-#include "elf.h"
-
-#ifndef BSWAP_NEEDED
-#define bswap_ehdr32(e) do { } while (0)
-#define bswap_phdr32(e) do { } while (0)
-#define bswap_shdr32(e) do { } while (0)
-#define bswap_sym32(e) do { } while (0)
-#ifdef TARGET_SPARC64
-#define bswap_ehdr64(e) do { } while (0)
-#define bswap_phdr64(e) do { } while (0)
-#define bswap_shdr64(e) do { } while (0)
-#define bswap_sym64(e) do { } while (0)
-#endif
-#endif
-
-#define SZ             32
-#define elf_word        uint32_t
-#define bswapSZs       bswap32s
-#include "elf_ops.h"
-
-#ifdef TARGET_SPARC64
-#undef elfhdr
-#undef elf_phdr
-#undef elf_shdr
-#undef elf_sym
-#undef elf_note
-#undef elf_word
-#undef bswapSZs
-#undef SZ
-#define elfhdr         elf64_hdr
-#define elf_phdr       elf64_phdr
-#define elf_note       elf64_note
-#define elf_shdr       elf64_shdr
-#define elf_sym                elf64_sym
-#define elf_word        uint64_t
-#define bswapSZs       bswap64s
-#define SZ             64
-#include "elf_ops.h"
-#endif
-
-int load_elf(const char *filename, uint8_t *addr)
-{
-    struct elf32_hdr ehdr;
-    int retval, fd;
-    Elf32_Half machine;
-
-    fd = open(filename, O_RDONLY | O_BINARY);
-    if (fd < 0)
-       goto error;
-
-    retval = read(fd, &ehdr, sizeof(ehdr));
-    if (retval < 0)
-       goto error;
-
-    if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E'
-       || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F')
-       goto error;
-    machine = tswap16(ehdr.e_machine);
-    if (machine == EM_SPARC || machine == EM_SPARC32PLUS) {
-       struct elf32_phdr phdr;
-
-       bswap_ehdr32(&ehdr);
-
-       if (find_phdr32(&ehdr, fd, &phdr, PT_LOAD))
-           goto error;
-       retval = read_program32(fd, &phdr, addr, ehdr.e_entry);
-       if (retval < 0)
-           goto error;
-       load_symbols32(&ehdr, fd);
-    }
-#ifdef TARGET_SPARC64
-    else if (machine == EM_SPARCV9) {
-       struct elf64_hdr ehdr64;
-       struct elf64_phdr phdr;
-
-       lseek(fd, 0, SEEK_SET);
-
-       retval = read(fd, &ehdr64, sizeof(ehdr64));
-       if (retval < 0)
-           goto error;
-
-       bswap_ehdr64(&ehdr64);
-
-       if (find_phdr64(&ehdr64, fd, &phdr, PT_LOAD))
-           goto error;
-       retval = read_program64(fd, &phdr, phys_ram_base + ehdr64.e_entry, ehdr64.e_entry);
-       if (retval < 0)
-           goto error;
-       load_symbols64(&ehdr64, fd);
-    }
-#endif
-
-    close(fd);
-    return retval;
- error:
-    close(fd);
-    return -1;
-}
-
-int load_aout(const char *filename, uint8_t *addr)
-{
-    int fd, size, ret;
-    struct exec e;
-    uint32_t magic;
-
-    fd = open(filename, O_RDONLY | O_BINARY);
-    if (fd < 0)
-        return -1;
-
-    size = read(fd, &e, sizeof(e));
-    if (size < 0)
-        goto fail;
-
-    bswap_ahdr(&e);
-
-    magic = N_MAGIC(e);
-    switch (magic) {
-    case ZMAGIC:
-    case QMAGIC:
-    case OMAGIC:
-       lseek(fd, N_TXTOFF(e), SEEK_SET);
-       size = read(fd, addr, e.a_text + e.a_data);
-       if (size < 0)
-           goto fail;
-       break;
-    case NMAGIC:
-       lseek(fd, N_TXTOFF(e), SEEK_SET);
-       size = read(fd, addr, e.a_text);
-       if (size < 0)
-           goto fail;
-       ret = read(fd, addr + N_DATADDR(e), e.a_data);
-       if (ret < 0)
-           goto fail;
-       size += ret;
-       break;
-    default:
-       goto fail;
-    }
-    close(fd);
-    return size;
- fail:
-    close(fd);
-    return -1;
-}
-
index 435ac02..014ed09 100644 (file)
@@ -26,6 +26,7 @@
 #define KERNEL_LOAD_ADDR     0x00004000
 #define CMDLINE_ADDR         0x007ff000
 #define INITRD_LOAD_ADDR     0x00800000
+#define PROM_SIZE_MAX        (256 * 1024)
 #define PROM_ADDR           0xffd00000
 #define PROM_FILENAMEB      "proll.bin"
 #define PROM_FILENAMEE      "proll.elf"
@@ -263,9 +264,12 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
     slavio_misc = slavio_misc_init(PHYS_JJ_SLAVIO, PHYS_JJ_ME_IRQ);
 
     prom_offset = ram_size + vram_size;
+    cpu_register_physical_memory(PROM_ADDR, 
+                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK, 
+                                 prom_offset | IO_MEM_ROM);
 
     snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE);
-    ret = load_elf(buf, phys_ram_base + prom_offset);
+    ret = load_elf(buf, 0);
     if (ret < 0) {
        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB);
        ret = load_image(buf, phys_ram_base + prom_offset);
@@ -275,12 +279,10 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
                buf);
        exit(1);
     }
-    cpu_register_physical_memory(PROM_ADDR, (ret + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK, 
-                                 prom_offset | IO_MEM_ROM);
 
     kernel_size = 0;
     if (linux_boot) {
-        kernel_size = load_elf(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
+        kernel_size = load_elf(kernel_filename, -0xf0000000);
         if (kernel_size < 0)
            kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
        if (kernel_size < 0)
index 0cf5381..bb40697 100644 (file)
@@ -27,6 +27,7 @@
 #define KERNEL_LOAD_ADDR     0x00404000
 #define CMDLINE_ADDR         0x003ff000
 #define INITRD_LOAD_ADDR     0x00300000
+#define PROM_SIZE_MAX        (256 * 1024)
 #define PROM_ADDR           0x1fff0000000ULL
 #define APB_SPECIAL_BASE     0x1fe00000000ULL
 #define APB_MEM_BASE        0x1ff00000000ULL
@@ -277,9 +278,12 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
     cpu_register_physical_memory(0, ram_size, 0);
 
     prom_offset = ram_size + vga_ram_size;
+    cpu_register_physical_memory(PROM_ADDR, 
+                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK, 
+                                 prom_offset | IO_MEM_ROM);
 
     snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE);
-    ret = load_elf(buf, phys_ram_base + prom_offset);
+    ret = load_elf(buf, 0);
     if (ret < 0) {
        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB);
        ret = load_image(buf, phys_ram_base + prom_offset);
@@ -289,13 +293,12 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
                buf);
        exit(1);
     }
-    cpu_register_physical_memory(PROM_ADDR, (ret + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK, 
-                                 prom_offset | IO_MEM_ROM);
 
     kernel_size = 0;
     initrd_size = 0;
     if (linux_boot) {
-        kernel_size = load_elf(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
+        /* XXX: put correct offset */
+        kernel_size = load_elf(kernel_filename, 0);
         if (kernel_size < 0)
            kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
        if (kernel_size < 0)