Commit 9ee3c029425a20ed16831c92c4cb3e192a909a61
1 parent
94ac5158
added entry parameter to ELF loader
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1859 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
19 additions
and
11 deletions
elf_ops.h
... | ... | @@ -138,13 +138,14 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab) |
138 | 138 | return -1; |
139 | 139 | } |
140 | 140 | |
141 | -int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, int must_swab) | |
141 | +int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, | |
142 | + int must_swab, uint64_t *pentry) | |
142 | 143 | { |
143 | 144 | struct elfhdr ehdr; |
144 | 145 | struct elf_phdr *phdr = NULL, *ph; |
145 | 146 | int size, i, total_size; |
146 | 147 | elf_word mem_size, addr; |
147 | - uint8_t *data; | |
148 | + uint8_t *data = NULL; | |
148 | 149 | |
149 | 150 | if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) |
150 | 151 | goto fail; |
... | ... | @@ -152,6 +153,9 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, int must_swab) |
152 | 153 | glue(bswap_ehdr, SZ)(&ehdr); |
153 | 154 | } |
154 | 155 | |
156 | + if (pentry) | |
157 | + *pentry = (uint64_t)ehdr.e_entry; | |
158 | + | |
155 | 159 | glue(load_symbols, SZ)(&ehdr, fd, must_swab); |
156 | 160 | |
157 | 161 | size = ehdr.e_phnum * sizeof(phdr[0]); |
... | ... | @@ -176,7 +180,8 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, int must_swab) |
176 | 180 | /* XXX: avoid allocating */ |
177 | 181 | data = qemu_mallocz(mem_size); |
178 | 182 | if (ph->p_filesz > 0) { |
179 | - lseek(fd, ph->p_offset, SEEK_SET); | |
183 | + if (lseek(fd, ph->p_offset, SEEK_SET) < 0) | |
184 | + goto fail; | |
180 | 185 | if (read(fd, data, ph->p_filesz) != ph->p_filesz) |
181 | 186 | goto fail; |
182 | 187 | } |
... | ... | @@ -187,10 +192,12 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, int must_swab) |
187 | 192 | total_size += mem_size; |
188 | 193 | |
189 | 194 | qemu_free(data); |
195 | + data = NULL; | |
190 | 196 | } |
191 | 197 | } |
192 | 198 | return total_size; |
193 | 199 | fail: |
200 | + qemu_free(data); | |
194 | 201 | qemu_free(phdr); |
195 | 202 | return -1; |
196 | 203 | } | ... | ... |
hw/sun4m.c
... | ... | @@ -269,7 +269,7 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, |
269 | 269 | prom_offset | IO_MEM_ROM); |
270 | 270 | |
271 | 271 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE); |
272 | - ret = load_elf(buf, 0); | |
272 | + ret = load_elf(buf, 0, NULL); | |
273 | 273 | if (ret < 0) { |
274 | 274 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB); |
275 | 275 | ret = load_image(buf, phys_ram_base + prom_offset); |
... | ... | @@ -282,7 +282,7 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, |
282 | 282 | |
283 | 283 | kernel_size = 0; |
284 | 284 | if (linux_boot) { |
285 | - kernel_size = load_elf(kernel_filename, -0xf0000000); | |
285 | + kernel_size = load_elf(kernel_filename, -0xf0000000, NULL); | |
286 | 286 | if (kernel_size < 0) |
287 | 287 | kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR); |
288 | 288 | if (kernel_size < 0) | ... | ... |
hw/sun4u.c
... | ... | @@ -283,7 +283,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, |
283 | 283 | prom_offset | IO_MEM_ROM); |
284 | 284 | |
285 | 285 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE); |
286 | - ret = load_elf(buf, 0); | |
286 | + ret = load_elf(buf, 0, NULL); | |
287 | 287 | if (ret < 0) { |
288 | 288 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB); |
289 | 289 | ret = load_image(buf, phys_ram_base + prom_offset); |
... | ... | @@ -298,7 +298,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, |
298 | 298 | initrd_size = 0; |
299 | 299 | if (linux_boot) { |
300 | 300 | /* XXX: put correct offset */ |
301 | - kernel_size = load_elf(kernel_filename, 0); | |
301 | + kernel_size = load_elf(kernel_filename, 0, NULL); | |
302 | 302 | if (kernel_size < 0) |
303 | 303 | kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR); |
304 | 304 | if (kernel_size < 0) | ... | ... |
loader.c
... | ... | @@ -194,7 +194,8 @@ static void *load_at(int fd, int offset, int size) |
194 | 194 | #include "elf_ops.h" |
195 | 195 | |
196 | 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) | |
197 | +int load_elf(const char *filename, int64_t virt_to_phys_addend, | |
198 | + uint64_t *pentry) | |
198 | 199 | { |
199 | 200 | int fd, data_order, must_swab, ret; |
200 | 201 | uint8_t e_ident[EI_NIDENT]; |
... | ... | @@ -220,9 +221,9 @@ int load_elf(const char *filename, int64_t virt_to_phys_addend) |
220 | 221 | |
221 | 222 | lseek(fd, 0, SEEK_SET); |
222 | 223 | if (e_ident[EI_CLASS] == ELFCLASS64) { |
223 | - ret = load_elf64(fd, virt_to_phys_addend, must_swab); | |
224 | + ret = load_elf64(fd, virt_to_phys_addend, must_swab, pentry); | |
224 | 225 | } else { |
225 | - ret = load_elf32(fd, virt_to_phys_addend, must_swab); | |
226 | + ret = load_elf32(fd, virt_to_phys_addend, must_swab, pentry); | |
226 | 227 | } |
227 | 228 | |
228 | 229 | close(fd); | ... | ... |
vl.h
... | ... | @@ -878,7 +878,7 @@ void slavio_pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu); |
878 | 878 | /* loader.c */ |
879 | 879 | int get_image_size(const char *filename); |
880 | 880 | int load_image(const char *filename, uint8_t *addr); |
881 | -int load_elf(const char *filename, int64_t virt_to_phys_addend); | |
881 | +int load_elf(const char *filename, int64_t virt_to_phys_addend, uint64_t *pentry); | |
882 | 882 | int load_aout(const char *filename, uint8_t *addr); |
883 | 883 | |
884 | 884 | /* slavio_timer.c */ | ... | ... |