1 /* This is the Linux kernel elf-loading code, ported into user space */
5 /* XXX: this code is not used as it is under the GPL license. Please
7 //#define USE_ELF_LOADER
10 /* should probably go in elf.h */
16 #define ELF_START_MMAP 0x80000000
18 #define elf_check_arch(x) ( (x) == EM_SPARC )
20 #define ELF_CLASS ELFCLASS32
21 #define ELF_DATA ELFDATA2MSB
22 #define ELF_ARCH EM_SPARC
27 * This structure is used to hold the arguments that are
28 * used when loading binaries.
35 #define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
36 #define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
37 #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
40 static void bswap_ehdr(Elf32_Ehdr *ehdr)
42 bswap16s(&ehdr->e_type); /* Object file type */
43 bswap16s(&ehdr->e_machine); /* Architecture */
44 bswap32s(&ehdr->e_version); /* Object file version */
45 bswap32s(&ehdr->e_entry); /* Entry point virtual address */
46 bswap32s(&ehdr->e_phoff); /* Program header table file offset */
47 bswap32s(&ehdr->e_shoff); /* Section header table file offset */
48 bswap32s(&ehdr->e_flags); /* Processor-specific flags */
49 bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
50 bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
51 bswap16s(&ehdr->e_phnum); /* Program header table entry count */
52 bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
53 bswap16s(&ehdr->e_shnum); /* Section header table entry count */
54 bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
57 static void bswap_phdr(Elf32_Phdr *phdr)
59 bswap32s(&phdr->p_type); /* Segment type */
60 bswap32s(&phdr->p_offset); /* Segment file offset */
61 bswap32s(&phdr->p_vaddr); /* Segment virtual address */
62 bswap32s(&phdr->p_paddr); /* Segment physical address */
63 bswap32s(&phdr->p_filesz); /* Segment size in file */
64 bswap32s(&phdr->p_memsz); /* Segment size in memory */
65 bswap32s(&phdr->p_flags); /* Segment flags */
66 bswap32s(&phdr->p_align); /* Segment alignment */
69 static void bswap_shdr(Elf32_Shdr *shdr)
71 bswap32s(&shdr->sh_name);
72 bswap32s(&shdr->sh_type);
73 bswap32s(&shdr->sh_flags);
74 bswap32s(&shdr->sh_addr);
75 bswap32s(&shdr->sh_offset);
76 bswap32s(&shdr->sh_size);
77 bswap32s(&shdr->sh_link);
78 bswap32s(&shdr->sh_info);
79 bswap32s(&shdr->sh_addralign);
80 bswap32s(&shdr->sh_entsize);
83 static void bswap_sym(Elf32_Sym *sym)
85 bswap32s(&sym->st_name);
86 bswap32s(&sym->st_value);
87 bswap32s(&sym->st_size);
88 bswap16s(&sym->st_shndx);
92 static int prepare_binprm(struct linux_binprm *bprm)
96 memset(bprm->buf, 0, sizeof(bprm->buf));
97 retval = lseek(bprm->fd, 0L, SEEK_SET);
99 retval = read(bprm->fd, bprm->buf, 128);
102 perror("prepare_binprm");
104 /* return(-errno); */
111 /* Best attempt to load symbols from this ELF object. */
112 static void load_symbols(struct elfhdr *hdr, int fd)
115 struct elf_shdr sechdr, symtab, strtab;
118 lseek(fd, hdr->e_shoff, SEEK_SET);
119 for (i = 0; i < hdr->e_shnum; i++) {
120 if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
125 if (sechdr.sh_type == SHT_SYMTAB) {
127 lseek(fd, hdr->e_shoff
128 + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
129 if (read(fd, &strtab, sizeof(strtab))
138 return; /* Shouldn't happen... */
141 /* Now know where the strtab and symtab are. Snarf them. */
142 disas_symtab = qemu_malloc(symtab.sh_size);
143 disas_strtab = strings = qemu_malloc(strtab.sh_size);
144 if (!disas_symtab || !disas_strtab)
147 lseek(fd, symtab.sh_offset, SEEK_SET);
148 if (read(fd, disas_symtab, symtab.sh_size) != symtab.sh_size)
152 for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++)
153 bswap_sym(disas_symtab + sizeof(struct elf_sym)*i);
156 lseek(fd, strtab.sh_offset, SEEK_SET);
157 if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
159 disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
162 static int load_elf_binary(struct linux_binprm * bprm, uint8_t *addr)
164 struct elfhdr elf_ex;
165 unsigned long startaddr = addr;
167 struct elf_phdr * elf_ppnt;
168 struct elf_phdr *elf_phdata;
171 elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */
176 if (elf_ex.e_ident[0] != 0x7f ||
177 strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
181 /* First of all, some simple consistency checks */
182 if (! elf_check_arch(elf_ex.e_machine)) {
186 /* Now read in all of the header information */
187 elf_phdata = (struct elf_phdr *)qemu_malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
188 if (elf_phdata == NULL) {
192 retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
194 retval = read(bprm->fd, (char *) elf_phdata,
195 elf_ex.e_phentsize * elf_ex.e_phnum);
199 perror("load_elf_binary");
201 qemu_free (elf_phdata);
206 elf_ppnt = elf_phdata;
207 for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
208 bswap_phdr(elf_ppnt);
211 elf_ppnt = elf_phdata;
213 /* Now we do a little grungy work by mmaping the ELF image into
214 * the correct location in memory. At this point, we assume that
215 * the image should be loaded at fixed address, not at a variable
219 for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
220 unsigned long error, offset, len;
222 if (elf_ppnt->p_type != PT_LOAD)
225 error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
227 (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
229 (elf_ppnt->p_offset -
230 TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
232 //offset = elf_ppnt->p_offset - TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr);
234 lseek(bprm->fd, offset, SEEK_SET);
235 len = elf_ppnt->p_filesz + TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr);
236 error = read(bprm->fd, addr, len);
245 qemu_free(elf_phdata);
247 load_symbols(&elf_ex, bprm->fd);
249 return addr-startaddr;
252 int elf_exec(const char * filename, uint8_t *addr)
254 struct linux_binprm bprm;
257 retval = open(filename, O_RDONLY);
262 retval = prepare_binprm(&bprm);
265 retval = load_elf_binary(&bprm, addr);
271 int load_kernel(const char *filename, uint8_t *addr)
275 fd = open(filename, O_RDONLY | O_BINARY);
278 /* load 32 bit code */
279 size = read(fd, addr, 16 * 1024 * 1024);
289 static char saved_kfn[1024];
290 static uint32_t saved_addr;
291 static int magic_state;
293 static uint32_t magic_mem_readl(void *opaque, target_phys_addr_t addr)
297 if (magic_state == 0) {
298 #ifdef USE_ELF_LOADER
299 ret = elf_exec(saved_kfn, saved_addr);
301 ret = load_kernel(saved_kfn, (uint8_t *)saved_addr);
304 fprintf(stderr, "qemu: could not load kernel '%s'\n",
307 magic_state = 1; /* No more magic */
313 static void magic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
318 static CPUReadMemoryFunc *magic_mem_read[3] = {
324 static CPUWriteMemoryFunc *magic_mem_write[3] = {
330 void magic_init(const char *kfn, int kloadaddr)
334 strcpy(saved_kfn, kfn);
335 saved_addr = kloadaddr;
337 magic_io_memory = cpu_register_io_memory(0, magic_mem_read, magic_mem_write, 0);
338 cpu_register_physical_memory(0x20000000, 4,