root / hw / magic-load.c @ d861b05e
History | View | Annotate | Download (4.6 kB)
1 |
#include "vl.h" |
---|---|
2 |
#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
|
54 |
#define ELF_DATA ELFDATA2MSB
|
55 |
#define ELF_ARCH EM_SPARC
|
56 |
|
57 |
#include "elf.h" |
58 |
|
59 |
#ifndef BSWAP_NEEDED
|
60 |
#define bswap_ehdr32(e) do { } while (0) |
61 |
#define bswap_phdr32(e) do { } while (0) |
62 |
#define bswap_shdr32(e) do { } while (0) |
63 |
#define bswap_sym32(e) do { } while (0) |
64 |
#ifdef TARGET_SPARC64
|
65 |
#define bswap_ehdr64(e) do { } while (0) |
66 |
#define bswap_phdr64(e) do { } while (0) |
67 |
#define bswap_shdr64(e) do { } while (0) |
68 |
#define bswap_sym64(e) do { } while (0) |
69 |
#endif
|
70 |
#endif
|
71 |
|
72 |
#define SZ 32 |
73 |
#define elf_word uint32_t
|
74 |
#define bswapSZs bswap32s
|
75 |
#include "elf_ops.h" |
76 |
|
77 |
#ifdef TARGET_SPARC64
|
78 |
#undef elfhdr
|
79 |
#undef elf_phdr
|
80 |
#undef elf_shdr
|
81 |
#undef elf_sym
|
82 |
#undef elf_note
|
83 |
#undef elf_word
|
84 |
#undef bswapSZs
|
85 |
#undef SZ
|
86 |
#define elfhdr elf64_hdr
|
87 |
#define elf_phdr elf64_phdr
|
88 |
#define elf_note elf64_note
|
89 |
#define elf_shdr elf64_shdr
|
90 |
#define elf_sym elf64_sym
|
91 |
#define elf_word uint64_t
|
92 |
#define bswapSZs bswap64s
|
93 |
#define SZ 64 |
94 |
#include "elf_ops.h" |
95 |
#endif
|
96 |
|
97 |
int load_elf(const char *filename, uint8_t *addr) |
98 |
{ |
99 |
struct elf32_hdr ehdr;
|
100 |
int retval, fd;
|
101 |
Elf32_Half machine; |
102 |
|
103 |
fd = open(filename, O_RDONLY | O_BINARY); |
104 |
if (fd < 0) |
105 |
goto error;
|
106 |
|
107 |
retval = read(fd, &ehdr, sizeof(ehdr));
|
108 |
if (retval < 0) |
109 |
goto error;
|
110 |
|
111 |
if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E' |
112 |
|| ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F') |
113 |
goto error;
|
114 |
machine = tswap16(ehdr.e_machine); |
115 |
if (machine == EM_SPARC || machine == EM_SPARC32PLUS) {
|
116 |
struct elf32_phdr phdr;
|
117 |
|
118 |
bswap_ehdr32(&ehdr); |
119 |
|
120 |
if (find_phdr32(&ehdr, fd, &phdr, PT_LOAD))
|
121 |
goto error;
|
122 |
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 |
bswap_ehdr64(&ehdr64); |
139 |
|
140 |
if (find_phdr64(&ehdr64, fd, &phdr, PT_LOAD))
|
141 |
goto error;
|
142 |
retval = read_program64(fd, &phdr, phys_ram_base + ehdr64.e_entry, ehdr64.e_entry); |
143 |
if (retval < 0) |
144 |
goto error;
|
145 |
load_symbols64(&ehdr64, fd); |
146 |
} |
147 |
#endif
|
148 |
|
149 |
close(fd); |
150 |
return retval;
|
151 |
error:
|
152 |
close(fd); |
153 |
return -1; |
154 |
} |
155 |
|
156 |
int load_aout(const char *filename, uint8_t *addr) |
157 |
{ |
158 |
int fd, size, ret;
|
159 |
struct exec e;
|
160 |
uint32_t magic; |
161 |
|
162 |
fd = open(filename, O_RDONLY | O_BINARY); |
163 |
if (fd < 0) |
164 |
return -1; |
165 |
|
166 |
size = read(fd, &e, sizeof(e));
|
167 |
if (size < 0) |
168 |
goto fail;
|
169 |
|
170 |
bswap_ahdr(&e); |
171 |
|
172 |
magic = N_MAGIC(e); |
173 |
switch (magic) {
|
174 |
case ZMAGIC:
|
175 |
case QMAGIC:
|
176 |
case OMAGIC:
|
177 |
lseek(fd, N_TXTOFF(e), SEEK_SET); |
178 |
size = read(fd, addr, e.a_text + e.a_data); |
179 |
if (size < 0) |
180 |
goto fail;
|
181 |
break;
|
182 |
case NMAGIC:
|
183 |
lseek(fd, N_TXTOFF(e), SEEK_SET); |
184 |
size = read(fd, addr, e.a_text); |
185 |
if (size < 0) |
186 |
goto fail;
|
187 |
ret = read(fd, addr + N_DATADDR(e), e.a_data); |
188 |
if (ret < 0) |
189 |
goto fail;
|
190 |
size += ret; |
191 |
break;
|
192 |
default:
|
193 |
goto fail;
|
194 |
} |
195 |
close(fd); |
196 |
return size;
|
197 |
fail:
|
198 |
close(fd); |
199 |
return -1; |
200 |
} |
201 |
|