]> Git Repo - qemu.git/blame - hw/elf_ops.h
sparc64 marge (Blue Swirl)
[qemu.git] / hw / elf_ops.h
CommitLineData
3475187d
FB
1#ifdef BSWAP_NEEDED
2static void glue(bswap_ehdr, SZ)(struct elfhdr *ehdr)
3{
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 */
17}
18
19static void glue(bswap_phdr, SZ)(struct elf_phdr *phdr)
20{
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 */
29}
30
31static void glue(bswap_shdr, SZ)(struct elf_shdr *shdr)
32{
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);
43}
44
45static void glue(bswap_sym, SZ)(struct elf_sym *sym)
46{
47 bswap32s(&sym->st_name);
48 bswapSZs(&sym->st_value);
49 bswapSZs(&sym->st_size);
50 bswap16s(&sym->st_shndx);
51}
52#endif
53
54static int glue(find_phdr, SZ)(struct elfhdr *ehdr, int fd, struct elf_phdr *phdr, elf_word type)
55{
56 int i, retval;
57
58 retval = lseek(fd, ehdr->e_phoff, SEEK_SET);
59 if (retval < 0)
60 return -1;
61
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;
69 }
70 return -1;
71}
72
73static void * glue(find_shdr, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, elf_word type)
74{
75 int i, retval;
76
77 retval = lseek(fd, ehdr->e_shoff, SEEK_SET);
78 if (retval < 0)
79 return NULL;
80
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);
88 }
89 return NULL;
90}
91
92static void * glue(find_strtab, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)
93{
94 int retval;
95
96 retval = lseek(fd, ehdr->e_shoff + sizeof(struct elf_shdr) * symtab->sh_link, SEEK_SET);
97 if (retval < 0)
98 return NULL;
99
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;
107}
108
109static int glue(read_program, SZ)(int fd, struct elf_phdr *phdr, void *dst, elf_word entry)
110{
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);
116}
117
118static int glue(read_section, SZ)(int fd, struct elf_shdr *s, void *dst)
119{
120 int retval;
121
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;
129}
130
131static void * glue(process_section, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, elf_word type)
132{
133 void *dst;
134
135 dst = glue(find_shdr, SZ)(ehdr, fd, shdr, type);
136 if (!dst)
137 goto error;
138
139 if (glue(read_section, SZ)(fd, shdr, dst))
140 goto error;
141 return dst;
142 error:
143 qemu_free(dst);
144 return NULL;
145}
146
147static void * glue(process_strtab, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)
148{
149 void *dst;
150
151 dst = glue(find_strtab, SZ)(ehdr, fd, shdr, symtab);
152 if (!dst)
153 goto error;
154
155 if (glue(read_section, SZ)(fd, shdr, dst))
156 goto error;
157 return dst;
158 error:
159 qemu_free(dst);
160 return NULL;
161}
162
163static void glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd)
164{
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;
173
174 /* Symbol table */
175 syms = glue(process_section, SZ)(ehdr, fd, &symtab, SHT_SYMTAB);
176 if (!syms)
177 return;
178
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
193 }
194 /* String table */
195 str = glue(process_strtab, SZ)(ehdr, fd, &strtab, &symtab);
196 if (!str)
197 goto error_freesyms;
198
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;
218}
This page took 0.042561 seconds and 4 git commands to generate.