]>
git.proxmox.com Git - qemu.git/blob - hw/magic-load.c
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 */
18 static void bswap_ahdr(struct exec
*e
)
25 bswap32s(&e
->a_entry
);
26 bswap32s(&e
->a_trsize
);
27 bswap32s(&e
->a_drsize
);
30 #define bswap_ahdr(x) do { } while (0)
33 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
38 #define _N_HDROFF(x) (1024 - sizeof (struct exec))
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))
46 #define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
48 #define N_DATADDR(x) \
49 (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
50 : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
53 #define ELF_CLASS ELFCLASS32
54 #define ELF_DATA ELFDATA2MSB
55 #define ELF_ARCH EM_SPARC
60 static void bswap_ehdr(Elf32_Ehdr
*ehdr
)
62 bswap16s(&ehdr
->e_type
); /* Object file type */
63 bswap16s(&ehdr
->e_machine
); /* Architecture */
64 bswap32s(&ehdr
->e_version
); /* Object file version */
65 bswap32s(&ehdr
->e_entry
); /* Entry point virtual address */
66 bswap32s(&ehdr
->e_phoff
); /* Program header table file offset */
67 bswap32s(&ehdr
->e_shoff
); /* Section header table file offset */
68 bswap32s(&ehdr
->e_flags
); /* Processor-specific flags */
69 bswap16s(&ehdr
->e_ehsize
); /* ELF header size in bytes */
70 bswap16s(&ehdr
->e_phentsize
); /* Program header table entry size */
71 bswap16s(&ehdr
->e_phnum
); /* Program header table entry count */
72 bswap16s(&ehdr
->e_shentsize
); /* Section header table entry size */
73 bswap16s(&ehdr
->e_shnum
); /* Section header table entry count */
74 bswap16s(&ehdr
->e_shstrndx
); /* Section header string table index */
77 static void bswap_phdr(Elf32_Phdr
*phdr
)
79 bswap32s(&phdr
->p_type
); /* Segment type */
80 bswap32s(&phdr
->p_offset
); /* Segment file offset */
81 bswap32s(&phdr
->p_vaddr
); /* Segment virtual address */
82 bswap32s(&phdr
->p_paddr
); /* Segment physical address */
83 bswap32s(&phdr
->p_filesz
); /* Segment size in file */
84 bswap32s(&phdr
->p_memsz
); /* Segment size in memory */
85 bswap32s(&phdr
->p_flags
); /* Segment flags */
86 bswap32s(&phdr
->p_align
); /* Segment alignment */
89 static void bswap_shdr(Elf32_Shdr
*shdr
)
91 bswap32s(&shdr
->sh_name
);
92 bswap32s(&shdr
->sh_type
);
93 bswap32s(&shdr
->sh_flags
);
94 bswap32s(&shdr
->sh_addr
);
95 bswap32s(&shdr
->sh_offset
);
96 bswap32s(&shdr
->sh_size
);
97 bswap32s(&shdr
->sh_link
);
98 bswap32s(&shdr
->sh_info
);
99 bswap32s(&shdr
->sh_addralign
);
100 bswap32s(&shdr
->sh_entsize
);
103 static void bswap_sym(Elf32_Sym
*sym
)
105 bswap32s(&sym
->st_name
);
106 bswap32s(&sym
->st_value
);
107 bswap32s(&sym
->st_size
);
108 bswap16s(&sym
->st_shndx
);
111 #define bswap_ehdr(e) do { } while (0)
112 #define bswap_phdr(e) do { } while (0)
113 #define bswap_shdr(e) do { } while (0)
114 #define bswap_sym(e) do { } while (0)
117 static int find_phdr(struct elfhdr
*ehdr
, int fd
, struct elf_phdr
*phdr
, uint32_t type
)
121 retval
= lseek(fd
, ehdr
->e_phoff
, SEEK_SET
);
125 for (i
= 0; i
< ehdr
->e_phnum
; i
++) {
126 retval
= read(fd
, phdr
, sizeof(*phdr
));
130 if (phdr
->p_type
== type
)
136 static void *find_shdr(struct elfhdr
*ehdr
, int fd
, struct elf_shdr
*shdr
, uint32_t type
)
140 retval
= lseek(fd
, ehdr
->e_shoff
, SEEK_SET
);
144 for (i
= 0; i
< ehdr
->e_shnum
; i
++) {
145 retval
= read(fd
, shdr
, sizeof(*shdr
));
149 if (shdr
->sh_type
== type
)
150 return qemu_malloc(shdr
->sh_size
);
155 static void *find_strtab(struct elfhdr
*ehdr
, int fd
, struct elf_shdr
*shdr
, struct elf_shdr
*symtab
)
159 retval
= lseek(fd
, ehdr
->e_shoff
+ sizeof(struct elf_shdr
) * symtab
->sh_link
, SEEK_SET
);
163 retval
= read(fd
, shdr
, sizeof(*shdr
));
167 if (shdr
->sh_type
== SHT_STRTAB
)
168 return qemu_malloc(shdr
->sh_size
);;
172 static int read_program(int fd
, struct elf_phdr
*phdr
, void *dst
, uint32_t entry
)
175 retval
= lseek(fd
, phdr
->p_offset
+ entry
- phdr
->p_vaddr
, SEEK_SET
);
178 return read(fd
, dst
, phdr
->p_filesz
);
181 static int read_section(int fd
, struct elf_shdr
*s
, void *dst
)
185 retval
= lseek(fd
, s
->sh_offset
, SEEK_SET
);
188 retval
= read(fd
, dst
, s
->sh_size
);
194 static void *process_section(struct elfhdr
*ehdr
, int fd
, struct elf_shdr
*shdr
, uint32_t type
)
198 dst
= find_shdr(ehdr
, fd
, shdr
, type
);
202 if (read_section(fd
, shdr
, dst
))
210 static void *process_strtab(struct elfhdr
*ehdr
, int fd
, struct elf_shdr
*shdr
, struct elf_shdr
*symtab
)
214 dst
= find_strtab(ehdr
, fd
, shdr
, symtab
);
218 if (read_section(fd
, shdr
, dst
))
226 static void load_symbols(struct elfhdr
*ehdr
, int fd
)
228 struct elf_shdr symtab
, strtab
;
229 struct elf_sym
*syms
;
235 syms
= process_section(ehdr
, fd
, &symtab
, SHT_SYMTAB
);
239 nsyms
= symtab
.sh_size
/ sizeof(struct elf_sym
);
240 for (i
= 0; i
< nsyms
; i
++)
244 str
= process_strtab(ehdr
, fd
, &strtab
, &symtab
);
249 s
= qemu_mallocz(sizeof(*s
));
250 s
->disas_symtab
= syms
;
251 s
->disas_num_syms
= nsyms
;
252 s
->disas_strtab
= str
;
261 int load_elf(const char *filename
, uint8_t *addr
)
264 struct elf_phdr phdr
;
267 fd
= open(filename
, O_RDONLY
| O_BINARY
);
271 retval
= read(fd
, &ehdr
, sizeof(ehdr
));
277 if (ehdr
.e_ident
[0] != 0x7f || ehdr
.e_ident
[1] != 'E'
278 || ehdr
.e_ident
[2] != 'L' || ehdr
.e_ident
[3] != 'F'
279 || (ehdr
.e_machine
!= EM_SPARC
280 && ehdr
.e_machine
!= EM_SPARC32PLUS
))
283 if (find_phdr(&ehdr
, fd
, &phdr
, PT_LOAD
))
285 retval
= read_program(fd
, &phdr
, addr
, ehdr
.e_entry
);
289 load_symbols(&ehdr
, fd
);
298 int load_aout(const char *filename
, uint8_t *addr
)
304 fd
= open(filename
, O_RDONLY
| O_BINARY
);
308 size
= read(fd
, &e
, sizeof(e
));
319 lseek(fd
, N_TXTOFF(e
), SEEK_SET
);
320 size
= read(fd
, addr
, e
.a_text
+ e
.a_data
);
325 lseek(fd
, N_TXTOFF(e
), SEEK_SET
);
326 size
= read(fd
, addr
, e
.a_text
);
329 ret
= read(fd
, addr
+ N_DATADDR(e
), e
.a_data
);