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,13 +138,14 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab) | ||
138 | return -1; | 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 | struct elfhdr ehdr; | 144 | struct elfhdr ehdr; |
144 | struct elf_phdr *phdr = NULL, *ph; | 145 | struct elf_phdr *phdr = NULL, *ph; |
145 | int size, i, total_size; | 146 | int size, i, total_size; |
146 | elf_word mem_size, addr; | 147 | elf_word mem_size, addr; |
147 | - uint8_t *data; | 148 | + uint8_t *data = NULL; |
148 | 149 | ||
149 | if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) | 150 | if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) |
150 | goto fail; | 151 | goto fail; |
@@ -152,6 +153,9 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, int must_swab) | @@ -152,6 +153,9 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, int must_swab) | ||
152 | glue(bswap_ehdr, SZ)(&ehdr); | 153 | glue(bswap_ehdr, SZ)(&ehdr); |
153 | } | 154 | } |
154 | 155 | ||
156 | + if (pentry) | ||
157 | + *pentry = (uint64_t)ehdr.e_entry; | ||
158 | + | ||
155 | glue(load_symbols, SZ)(&ehdr, fd, must_swab); | 159 | glue(load_symbols, SZ)(&ehdr, fd, must_swab); |
156 | 160 | ||
157 | size = ehdr.e_phnum * sizeof(phdr[0]); | 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,7 +180,8 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, int must_swab) | ||
176 | /* XXX: avoid allocating */ | 180 | /* XXX: avoid allocating */ |
177 | data = qemu_mallocz(mem_size); | 181 | data = qemu_mallocz(mem_size); |
178 | if (ph->p_filesz > 0) { | 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 | if (read(fd, data, ph->p_filesz) != ph->p_filesz) | 185 | if (read(fd, data, ph->p_filesz) != ph->p_filesz) |
181 | goto fail; | 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,10 +192,12 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, int must_swab) | ||
187 | total_size += mem_size; | 192 | total_size += mem_size; |
188 | 193 | ||
189 | qemu_free(data); | 194 | qemu_free(data); |
195 | + data = NULL; | ||
190 | } | 196 | } |
191 | } | 197 | } |
192 | return total_size; | 198 | return total_size; |
193 | fail: | 199 | fail: |
200 | + qemu_free(data); | ||
194 | qemu_free(phdr); | 201 | qemu_free(phdr); |
195 | return -1; | 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,7 +269,7 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, | ||
269 | prom_offset | IO_MEM_ROM); | 269 | prom_offset | IO_MEM_ROM); |
270 | 270 | ||
271 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE); | 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 | if (ret < 0) { | 273 | if (ret < 0) { |
274 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB); | 274 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB); |
275 | ret = load_image(buf, phys_ram_base + prom_offset); | 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,7 +282,7 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, | ||
282 | 282 | ||
283 | kernel_size = 0; | 283 | kernel_size = 0; |
284 | if (linux_boot) { | 284 | if (linux_boot) { |
285 | - kernel_size = load_elf(kernel_filename, -0xf0000000); | 285 | + kernel_size = load_elf(kernel_filename, -0xf0000000, NULL); |
286 | if (kernel_size < 0) | 286 | if (kernel_size < 0) |
287 | kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR); | 287 | kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR); |
288 | if (kernel_size < 0) | 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,7 +283,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, | ||
283 | prom_offset | IO_MEM_ROM); | 283 | prom_offset | IO_MEM_ROM); |
284 | 284 | ||
285 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE); | 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 | if (ret < 0) { | 287 | if (ret < 0) { |
288 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB); | 288 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB); |
289 | ret = load_image(buf, phys_ram_base + prom_offset); | 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,7 +298,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, | ||
298 | initrd_size = 0; | 298 | initrd_size = 0; |
299 | if (linux_boot) { | 299 | if (linux_boot) { |
300 | /* XXX: put correct offset */ | 300 | /* XXX: put correct offset */ |
301 | - kernel_size = load_elf(kernel_filename, 0); | 301 | + kernel_size = load_elf(kernel_filename, 0, NULL); |
302 | if (kernel_size < 0) | 302 | if (kernel_size < 0) |
303 | kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR); | 303 | kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR); |
304 | if (kernel_size < 0) | 304 | if (kernel_size < 0) |
loader.c
@@ -194,7 +194,8 @@ static void *load_at(int fd, int offset, int size) | @@ -194,7 +194,8 @@ static void *load_at(int fd, int offset, int size) | ||
194 | #include "elf_ops.h" | 194 | #include "elf_ops.h" |
195 | 195 | ||
196 | /* return < 0 if error, otherwise the number of bytes loaded in memory */ | 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 | int fd, data_order, must_swab, ret; | 200 | int fd, data_order, must_swab, ret; |
200 | uint8_t e_ident[EI_NIDENT]; | 201 | uint8_t e_ident[EI_NIDENT]; |
@@ -220,9 +221,9 @@ int load_elf(const char *filename, int64_t virt_to_phys_addend) | @@ -220,9 +221,9 @@ int load_elf(const char *filename, int64_t virt_to_phys_addend) | ||
220 | 221 | ||
221 | lseek(fd, 0, SEEK_SET); | 222 | lseek(fd, 0, SEEK_SET); |
222 | if (e_ident[EI_CLASS] == ELFCLASS64) { | 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 | } else { | 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 | close(fd); | 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,7 +878,7 @@ void slavio_pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu); | ||
878 | /* loader.c */ | 878 | /* loader.c */ |
879 | int get_image_size(const char *filename); | 879 | int get_image_size(const char *filename); |
880 | int load_image(const char *filename, uint8_t *addr); | 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 | int load_aout(const char *filename, uint8_t *addr); | 882 | int load_aout(const char *filename, uint8_t *addr); |
883 | 883 | ||
884 | /* slavio_timer.c */ | 884 | /* slavio_timer.c */ |