Record configure commandline.
[qemu/mini2440.git] / hw / elf_ops.h
blob1f3232d47c93092416e348b0a2e9e6c7ed2b7727
1 #ifdef BSWAP_NEEDED
2 static void glue(bswap_ehdr, SZ)(struct elfhdr *ehdr)
4 bswap16s(&ehdr->e_type); /* Object file type */
5 bswap16s(&ehdr->e_machine); /* Architecture */
6 bswap32s(&ehdr->e_version); /* Object file version */
7 bswapSZs(&ehdr->e_entry); /* Entry point virtual address */
8 bswapSZs(&ehdr->e_phoff); /* Program header table file offset */
9 bswapSZs(&ehdr->e_shoff); /* Section header table file offset */
10 bswap32s(&ehdr->e_flags); /* Processor-specific flags */
11 bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
12 bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
13 bswap16s(&ehdr->e_phnum); /* Program header table entry count */
14 bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
15 bswap16s(&ehdr->e_shnum); /* Section header table entry count */
16 bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
19 static void glue(bswap_phdr, SZ)(struct elf_phdr *phdr)
21 bswap32s(&phdr->p_type); /* Segment type */
22 bswapSZs(&phdr->p_offset); /* Segment file offset */
23 bswapSZs(&phdr->p_vaddr); /* Segment virtual address */
24 bswapSZs(&phdr->p_paddr); /* Segment physical address */
25 bswapSZs(&phdr->p_filesz); /* Segment size in file */
26 bswapSZs(&phdr->p_memsz); /* Segment size in memory */
27 bswap32s(&phdr->p_flags); /* Segment flags */
28 bswapSZs(&phdr->p_align); /* Segment alignment */
31 static void glue(bswap_shdr, SZ)(struct elf_shdr *shdr)
33 bswap32s(&shdr->sh_name);
34 bswap32s(&shdr->sh_type);
35 bswapSZs(&shdr->sh_flags);
36 bswapSZs(&shdr->sh_addr);
37 bswapSZs(&shdr->sh_offset);
38 bswapSZs(&shdr->sh_size);
39 bswap32s(&shdr->sh_link);
40 bswap32s(&shdr->sh_info);
41 bswapSZs(&shdr->sh_addralign);
42 bswapSZs(&shdr->sh_entsize);
45 static void glue(bswap_sym, SZ)(struct elf_sym *sym)
47 bswap32s(&sym->st_name);
48 bswapSZs(&sym->st_value);
49 bswapSZs(&sym->st_size);
50 bswap16s(&sym->st_shndx);
52 #endif
54 static int glue(find_phdr, SZ)(struct elfhdr *ehdr, int fd, struct elf_phdr *phdr, elf_word type)
56 int i, retval;
58 retval = lseek(fd, ehdr->e_phoff, SEEK_SET);
59 if (retval < 0)
60 return -1;
62 for (i = 0; i < ehdr->e_phnum; i++) {
63 retval = read(fd, phdr, sizeof(*phdr));
64 if (retval < 0)
65 return -1;
66 glue(bswap_phdr, SZ)(phdr);
67 if (phdr->p_type == type)
68 return 0;
70 return -1;
73 static void * glue(find_shdr, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, elf_word type)
75 int i, retval;
77 retval = lseek(fd, ehdr->e_shoff, SEEK_SET);
78 if (retval < 0)
79 return NULL;
81 for (i = 0; i < ehdr->e_shnum; i++) {
82 retval = read(fd, shdr, sizeof(*shdr));
83 if (retval < 0)
84 return NULL;
85 glue(bswap_shdr, SZ)(shdr);
86 if (shdr->sh_type == type)
87 return qemu_malloc(shdr->sh_size);
89 return NULL;
92 static void * glue(find_strtab, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)
94 int retval;
96 retval = lseek(fd, ehdr->e_shoff + sizeof(struct elf_shdr) * symtab->sh_link, SEEK_SET);
97 if (retval < 0)
98 return NULL;
100 retval = read(fd, shdr, sizeof(*shdr));
101 if (retval < 0)
102 return NULL;
103 glue(bswap_shdr, SZ)(shdr);
104 if (shdr->sh_type == SHT_STRTAB)
105 return qemu_malloc(shdr->sh_size);;
106 return NULL;
109 static int glue(read_program, SZ)(int fd, struct elf_phdr *phdr, void *dst, elf_word entry)
111 int retval;
112 retval = lseek(fd, phdr->p_offset + entry - phdr->p_vaddr, SEEK_SET);
113 if (retval < 0)
114 return -1;
115 return read(fd, dst, phdr->p_filesz);
118 static int glue(read_section, SZ)(int fd, struct elf_shdr *s, void *dst)
120 int retval;
122 retval = lseek(fd, s->sh_offset, SEEK_SET);
123 if (retval < 0)
124 return -1;
125 retval = read(fd, dst, s->sh_size);
126 if (retval < 0)
127 return -1;
128 return 0;
131 static void * glue(process_section, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, elf_word type)
133 void *dst;
135 dst = glue(find_shdr, SZ)(ehdr, fd, shdr, type);
136 if (!dst)
137 goto error;
139 if (glue(read_section, SZ)(fd, shdr, dst))
140 goto error;
141 return dst;
142 error:
143 qemu_free(dst);
144 return NULL;
147 static void * glue(process_strtab, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)
149 void *dst;
151 dst = glue(find_strtab, SZ)(ehdr, fd, shdr, symtab);
152 if (!dst)
153 goto error;
155 if (glue(read_section, SZ)(fd, shdr, dst))
156 goto error;
157 return dst;
158 error:
159 qemu_free(dst);
160 return NULL;
163 static void glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd)
165 struct elf_shdr symtab, strtab;
166 struct elf_sym *syms;
167 #if (SZ == 64)
168 struct elf32_sym *syms32;
169 #endif
170 struct syminfo *s;
171 int nsyms, i;
172 char *str;
174 /* Symbol table */
175 syms = glue(process_section, SZ)(ehdr, fd, &symtab, SHT_SYMTAB);
176 if (!syms)
177 return;
179 nsyms = symtab.sh_size / sizeof(struct elf_sym);
180 #if (SZ == 64)
181 syms32 = qemu_mallocz(nsyms * sizeof(struct elf32_sym));
182 #endif
183 for (i = 0; i < nsyms; i++) {
184 glue(bswap_sym, SZ)(&syms[i]);
185 #if (SZ == 64)
186 syms32[i].st_name = syms[i].st_name;
187 syms32[i].st_info = syms[i].st_info;
188 syms32[i].st_other = syms[i].st_other;
189 syms32[i].st_shndx = syms[i].st_shndx;
190 syms32[i].st_value = syms[i].st_value & 0xffffffff;
191 syms32[i].st_size = syms[i].st_size & 0xffffffff;
192 #endif
194 /* String table */
195 str = glue(process_strtab, SZ)(ehdr, fd, &strtab, &symtab);
196 if (!str)
197 goto error_freesyms;
199 /* Commit */
200 s = qemu_mallocz(sizeof(*s));
201 #if (SZ == 64)
202 s->disas_symtab = syms32;
203 qemu_free(syms);
204 #else
205 s->disas_symtab = syms;
206 #endif
207 s->disas_num_syms = nsyms;
208 s->disas_strtab = str;
209 s->next = syminfos;
210 syminfos = s;
211 return;
212 error_freesyms:
213 #if (SZ == 64)
214 qemu_free(syms32);
215 #endif
216 qemu_free(syms);
217 return;