Statistics
| Branch: | Revision:

root / hw / magic-load.c @ d861b05e

History | View | Annotate | Download (4.6 kB)

1 420557e8 bellard
#include "vl.h"
2 420557e8 bellard
#include "disas.h"
3 e80cfcfc bellard
#include "exec-all.h"
4 e80cfcfc bellard
5 e80cfcfc bellard
struct exec
6 e80cfcfc bellard
{
7 e80cfcfc bellard
  uint32_t a_info;   /* Use macros N_MAGIC, etc for access */
8 e80cfcfc bellard
  uint32_t a_text;   /* length of text, in bytes */
9 e80cfcfc bellard
  uint32_t a_data;   /* length of data, in bytes */
10 e80cfcfc bellard
  uint32_t a_bss;    /* length of uninitialized data area, in bytes */
11 e80cfcfc bellard
  uint32_t a_syms;   /* length of symbol table data in file, in bytes */
12 e80cfcfc bellard
  uint32_t a_entry;  /* start address */
13 e80cfcfc bellard
  uint32_t a_trsize; /* length of relocation info for text, in bytes */
14 e80cfcfc bellard
  uint32_t a_drsize; /* length of relocation info for data, in bytes */
15 e80cfcfc bellard
};
16 e80cfcfc bellard
17 e80cfcfc bellard
#ifdef BSWAP_NEEDED
18 e80cfcfc bellard
static void bswap_ahdr(struct exec *e)
19 e80cfcfc bellard
{
20 e80cfcfc bellard
    bswap32s(&e->a_info);
21 e80cfcfc bellard
    bswap32s(&e->a_text);
22 e80cfcfc bellard
    bswap32s(&e->a_data);
23 e80cfcfc bellard
    bswap32s(&e->a_bss);
24 e80cfcfc bellard
    bswap32s(&e->a_syms);
25 e80cfcfc bellard
    bswap32s(&e->a_entry);
26 e80cfcfc bellard
    bswap32s(&e->a_trsize);
27 e80cfcfc bellard
    bswap32s(&e->a_drsize);
28 e80cfcfc bellard
}
29 e80cfcfc bellard
#else
30 e80cfcfc bellard
#define bswap_ahdr(x) do { } while (0)
31 e80cfcfc bellard
#endif
32 e80cfcfc bellard
33 e80cfcfc bellard
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
34 e80cfcfc bellard
#define OMAGIC 0407
35 e80cfcfc bellard
#define NMAGIC 0410
36 e80cfcfc bellard
#define ZMAGIC 0413
37 e80cfcfc bellard
#define QMAGIC 0314
38 e80cfcfc bellard
#define _N_HDROFF(x) (1024 - sizeof (struct exec))
39 e80cfcfc bellard
#define N_TXTOFF(x)                                                        \
40 e80cfcfc bellard
    (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) :        \
