diff options
Diffstat (limited to 'utils/sbtools')
-rw-r--r-- | utils/sbtools/elf.c | 59 | ||||
-rw-r--r-- | utils/sbtools/elf.h | 21 | ||||
-rw-r--r-- | utils/sbtools/elftosb.c | 1 |
3 files changed, 76 insertions, 5 deletions
diff --git a/utils/sbtools/elf.c b/utils/sbtools/elf.c index fed09cd6ff..57f38b8016 100644 --- a/utils/sbtools/elf.c +++ b/utils/sbtools/elf.c | |||
@@ -155,6 +155,21 @@ static struct elf_section_t *elf_add_section(struct elf_params_t *params) | |||
155 | return sec; | 155 | return sec; |
156 | } | 156 | } |
157 | 157 | ||
158 | static struct elf_segment_t *elf_add_segment(struct elf_params_t *params) | ||
159 | { | ||
160 | struct elf_segment_t *seg = xmalloc(sizeof(struct elf_section_t)); | ||
161 | if(params->first_segment == NULL) | ||
162 | params->first_segment = params->last_segment = seg; | ||
163 | else | ||
164 | { | ||
165 | params->last_segment->next = seg; | ||
166 | params->last_segment = seg; | ||
167 | } | ||
168 | seg->next = NULL; | ||
169 | |||
170 | return seg; | ||
171 | } | ||
172 | |||
158 | void elf_add_load_section(struct elf_params_t *params, | 173 | void elf_add_load_section(struct elf_params_t *params, |
159 | uint32_t load_addr, uint32_t size, const void *section) | 174 | uint32_t load_addr, uint32_t size, const void *section) |
160 | { | 175 | { |
@@ -406,7 +421,7 @@ bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read, | |||
406 | } | 421 | } |
407 | /* run through sections */ | 422 | /* run through sections */ |
408 | printf(user, false, "ELF file:\n"); | 423 | printf(user, false, "ELF file:\n"); |
409 | for(int i = 1; i< ehdr.e_shnum; i++) | 424 | for(int i = 1; i < ehdr.e_shnum; i++) |
410 | { | 425 | { |
411 | uint32_t off = ehdr.e_shoff + i * ehdr.e_shentsize; | 426 | uint32_t off = ehdr.e_shoff + i * ehdr.e_shentsize; |
412 | Elf32_Shdr shdr; | 427 | Elf32_Shdr shdr; |
@@ -437,9 +452,51 @@ bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read, | |||
437 | } | 452 | } |
438 | 453 | ||
439 | } | 454 | } |
455 | /* run through segments */ | ||
456 | for(int i = 1; i < ehdr.e_phnum; i++) | ||
457 | { | ||
458 | uint32_t off = ehdr.e_phoff + i * ehdr.e_phentsize; | ||
459 | Elf32_Phdr phdr; | ||
460 | memset(&phdr, 0, sizeof(phdr)); | ||
461 | if(!read(user, off, &phdr, sizeof(phdr))) | ||
462 | error_printf("error reading elf segment header"); | ||
463 | if(phdr.p_type != PT_LOAD) | ||
464 | continue; | ||
465 | struct elf_segment_t *seg = elf_add_segment(params); | ||
466 | seg->vaddr = phdr.p_vaddr; | ||
467 | seg->paddr = phdr.p_paddr; | ||
468 | seg->vsize = phdr.p_memsz; | ||
469 | seg->psize = phdr.p_filesz; | ||
470 | printf(user, false, "create segment [%#x,+%#x[ -> [%#x,+%#x[\n", | ||
471 | seg->vaddr, seg->vsize, seg->paddr, seg->psize); | ||
472 | } | ||
473 | |||
440 | return true; | 474 | return true; |
441 | } | 475 | } |
442 | 476 | ||
477 | uint32_t elf_translate_virtual_address(struct elf_params_t *params, uint32_t addr) | ||
478 | { | ||
479 | struct elf_segment_t *seg = params->first_segment; | ||
480 | while(seg) | ||
481 | { | ||
482 | if(seg->vaddr <= addr && addr < seg->vaddr + seg->vsize) | ||
483 | return addr - seg->vaddr + seg->paddr; | ||
484 | seg = seg->next; | ||
485 | } | ||
486 | return addr; | ||
487 | } | ||
488 | |||
489 | void elf_translate_addresses(struct elf_params_t *params) | ||
490 | { | ||
491 | struct elf_section_t *sec = params->first_section; | ||
492 | while(sec) | ||
493 | { | ||
494 | sec->addr = elf_translate_virtual_address(params, sec->addr); | ||
495 | sec = sec->next; | ||
496 | } | ||
497 | params->start_addr = elf_translate_virtual_address(params, params->start_addr); | ||
498 | } | ||
499 | |||
443 | bool elf_is_empty(struct elf_params_t *params) | 500 | bool elf_is_empty(struct elf_params_t *params) |
444 | { | 501 | { |
445 | return params->first_section == NULL; | 502 | return params->first_section == NULL; |
diff --git a/utils/sbtools/elf.h b/utils/sbtools/elf.h index b145bfffc5..d63b9a93b7 100644 --- a/utils/sbtools/elf.h +++ b/utils/sbtools/elf.h | |||
@@ -16,24 +16,35 @@ enum elf_section_type_t | |||
16 | 16 | ||
17 | struct elf_section_t | 17 | struct elf_section_t |
18 | { | 18 | { |
19 | uint32_t addr; | 19 | uint32_t addr; /* virtual address */ |
20 | uint32_t size; | 20 | uint32_t size; /* virtual size */ |
21 | enum elf_section_type_t type; | 21 | enum elf_section_type_t type; |
22 | /* <union> */ | 22 | /* <union> */ |
23 | void *section; | 23 | void *section; /* data */ |
24 | uint32_t pattern; | 24 | uint32_t pattern; /* fill pattern */ |
25 | /* </union> */ | 25 | /* </union> */ |
26 | struct elf_section_t *next; | 26 | struct elf_section_t *next; |
27 | /* Internal to elf_write_file */ | 27 | /* Internal to elf_write_file */ |
28 | uint32_t offset; | 28 | uint32_t offset; |
29 | }; | 29 | }; |
30 | 30 | ||
31 | struct elf_segment_t | ||
32 | { | ||
33 | uint32_t vaddr; /* virtual address */ | ||
34 | uint32_t paddr; /* physical address */ | ||
35 | uint32_t vsize; /* virtual size */ | ||
36 | uint32_t psize; /* physical size */ | ||
37 | struct elf_segment_t *next; | ||
38 | }; | ||
39 | |||
31 | struct elf_params_t | 40 | struct elf_params_t |
32 | { | 41 | { |
33 | bool has_start_addr; | 42 | bool has_start_addr; |
34 | uint32_t start_addr; | 43 | uint32_t start_addr; |
35 | struct elf_section_t *first_section; | 44 | struct elf_section_t *first_section; |
36 | struct elf_section_t *last_section; | 45 | struct elf_section_t *last_section; |
46 | struct elf_segment_t *first_segment; | ||
47 | struct elf_segment_t *last_segment; | ||
37 | }; | 48 | }; |
38 | 49 | ||
39 | typedef bool (*elf_read_fn_t)(void *user, uint32_t addr, void *buf, size_t count); | 50 | typedef bool (*elf_read_fn_t)(void *user, uint32_t addr, void *buf, size_t count); |
@@ -46,6 +57,8 @@ void elf_add_load_section(struct elf_params_t *params, | |||
46 | uint32_t load_addr, uint32_t size, const void *section); | 57 | uint32_t load_addr, uint32_t size, const void *section); |
47 | void elf_add_fill_section(struct elf_params_t *params, | 58 | void elf_add_fill_section(struct elf_params_t *params, |
48 | uint32_t fill_addr, uint32_t size, uint32_t pattern); | 59 | uint32_t fill_addr, uint32_t size, uint32_t pattern); |
60 | uint32_t elf_translate_virtual_address(struct elf_params_t *params, uint32_t addr); | ||
61 | void elf_translate_addresses(struct elf_params_t *params); | ||
49 | void elf_write_file(struct elf_params_t *params, elf_write_fn_t write, void *user); | 62 | void elf_write_file(struct elf_params_t *params, elf_write_fn_t write, void *user); |
50 | bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read, elf_printf_fn_t printf, | 63 | bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read, elf_printf_fn_t printf, |
51 | void *user); | 64 | void *user); |
diff --git a/utils/sbtools/elftosb.c b/utils/sbtools/elftosb.c index 78d2e80bf9..cb5cc4c6db 100644 --- a/utils/sbtools/elftosb.c +++ b/utils/sbtools/elftosb.c | |||
@@ -817,6 +817,7 @@ static void load_elf_by_id(struct cmd_file_t *cmd_file, const char *id) | |||
817 | close(fd); | 817 | close(fd); |
818 | if(!src->loaded) | 818 | if(!src->loaded) |
819 | bug("error loading elf file '%s' (id '%s')\n", src->filename, id); | 819 | bug("error loading elf file '%s' (id '%s')\n", src->filename, id); |
820 | elf_translate_addresses(&src->elf); | ||
820 | } | 821 | } |
821 | 822 | ||
822 | static void load_bin_by_id(struct cmd_file_t *cmd_file, const char *id) | 823 | static void load_bin_by_id(struct cmd_file_t *cmd_file, const char *id) |