Revision | c07af71a15aa96bb85c54e96eb6b82813050caed (tree) |
---|---|
Zeit | 2014-02-18 17:45:52 |
Autor | Yoshinori Sato <ysato@sa76...> |
Commiter | Yoshinori Sato |
ELF support
@@ -17,6 +17,10 @@ | ||
17 | 17 | #include <errno.h> |
18 | 18 | #include <sys/mman.h> |
19 | 19 | #include <sys/stat.h> |
20 | +#ifdef HAVE_GELF_H | |
21 | +#include <gelf.h> | |
22 | +#endif | |
23 | + | |
20 | 24 | #include "h8flash.h" |
21 | 25 | |
22 | 26 | #define SREC_MAXLEN (256*2 + 4 + 1) |
@@ -157,6 +161,76 @@ static int write_srec(FILE *fp, struct writeinfo_t *writeinfo, struct port_t *p) | ||
157 | 161 | return r; |
158 | 162 | } |
159 | 163 | |
164 | +#ifdef HAVE_ELF_H | |
165 | +static int writefile_elf(FILE *fp, struct writeinfo_t *writeinfo, | |
166 | + struct port_t *p) | |
167 | +{ | |
168 | + unsigned char *romimage = NULL; | |
169 | + unsigned int romsize; | |
170 | + int fd; | |
171 | + int n; | |
172 | + int i; | |
173 | + Elf *elf = NULL; | |
174 | + GElf_Phdr phdr; | |
175 | + unsigned long last_addr = 0; | |
176 | + int ret = -1; | |
177 | + | |
178 | + romsize = writeinfo->area.end - writeinfo->area.start + 1; | |
179 | + romimage = (unsigned char *)malloc(romsize); | |
180 | + if (!romimage) { | |
181 | + perror(PROGNAME); | |
182 | + goto error; | |
183 | + } | |
184 | + memset(romimage, 0xff, romsize); | |
185 | + elf_version(EV_CURRENT); | |
186 | + fd = fileno(fp); | |
187 | + elf = elf_begin(fd, ELF_C_READ, NULL); | |
188 | + if (elf == NULL) { | |
189 | + fputs(elf_errmsg(-1), stderr); | |
190 | + goto error; | |
191 | + } | |
192 | + if(elf_kind(elf) != ELF_K_ELF) { | |
193 | + fputs("Not ELF executable", stderr); | |
194 | + goto error; | |
195 | + } | |
196 | + elf_getphdrnum(elf, &n); | |
197 | + for (i = 0; i < n; i++) { | |
198 | + if (gelf_getphdr(elf, &phdr) == NULL) { | |
199 | + fputs(elf_errmsg(-1), stderr); | |
200 | + goto error; | |
201 | + } | |
202 | + if (verbose) { | |
203 | + printf(" offset paddr size\n"); | |
204 | + printf("%d: %08x %08x %08x\n", | |
205 | + n, phdr.p_offset, phdr.p_pddr, phdr,p_filesz); | |
206 | + } | |
207 | + if (phdr.p_paddr < writeinfo->area.start || | |
208 | + (phdr.p_paddr + phdr.p_filesz) > writeinfo->area.end) { | |
209 | + fprintf("%08x - %08x is out of rom", | |
210 | + phdr.p_pddr, phdr.p_pddr + phdr,p_filesz); | |
211 | + goto error; | |
212 | + } | |
213 | + lseek(fd, phdr.p_offset, SEEK_SET); | |
214 | + sz = read(fd, romimage + (phdr.p_paddr - writeinfo->area.start), | |
215 | + phdr.p_filesz); | |
216 | + if (sz != phdr.p_filesz) { | |
217 | + fputs("File read error", stderr); | |
218 | + goto error; | |
219 | + } | |
220 | + if (last_addr < (phdr.p_paddr + pdhr.filesz)) | |
221 | + last_addr = phdr.p_paddr + pdhr.filesz; | |
222 | + } | |
223 | + writeinfo->area.end = last_addr; | |
224 | + ret = write_rom(p, romimage, writeinfo); | |
225 | +error: | |
226 | + if (elf) | |
227 | + elf_end(elf); | |
228 | + fclose(fp); | |
229 | + free(romimage); | |
230 | + return ret; | |
231 | +} | |
232 | +#endif | |
233 | + | |
160 | 234 | /* read rom writing data */ |
161 | 235 | static int writefile_to_rom(char *fn, int force_binary, struct writeinfo_t *writeinfo, |
162 | 236 | struct port_t *port) |
@@ -177,12 +251,17 @@ static int writefile_to_rom(char *fn, int force_binary, struct writeinfo_t *writ | ||
177 | 251 | return -1; |
178 | 252 | } |
179 | 253 | /* get head */ |
180 | - if (fgets(linebuf, sizeof(linebuf), fp) == NULL && ferror(fp)) { | |
254 | + if (fread(linebuf, sizeof(linebuf), 1, fp) < 0 && ferror(fp)) { | |
181 | 255 | fclose(fp); |
182 | 256 | return -1; |
183 | 257 | } |
184 | 258 | fseek(fp,0,SEEK_SET); |
185 | 259 | |
260 | +#ifdef HAVE_ELF_H | |
261 | + /* check ELF */ | |
262 | + if (!force_binary && memcmp(linebuf, "\x7fELF", 4) == 0) | |
263 | + return write_elf(fp, writeinfo, port) | |
264 | +#endif | |
186 | 265 | /* check 'S??' */ |
187 | 266 | if (force_binary || |
188 | 267 | linebuf[0] != 'S' || |