41 e80cfcfc bellard
     (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
42 e80cfcfc bellard
#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? TARGET_PAGE_SIZE : 0)
43 e80cfcfc bellard
#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
44 e80cfcfc bellard
#define _N_SEGMENT_ROUND(x) (((x) + TARGET_PAGE_SIZE - 1) & ~(TARGET_PAGE_SIZE - 1))
45 e80cfcfc bellard
46 e80cfcfc bellard
#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
47 e80cfcfc bellard
48 e80cfcfc bellard
#define N_DATADDR(x) \
49 e80cfcfc bellard
    (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
50 e80cfcfc bellard
     : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
51 e80cfcfc bellard
52 420557e8 bellard
53 420557e8 bellard
#define ELF_CLASS   ELFCLASS32
54 420557e8 bellard
#define ELF_DATA    ELFDATA2MSB
55 420557e8 bellard
#define ELF_ARCH    EM_SPARC
56 420557e8 bellard
57 420557e8 bellard
#include "elf.h"
58 420557e8 bellard
59 3475187d bellard
#ifndef BSWAP_NEEDED
60 3475187d bellard
#define bswap_ehdr32(e) do { } while (0)
61 3475187d bellard
#define bswap_phdr32(e) do { } while (0)
62 3475187d bellard
#define bswap_shdr32(e) do { } while (0)
63 3475187d bellard
#define bswap_sym32(e) do { } while (0)
64 3475187d bellard
#ifdef TARGET_SPARC64
65 3475187d bellard
#define bswap_ehdr64(e) do { } while (0)
66 3475187d bellard
#define bswap_phdr64(e) do { } while (0)
67 3475187d bellard
#define bswap_shdr64(e) do { } while (0)
68 3475187d bellard
#define bswap_sym64(e) do { } while (0)
69 3475187d bellard
#endif
70 420557e8 bellard
#endif
71 420557e8 bellard
72 3475187d bellard
#define SZ                32
73 3475187d bellard
#define elf_word        uint32_t
74 3475187d bellard
#define bswapSZs        bswap32s
75 3475187d bellard
#include "elf_ops.h"
76 3475187d bellard
77 3475187d bellard
#ifdef TARGET_SPARC64
78 3475187d bellard
#undef elfhdr
79 3475187d bellard
#undef elf_phdr
80 3475187d bellard
#undef elf_shdr
81 3475187d bellard
#undef elf_sym
82 3475187d bellard
#undef elf_note
83 3475187d bellard
#undef elf_word
84 3475187d bellard
#undef bswapSZs
85 3475187d bellard
#undef SZ
86 3475187d bellard
#define elfhdr                elf64_hdr
87 3475187d bellard
#define elf_phdr        elf64_phdr
88 3475187d bellard
#define elf_note        elf64_note
89 3475187d bellard
#define elf_shdr        elf64_shdr
90 3475187d bellard
#define elf_sym                elf64_sym
91 3475187d bellard
#define elf_word        uint64_t
92 3475187d bellard
#define bswapSZs        bswap64s
93 3475187d bellard
#define SZ                64
94 3475187d bellard
#include "elf_ops.h"
95 3475187d bellard
#endif
96 420557e8 bellard
97 e80cfcfc bellard
int load_elf(const char *filename, uint8_t *addr)
98 8d5f07fa bellard
{
99 3475187d bellard
    struct elf32_hdr ehdr;
100 8d5f07fa bellard
    int retval, fd;
101 3475187d bellard
    Elf32_Half machine;
102 420557e8 bellard
103 8d5f07fa bellard
    fd = open(filename, O_RDONLY | O_BINARY);
104 8d5f07fa bellard
    if (fd < 0)
105 8d5f07fa bellard
        goto error;
106 420557e8 bellard
107 8d5f07fa bellard
    retval = read(fd, &ehdr, sizeof(ehdr));
108 8d5f07fa bellard
    if (retval < 0)
109 8d5f07fa bellard
        goto error;
110 420557e8 bellard
111 8d5f07fa bellard
    if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E'
112 3475187d bellard
        || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F')
113 8d5f07fa bellard
        goto error;
114 3475187d bellard
    machine = tswap16(ehdr.e_machine);
115 3475187d bellard
    if (machine == EM_SPARC || machine == EM_SPARC32PLUS) {
116 3475187d bellard
        struct elf32_phdr phdr;
117 420557e8 bellard
118 3475187d bellard
        bswap_ehdr32(&ehdr);
119 420557e8 bellard
120 3475187d bellard
        if (find_phdr32(&ehdr, fd, &phdr, PT_LOAD))
121 3475187d bellard
            goto error;
122 3475187d bellard
        retval = read_program32(fd, &phdr, addr, ehdr.e_entry);
123 3475187d bellard
        if (retval < 0)
124 3475187d bellard
            goto error;
125 3475187d bellard
        load_symbols32(&ehdr, fd);
126 3475187d bellard
    }
127 3475187d bellard
#ifdef TARGET_SPARC64
128 3475187d bellard
    else if (machine == EM_SPARCV9) {
129 3475187d bellard
        struct elf64_hdr ehdr64;
130 3475187d bellard
        struct elf64_phdr phdr;
131 3475187d bellard
132 3475187d bellard
        lseek(fd, 0, SEEK_SET);
133 3475187d bellard
134 3475187d bellard
        retval = read(fd, &ehdr64, sizeof(ehdr64));
135 3475187d bellard
        if (retval < 0)
136 3475187d bellard
            goto error;
137 3475187d bellard
138 3475187d bellard
        bswap_ehdr64(&ehdr64);
139 3475187d bellard
140 3475187d bellard
        if (find_phdr64(&ehdr64, fd, &phdr, PT_LOAD))
141 3475187d bellard
            goto error;
142 83469015 bellard
        retval = read_program64(fd, &phdr, phys_ram_base + ehdr64.e_entry, ehdr64.e_entry);
143 3475187d bellard
        if (retval < 0)
144 3475187d bellard
            goto error;
145 3475187d bellard
        load_symbols64(&ehdr64, fd);
146 3475187d bellard
    }
147 3475187d bellard
#endif
148 420557e8 bellard
149 8d5f07fa bellard
    close(fd);
150 8d5f07fa bellard
    return retval;
151 8d5f07fa bellard
 error:
152 8d5f07fa bellard
    close(fd);
153 8d5f07fa bellard
    return -1;
154 420557e8 bellard
}
155 420557e8 bellard
156 e80cfcfc bellard
int load_aout(const char *filename, uint8_t *addr)
157 420557e8 bellard
{
158 e80cfcfc bellard
    int fd, size, ret;
159 e80cfcfc bellard
    struct exec e;
160 e80cfcfc bellard
    uint32_t magic;
161 420557e8 bellard
162 420557e8 bellard
    fd = open(filename, O_RDONLY | O_BINARY);
163 420557e8 bellard
    if (fd < 0)
164 420557e8 bellard
        return -1;
165 e80cfcfc bellard
166 e80cfcfc bellard
    size = read(fd, &e, sizeof(e));
167 420557e8 bellard
    if (size < 0)
168 420557e8 bellard
        goto fail;
169 e80cfcfc bellard
170 e80cfcfc bellard
    bswap_ahdr(&e);
171 e80cfcfc bellard
172 e80cfcfc bellard
    magic = N_MAGIC(e);
173 e80cfcfc bellard
    switch (magic) {
174 e80cfcfc bellard
    case ZMAGIC:
175 e80cfcfc bellard
    case QMAGIC:
176 e80cfcfc bellard
    case OMAGIC:
177 e80cfcfc bellard
        lseek(fd, N_TXTOFF(e), SEEK_SET);
178 e80cfcfc bellard
        size = read(fd, addr, e.a_text + e.a_data);
179 e80cfcfc bellard
        if (size < 0)
180 e80cfcfc bellard
            goto fail;
181 e80cfcfc bellard
        break;
182 e80cfcfc bellard
    case NMAGIC:
183 e80cfcfc bellard
        lseek(fd, N_TXTOFF(e), SEEK_SET);
184 e80cfcfc bellard
        size = read(fd, addr, e.a_text);
185 e80cfcfc bellard
        if (size < 0)
186 e80cfcfc bellard
            goto fail;
187 e80cfcfc bellard
        ret = read(fd, addr + N_DATADDR(e), e.a_data);
188 e80cfcfc bellard
        if (ret < 0)
189 e80cfcfc bellard
            goto fail;
190 e80cfcfc bellard
        size += ret;
191 e80cfcfc bellard
        break;
192 e80cfcfc bellard
    default:
193 e80cfcfc bellard
        goto fail;
194 e80cfcfc bellard
    }
195 420557e8 bellard
    close(fd);
196 420557e8 bellard
    return size;
197 420557e8 bellard
 fail:
198 420557e8 bellard
    close(fd);
199 420557e8 bellard
    return -1;
200 420557e8 bellard
}