Commit 5fe141fd30d35516eac3674f7b62be51ba34543f
1 parent
ce2f4b3c
generic ELF loader
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1831 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
439 additions
and
36 deletions
Makefile.target
... | ... | @@ -270,7 +270,7 @@ ifeq ($(ARCH),alpha) |
270 | 270 | endif |
271 | 271 | |
272 | 272 | # must use static linking to avoid leaving stuff in virtual address space |
273 | -VL_OBJS=vl.o osdep.o block.o readline.o monitor.o pci.o console.o | |
273 | +VL_OBJS=vl.o osdep.o block.o readline.o monitor.o pci.o console.o loader.o | |
274 | 274 | VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o block-vpc.o block-vvfat.o |
275 | 275 | ifdef CONFIG_WIN32 |
276 | 276 | VL_OBJS+=tap-win32.o |
... | ... | @@ -332,9 +332,8 @@ ifeq ($(TARGET_ARCH), sparc64) |
332 | 332 | VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o |
333 | 333 | VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o |
334 | 334 | VL_OBJS+= cirrus_vga.o parallel.o |
335 | -VL_OBJS+= magic-load.o | |
336 | 335 | else |
337 | -VL_OBJS+= sun4m.o tcx.o lance.o iommu.o m48t59.o magic-load.o slavio_intctl.o | |
336 | +VL_OBJS+= sun4m.o tcx.o lance.o iommu.o m48t59.o slavio_intctl.o | |
338 | 337 | VL_OBJS+= slavio_timer.o slavio_serial.o slavio_misc.o fdc.o esp.o |
339 | 338 | endif |
340 | 339 | endif |
... | ... | @@ -459,6 +458,8 @@ op.o: op.c op_template.c op_mem.c |
459 | 458 | op_helper.o: op_helper_mem.c |
460 | 459 | endif |
461 | 460 | |
461 | +loader.o: loader.c elf_ops.h | |
462 | + | |
462 | 463 | %.o: %.c |
463 | 464 | $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $< |
464 | 465 | ... | ... |
elf_ops.h
0 → 100644
1 | +static void glue(bswap_ehdr, SZ)(struct elfhdr *ehdr) | |
2 | +{ | |
3 | + bswap16s(&ehdr->e_type); /* Object file type */ | |
4 | + bswap16s(&ehdr->e_machine); /* Architecture */ | |
5 | + bswap32s(&ehdr->e_version); /* Object file version */ | |
6 | + bswapSZs(&ehdr->e_entry); /* Entry point virtual address */ | |
7 | + bswapSZs(&ehdr->e_phoff); /* Program header table file offset */ | |
8 | + bswapSZs(&ehdr->e_shoff); /* Section header table file offset */ | |
9 | + bswap32s(&ehdr->e_flags); /* Processor-specific flags */ | |
10 | + bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */ | |
11 | + bswap16s(&ehdr->e_phentsize); /* Program header table entry size */ | |
12 | + bswap16s(&ehdr->e_phnum); /* Program header table entry count */ | |
13 | + bswap16s(&ehdr->e_shentsize); /* Section header table entry size */ | |
14 | + bswap16s(&ehdr->e_shnum); /* Section header table entry count */ | |
15 | + bswap16s(&ehdr->e_shstrndx); /* Section header string table index */ | |
16 | +} | |
17 | + | |
18 | +static void glue(bswap_phdr, SZ)(struct elf_phdr *phdr) | |
19 | +{ | |
20 | + bswap32s(&phdr->p_type); /* Segment type */ | |
21 | + bswapSZs(&phdr->p_offset); /* Segment file offset */ | |
22 | + bswapSZs(&phdr->p_vaddr); /* Segment virtual address */ | |
23 | + bswapSZs(&phdr->p_paddr); /* Segment physical address */ | |
24 | + bswapSZs(&phdr->p_filesz); /* Segment size in file */ | |
25 | + bswapSZs(&phdr->p_memsz); /* Segment size in memory */ | |
26 | + bswap32s(&phdr->p_flags); /* Segment flags */ | |
27 | + bswapSZs(&phdr->p_align); /* Segment alignment */ | |
28 | +} | |
29 | + | |
30 | +static void glue(bswap_shdr, SZ)(struct elf_shdr *shdr) | |
31 | +{ | |
32 | + bswap32s(&shdr->sh_name); | |
33 | + bswap32s(&shdr->sh_type); | |
34 | + bswapSZs(&shdr->sh_flags); | |
35 | + bswapSZs(&shdr->sh_addr); | |
36 | + bswapSZs(&shdr->sh_offset); | |
37 | + bswapSZs(&shdr->sh_size); | |
38 | + bswap32s(&shdr->sh_link); | |
39 | + bswap32s(&shdr->sh_info); | |
40 | + bswapSZs(&shdr->sh_addralign); | |
41 | + bswapSZs(&shdr->sh_entsize); | |
42 | +} | |
43 | + | |
44 | +static void glue(bswap_sym, SZ)(struct elf_sym *sym) | |
45 | +{ | |
46 | + bswap32s(&sym->st_name); | |
47 | + bswapSZs(&sym->st_value); | |
48 | + bswapSZs(&sym->st_size); | |
49 | + bswap16s(&sym->st_shndx); | |
50 | +} | |
51 | + | |
52 | +static struct elf_shdr *glue(find_section, SZ)(struct elf_shdr *shdr_table, | |
53 | + int n, int type) | |
54 | +{ | |
55 | + int i; | |
56 | + for(i=0;i<n;i++) { | |
57 | + if (shdr_table[i].sh_type == type) | |
58 | + return shdr_table + i; | |
59 | + } | |
60 | + return NULL; | |
61 | +} | |
62 | + | |
63 | +static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab) | |
64 | +{ | |
65 | + struct elf_shdr *symtab, *strtab, *shdr_table = NULL; | |
66 | + struct elf_sym *syms = NULL; | |
67 | +#if (SZ == 64) | |
68 | + struct elf32_sym *syms32 = NULL; | |
69 | +#endif | |
70 | + struct syminfo *s; | |
71 | + int nsyms, i; | |
72 | + char *str = NULL; | |
73 | + | |
74 | + shdr_table = load_at(fd, ehdr->e_shoff, | |
75 | + sizeof(struct elf_shdr) * ehdr->e_shnum); | |
76 | + if (!shdr_table) | |
77 | + return -1; | |
78 | + | |
79 | + if (must_swab) { | |
80 | + for (i = 0; i < ehdr->e_shnum; i++) { | |
81 | + glue(bswap_shdr, SZ)(shdr_table + i); | |
82 | + } | |
83 | + } | |
84 | + | |
85 | + symtab = glue(find_section, SZ)(shdr_table, ehdr->e_shnum, SHT_SYMTAB); | |
86 | + if (!symtab) | |
87 | + goto fail; | |
88 | + syms = load_at(fd, symtab->sh_offset, symtab->sh_size); | |
89 | + if (!syms) | |
90 | + goto fail; | |
91 | + | |
92 | + nsyms = symtab->sh_size / sizeof(struct elf_sym); | |
93 | +#if (SZ == 64) | |
94 | + syms32 = qemu_mallocz(nsyms * sizeof(struct elf32_sym)); | |
95 | +#endif | |
96 | + for (i = 0; i < nsyms; i++) { | |
97 | + if (must_swab) | |
98 | + glue(bswap_sym, SZ)(&syms[i]); | |
99 | +#if (SZ == 64) | |
100 | + syms32[i].st_name = syms[i].st_name; | |
101 | + syms32[i].st_info = syms[i].st_info; | |
102 | + syms32[i].st_other = syms[i].st_other; | |
103 | + syms32[i].st_shndx = syms[i].st_shndx; | |
104 | + syms32[i].st_value = syms[i].st_value & 0xffffffff; | |
105 | + syms32[i].st_size = syms[i].st_size & 0xffffffff; | |
106 | +#endif | |
107 | + } | |
108 | + /* String table */ | |
109 | + if (symtab->sh_link >= ehdr->e_shnum) | |
110 | + goto fail; | |
111 | + strtab = &shdr_table[symtab->sh_link]; | |
112 | + | |
113 | + str = load_at(fd, strtab->sh_offset, strtab->sh_size); | |
114 | + if (!str) | |
115 | + goto fail; | |
116 | + | |
117 | + /* Commit */ | |
118 | + s = qemu_mallocz(sizeof(*s)); | |
119 | +#if (SZ == 64) | |
120 | + s->disas_symtab = syms32; | |
121 | + qemu_free(syms); | |
122 | +#else | |
123 | + s->disas_symtab = syms; | |
124 | +#endif | |
125 | + s->disas_num_syms = nsyms; | |
126 | + s->disas_strtab = str; | |
127 | + s->next = syminfos; | |
128 | + syminfos = s; | |
129 | + qemu_free(shdr_table); | |
130 | + return 0; | |
131 | + fail: | |
132 | +#if (SZ == 64) | |
133 | + qemu_free(syms32); | |
134 | +#endif | |
135 | + qemu_free(syms); | |
136 | + qemu_free(str); | |
137 | + qemu_free(shdr_table); | |
138 | + return -1; | |
139 | +} | |
140 | + | |
141 | +int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, int must_swab) | |
142 | +{ | |
143 | + struct elfhdr ehdr; | |
144 | + struct elf_phdr *phdr = NULL, *ph; | |
145 | + int size, i, total_size; | |
146 | + elf_word mem_size, addr; | |
147 | + uint8_t *data; | |
148 | + | |
149 | + if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) | |
150 | + goto fail; | |
151 | + if (must_swab) { | |
152 | + glue(bswap_ehdr, SZ)(&ehdr); | |
153 | + } | |
154 | + | |
155 | + glue(load_symbols, SZ)(&ehdr, fd, must_swab); | |
156 | + | |
157 | + size = ehdr.e_phnum * sizeof(phdr[0]); | |
158 | + lseek(fd, ehdr.e_phoff, SEEK_SET); | |
159 | + phdr = qemu_mallocz(size); | |
160 | + if (!phdr) | |
161 | + goto fail; | |
162 | + if (read(fd, phdr, size) != size) | |
163 | + goto fail; | |
164 | + if (must_swab) { | |
165 | + for(i = 0; i < ehdr.e_phnum; i++) { | |
166 | + ph = &phdr[i]; | |
167 | + glue(bswap_phdr, SZ)(ph); | |
168 | + } | |
169 | + } | |
170 | + | |
171 | + total_size = 0; | |
172 | + for(i = 0; i < ehdr.e_phnum; i++) { | |
173 | + ph = &phdr[i]; | |
174 | + if (ph->p_type == PT_LOAD) { | |
175 | + mem_size = ph->p_memsz; | |
176 | + /* XXX: avoid allocating */ | |
177 | + data = qemu_mallocz(mem_size); | |
178 | + if (ph->p_filesz > 0) { | |
179 | + lseek(fd, ph->p_offset, SEEK_SET); | |
180 | + if (read(fd, data, ph->p_filesz) != ph->p_filesz) | |
181 | + goto fail; | |
182 | + } | |
183 | + addr = ph->p_vaddr + virt_to_phys_addend; | |
184 | + | |
185 | + cpu_physical_memory_write_rom(addr, data, mem_size); | |
186 | + | |
187 | + total_size += mem_size; | |
188 | + | |
189 | + qemu_free(data); | |
190 | + } | |
191 | + } | |
192 | + return total_size; | |
193 | + fail: | |
194 | + qemu_free(phdr); | |
195 | + return -1; | |
196 | +} | |
197 | + | ... | ... |
loader.c
0 → 100644
1 | +/* | |
2 | + * QEMU Executable loader | |
3 | + * | |
4 | + * Copyright (c) 2006 Fabrice Bellard | |
5 | + * | |
6 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | |
7 | + * of this software and associated documentation files (the "Software"), to deal | |
8 | + * in the Software without restriction, including without limitation the rights | |
9 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
10 | + * copies of the Software, and to permit persons to whom the Software is | |
11 | + * furnished to do so, subject to the following conditions: | |
12 | + * | |
13 | + * The above copyright notice and this permission notice shall be included in | |
14 | + * all copies or substantial portions of the Software. | |
15 | + * | |
16 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
17 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
18 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
19 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
20 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
22 | + * THE SOFTWARE. | |
23 | + */ | |
24 | +#include "vl.h" | |
25 | +#include "disas.h" | |
26 | + | |
27 | +/* return the size or -1 if error */ | |
28 | +int get_image_size(const char *filename) | |
29 | +{ | |
30 | + int fd, size; | |
31 | + fd = open(filename, O_RDONLY | O_BINARY); | |
32 | + if (fd < 0) | |
33 | + return -1; | |
34 | + size = lseek(fd, 0, SEEK_END); | |
35 | + close(fd); | |
36 | + return size; | |
37 | +} | |
38 | + | |
39 | +/* return the size or -1 if error */ | |
40 | +int load_image(const char *filename, uint8_t *addr) | |
41 | +{ | |
42 | + int fd, size; | |
43 | + fd = open(filename, O_RDONLY | O_BINARY); | |
44 | + if (fd < 0) | |
45 | + return -1; | |
46 | + size = lseek(fd, 0, SEEK_END); | |
47 | + lseek(fd, 0, SEEK_SET); | |
48 | + if (read(fd, addr, size) != size) { | |
49 | + close(fd); | |
50 | + return -1; | |
51 | + } | |
52 | + close(fd); | |
53 | + return size; | |
54 | +} | |
55 | + | |
56 | +/* A.OUT loader */ | |
57 | + | |
58 | +struct exec | |
59 | +{ | |
60 | + uint32_t a_info; /* Use macros N_MAGIC, etc for access */ | |
61 | + uint32_t a_text; /* length of text, in bytes */ | |
62 | + uint32_t a_data; /* length of data, in bytes */ | |
63 | + uint32_t a_bss; /* length of uninitialized data area, in bytes */ | |
64 | + uint32_t a_syms; /* length of symbol table data in file, in bytes */ | |
65 | + uint32_t a_entry; /* start address */ | |
66 | + uint32_t a_trsize; /* length of relocation info for text, in bytes */ | |
67 | + uint32_t a_drsize; /* length of relocation info for data, in bytes */ | |
68 | +}; | |
69 | + | |
70 | +#ifdef BSWAP_NEEDED | |
71 | +static void bswap_ahdr(struct exec *e) | |
72 | +{ | |
73 | + bswap32s(&e->a_info); | |
74 | + bswap32s(&e->a_text); | |
75 | + bswap32s(&e->a_data); | |
76 | + bswap32s(&e->a_bss); | |
77 | + bswap32s(&e->a_syms); | |
78 | + bswap32s(&e->a_entry); | |
79 | + bswap32s(&e->a_trsize); | |
80 | + bswap32s(&e->a_drsize); | |
81 | +} | |
82 | +#else | |
83 | +#define bswap_ahdr(x) do { } while (0) | |
84 | +#endif | |
85 | + | |
86 | +#define N_MAGIC(exec) ((exec).a_info & 0xffff) | |
87 | +#define OMAGIC 0407 | |
88 | +#define NMAGIC 0410 | |
89 | +#define ZMAGIC 0413 | |
90 | +#define QMAGIC 0314 | |
91 | +#define _N_HDROFF(x) (1024 - sizeof (struct exec)) | |
92 | +#define N_TXTOFF(x) \ | |
93 | + (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \ | |
94 | + (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec))) | |
95 | +#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? TARGET_PAGE_SIZE : 0) | |
96 | +#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text) | |
97 | +#define _N_SEGMENT_ROUND(x) (((x) + TARGET_PAGE_SIZE - 1) & ~(TARGET_PAGE_SIZE - 1)) | |
98 | + | |
99 | +#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text) | |
100 | + | |
101 | +#define N_DATADDR(x) \ | |
102 | + (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \ | |
103 | + : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x)))) | |
104 | + | |
105 | + | |
106 | +int load_aout(const char *filename, uint8_t *addr) | |
107 | +{ | |
108 | + int fd, size, ret; | |
109 | + struct exec e; | |
110 | + uint32_t magic; | |
111 | + | |
112 | + fd = open(filename, O_RDONLY | O_BINARY); | |
113 | + if (fd < 0) | |
114 | + return -1; | |
115 | + | |
116 | + size = read(fd, &e, sizeof(e)); | |
117 | + if (size < 0) | |
118 | + goto fail; | |
119 | + | |
120 | + bswap_ahdr(&e); | |
121 | + | |
122 | + magic = N_MAGIC(e); | |
123 | + switch (magic) { | |
124 | + case ZMAGIC: | |
125 | + case QMAGIC: | |
126 | + case OMAGIC: | |
127 | + lseek(fd, N_TXTOFF(e), SEEK_SET); | |
128 | + size = read(fd, addr, e.a_text + e.a_data); | |
129 | + if (size < 0) | |
130 | + goto fail; | |
131 | + break; | |
132 | + case NMAGIC: | |
133 | + lseek(fd, N_TXTOFF(e), SEEK_SET); | |
134 | + size = read(fd, addr, e.a_text); | |
135 | + if (size < 0) | |
136 | + goto fail; | |
137 | + ret = read(fd, addr + N_DATADDR(e), e.a_data); | |
138 | + if (ret < 0) | |
139 | + goto fail; | |
140 | + size += ret; | |
141 | + break; | |
142 | + default: | |
143 | + goto fail; | |
144 | + } | |
145 | + close(fd); | |
146 | + return size; | |
147 | + fail: | |
148 | + close(fd); | |
149 | + return -1; | |
150 | +} | |
151 | + | |
152 | +/* ELF loader */ | |
153 | + | |
154 | +static void *load_at(int fd, int offset, int size) | |
155 | +{ | |
156 | + void *ptr; | |
157 | + if (lseek(fd, offset, SEEK_SET) < 0) | |
158 | + return NULL; | |
159 | + ptr = qemu_malloc(size); | |
160 | + if (!ptr) | |
161 | + return NULL; | |
162 | + if (read(fd, ptr, size) != size) { | |
163 | + qemu_free(ptr); | |
164 | + return NULL; | |
165 | + } | |
166 | + return ptr; | |
167 | +} | |
168 | + | |
169 | + | |
170 | +#define ELF_CLASS ELFCLASS32 | |
171 | +#include "elf.h" | |
172 | + | |
173 | +#define SZ 32 | |
174 | +#define elf_word uint32_t | |
175 | +#define bswapSZs bswap32s | |
176 | +#include "elf_ops.h" | |
177 | + | |
178 | +#undef elfhdr | |
179 | +#undef elf_phdr | |
180 | +#undef elf_shdr | |
181 | +#undef elf_sym | |
182 | +#undef elf_note | |
183 | +#undef elf_word | |
184 | +#undef bswapSZs | |
185 | +#undef SZ | |
186 | +#define elfhdr elf64_hdr | |
187 | +#define elf_phdr elf64_phdr | |
188 | +#define elf_note elf64_note | |
189 | +#define elf_shdr elf64_shdr | |
190 | +#define elf_sym elf64_sym | |
191 | +#define elf_word uint64_t | |
192 | +#define bswapSZs bswap64s | |
193 | +#define SZ 64 | |
194 | +#include "elf_ops.h" | |
195 | + | |
196 | +/* return < 0 if error, otherwise the number of bytes loaded in memory */ | |
197 | +int load_elf(const char *filename, int64_t virt_to_phys_addend) | |
198 | +{ | |
199 | + int fd, data_order, must_swab, ret; | |
200 | + uint8_t e_ident[EI_NIDENT]; | |
201 | + | |
202 | + fd = open(filename, O_RDONLY); | |
203 | + if (fd < 0) { | |
204 | + perror(filename); | |
205 | + return -1; | |
206 | + } | |
207 | + if (read(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident)) | |
208 | + goto fail; | |
209 | + if (e_ident[0] != ELFMAG0 || | |
210 | + e_ident[1] != ELFMAG1 || | |
211 | + e_ident[2] != ELFMAG2 || | |
212 | + e_ident[3] != ELFMAG3) | |
213 | + goto fail; | |
214 | +#ifdef WORDS_BIGENDIAN | |
215 | + data_order = ELFDATA2MSB; | |
216 | +#else | |
217 | + data_order = ELFDATA2LSB; | |
218 | +#endif | |
219 | + must_swab = data_order != e_ident[EI_DATA]; | |
220 | + | |
221 | + lseek(fd, 0, SEEK_SET); | |
222 | + if (e_ident[EI_CLASS] == ELFCLASS64) { | |
223 | + ret = load_elf64(fd, virt_to_phys_addend, must_swab); | |
224 | + } else { | |
225 | + ret = load_elf32(fd, virt_to_phys_addend, must_swab); | |
226 | + } | |
227 | + | |
228 | + close(fd); | |
229 | + return ret; | |
230 | + | |
231 | + fail: | |
232 | + close(fd); | |
233 | + return -1; | |
234 | +} | ... | ... |
vl.c
... | ... | @@ -332,35 +332,6 @@ int strstart(const char *str, const char *val, const char **ptr) |
332 | 332 | return 1; |
333 | 333 | } |
334 | 334 | |
335 | -/* return the size or -1 if error */ | |
336 | -int get_image_size(const char *filename) | |
337 | -{ | |
338 | - int fd, size; | |
339 | - fd = open(filename, O_RDONLY | O_BINARY); | |
340 | - if (fd < 0) | |
341 | - return -1; | |
342 | - size = lseek(fd, 0, SEEK_END); | |
343 | - close(fd); | |
344 | - return size; | |
345 | -} | |
346 | - | |
347 | -/* return the size or -1 if error */ | |
348 | -int load_image(const char *filename, uint8_t *addr) | |
349 | -{ | |
350 | - int fd, size; | |
351 | - fd = open(filename, O_RDONLY | O_BINARY); | |
352 | - if (fd < 0) | |
353 | - return -1; | |
354 | - size = lseek(fd, 0, SEEK_END); | |
355 | - lseek(fd, 0, SEEK_SET); | |
356 | - if (read(fd, addr, size) != size) { | |
357 | - close(fd); | |
358 | - return -1; | |
359 | - } | |
360 | - close(fd); | |
361 | - return size; | |
362 | -} | |
363 | - | |
364 | 335 | void cpu_outb(CPUState *env, int addr, int val) |
365 | 336 | { |
366 | 337 | #ifdef DEBUG_IOPORT | ... | ... |
vl.h
... | ... | @@ -87,8 +87,6 @@ uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c); |
87 | 87 | |
88 | 88 | void hw_error(const char *fmt, ...); |
89 | 89 | |
90 | -int get_image_size(const char *filename); | |
91 | -int load_image(const char *filename, uint8_t *addr); | |
92 | 90 | extern const char *bios_dir; |
93 | 91 | |
94 | 92 | void pstrcpy(char *buf, int buf_size, const char *str); |
... | ... | @@ -871,8 +869,10 @@ void slavio_irq_info(void *opaque); |
871 | 869 | void slavio_pic_set_irq(void *opaque, int irq, int level); |
872 | 870 | void slavio_pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu); |
873 | 871 | |
874 | -/* magic-load.c */ | |
875 | -int load_elf(const char *filename, uint8_t *addr); | |
872 | +/* loader.c */ | |
873 | +int get_image_size(const char *filename); | |
874 | +int load_image(const char *filename, uint8_t *addr); | |
875 | +int load_elf(const char *filename, int64_t virt_to_phys_addend); | |
876 | 876 | int load_aout(const char *filename, uint8_t *addr); |
877 | 877 | |
878 | 878 | /* slavio_timer.c */ | ... | ... |