diff options
Diffstat (limited to 'utils/imxtools/sbtools')
-rw-r--r-- | utils/imxtools/sbtools/elf.c | 40 | ||||
-rw-r--r-- | utils/imxtools/sbtools/elf.h | 5 | ||||
-rw-r--r-- | utils/imxtools/sbtools/sbtoelf.c | 17 |
3 files changed, 39 insertions, 23 deletions
diff --git a/utils/imxtools/sbtools/elf.c b/utils/imxtools/sbtools/elf.c index 76f29c6db7..226057bc19 100644 --- a/utils/imxtools/sbtools/elf.c +++ b/utils/imxtools/sbtools/elf.c | |||
@@ -18,9 +18,11 @@ | |||
18 | * KIND, either express or implied. | 18 | * KIND, either express or implied. |
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #define _POSIX_C_SOURCE 200809L /* for strdup */ | ||
21 | #include "elf.h" | 22 | #include "elf.h" |
22 | #include "misc.h" | 23 | #include "misc.h" |
23 | #include <stdarg.h> | 24 | #include <stdarg.h> |
25 | #include <string.h> | ||
24 | 26 | ||
25 | /** | 27 | /** |
26 | * Definitions | 28 | * Definitions |
@@ -190,10 +192,11 @@ static struct elf_segment_t *elf_add_segment(struct elf_params_t *params) | |||
190 | } | 192 | } |
191 | 193 | ||
192 | void elf_add_load_section(struct elf_params_t *params, | 194 | void elf_add_load_section(struct elf_params_t *params, |
193 | uint32_t load_addr, uint32_t size, const void *section) | 195 | uint32_t load_addr, uint32_t size, const void *section, const char *name) |
194 | { | 196 | { |
195 | struct elf_section_t *sec = elf_add_section(params); | 197 | struct elf_section_t *sec = elf_add_section(params); |
196 | 198 | ||
199 | sec->name = strdup(name); | ||
197 | sec->type = EST_LOAD; | 200 | sec->type = EST_LOAD; |
198 | sec->addr = load_addr; | 201 | sec->addr = load_addr; |
199 | sec->size = size; | 202 | sec->size = size; |
@@ -202,7 +205,7 @@ void elf_add_load_section(struct elf_params_t *params, | |||
202 | } | 205 | } |
203 | 206 | ||
204 | void elf_add_fill_section(struct elf_params_t *params, | 207 | void elf_add_fill_section(struct elf_params_t *params, |
205 | uint32_t fill_addr, uint32_t size, uint32_t pattern) | 208 | uint32_t fill_addr, uint32_t size, uint32_t pattern, const char *name) |
206 | { | 209 | { |
207 | if(pattern != 0x00) | 210 | if(pattern != 0x00) |
208 | { | 211 | { |
@@ -212,6 +215,7 @@ void elf_add_fill_section(struct elf_params_t *params, | |||
212 | 215 | ||
213 | struct elf_section_t *sec = elf_add_section(params); | 216 | struct elf_section_t *sec = elf_add_section(params); |
214 | 217 | ||
218 | sec->name = strdup(name); | ||
215 | sec->type = EST_FILL; | 219 | sec->type = EST_FILL; |
216 | sec->addr = fill_addr; | 220 | sec->addr = fill_addr; |
217 | sec->size = size; | 221 | sec->size = size; |
@@ -282,6 +286,7 @@ void elf_simplify(struct elf_params_t *params) | |||
282 | memcpy(data + cur_sec->size, sections[i].section, sections[i].size); | 286 | memcpy(data + cur_sec->size, sections[i].section, sections[i].size); |
283 | free(cur_sec->section); | 287 | free(cur_sec->section); |
284 | free(sections[i].section); | 288 | free(sections[i].section); |
289 | free(sections[i].name); | ||
285 | cur_sec->section = data; | 290 | cur_sec->section = data; |
286 | cur_sec->size += sections[i].size; | 291 | cur_sec->size += sections[i].size; |
287 | sections[i].size = 0; // will be ignored by rebuilding (see below) | 292 | sections[i].size = 0; // will be ignored by rebuilding (see below) |
@@ -426,12 +431,19 @@ void elf_write_file(struct elf_params_t *params, elf_write_fn_t write, | |||
426 | 431 | ||
427 | write(user, 0, &ehdr, sizeof ehdr); | 432 | write(user, 0, &ehdr, sizeof ehdr); |
428 | 433 | ||
429 | /* allocate enough size to hold any combinaison of .text/.bss in the string table: | 434 | /* allocate enough size for the string table: |
430 | * - one empty name ("\0") | 435 | * - one empty name ("\0") |
431 | * - at most N names of the form ".textXXXX\0" or ".bssXXXX\0" | 436 | * - one name ".shstrtab\0" |
432 | * - one name ".shstrtab\0" */ | 437 | * - all section names with zeroes */ |
433 | char *strtbl_content = malloc(1 + strlen(".shstrtab") + 1 + | 438 | size_t strtbl_size = 1+ strlen(".shstrtab") + 1; |
434 | phnum * (strlen(".textXXXX") + 1)); | 439 | sec = params->first_section; |
440 | while(sec) | ||
441 | { | ||
442 | strtbl_size += strlen(sec->name) + 1; | ||
443 | sec = sec->next; | ||
444 | } | ||
445 | |||
446 | char *strtbl_content = malloc(strtbl_size); | ||
435 | 447 | ||
436 | strtbl_content[0] = '\0'; | 448 | strtbl_content[0] = '\0'; |
437 | strcpy(&strtbl_content[1], ".shstrtab"); | 449 | strcpy(&strtbl_content[1], ".shstrtab"); |
@@ -487,21 +499,14 @@ void elf_write_file(struct elf_params_t *params, elf_write_fn_t write, | |||
487 | offset += sizeof(Elf32_Shdr); | 499 | offset += sizeof(Elf32_Shdr); |
488 | } | 500 | } |
489 | 501 | ||
490 | uint32_t text_idx = 0; | ||
491 | uint32_t bss_idx = 0; | ||
492 | while(sec) | 502 | while(sec) |
493 | { | 503 | { |
494 | shdr.sh_name = strtbl_index; | 504 | shdr.sh_name = strtbl_index; |
505 | strtbl_index += 1 + sprintf(&strtbl_content[strtbl_index], "%s", sec->name); | ||
495 | if(sec->type == EST_LOAD) | 506 | if(sec->type == EST_LOAD) |
496 | { | ||
497 | strtbl_index += 1 + sprintf(&strtbl_content[strtbl_index], ".text%d", text_idx++); | ||
498 | shdr.sh_type = SHT_PROGBITS; | 507 | shdr.sh_type = SHT_PROGBITS; |
499 | } | ||
500 | else | 508 | else |
501 | { | ||
502 | strtbl_index += 1 + sprintf(&strtbl_content[strtbl_index], ".bss%d", bss_idx++); | ||
503 | shdr.sh_type = SHT_NOBITS; | 509 | shdr.sh_type = SHT_NOBITS; |
504 | } | ||
505 | shdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR; | 510 | shdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR; |
506 | shdr.sh_addr = sec->addr; | 511 | shdr.sh_addr = sec->addr; |
507 | shdr.sh_offset = sec->offset; | 512 | shdr.sh_offset = sec->offset; |
@@ -610,7 +615,7 @@ bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read, | |||
610 | void *data = xmalloc(shdr.sh_size); | 615 | void *data = xmalloc(shdr.sh_size); |
611 | if(!read(user, shdr.sh_offset, data, shdr.sh_size)) | 616 | if(!read(user, shdr.sh_offset, data, shdr.sh_size)) |
612 | error_printf("error read self section data\n"); | 617 | error_printf("error read self section data\n"); |
613 | elf_add_load_section(params, shdr.sh_addr, shdr.sh_size, data); | 618 | elf_add_load_section(params, shdr.sh_addr, shdr.sh_size, data, &strtab[shdr.sh_name]); |
614 | free(data); | 619 | free(data); |
615 | 620 | ||
616 | if(strtab) | 621 | if(strtab) |
@@ -618,7 +623,7 @@ bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read, | |||
618 | } | 623 | } |
619 | else if(shdr.sh_type == SHT_NOBITS && shdr.sh_flags & SHF_ALLOC) | 624 | else if(shdr.sh_type == SHT_NOBITS && shdr.sh_flags & SHF_ALLOC) |
620 | { | 625 | { |
621 | elf_add_fill_section(params, shdr.sh_addr, shdr.sh_size, 0); | 626 | elf_add_fill_section(params, shdr.sh_addr, shdr.sh_size, 0, &strtab[shdr.sh_name]); |
622 | if(strtab) | 627 | if(strtab) |
623 | printf(user, false, "create fill segment for %s\n", &strtab[shdr.sh_name]); | 628 | printf(user, false, "create fill segment for %s\n", &strtab[shdr.sh_name]); |
624 | } | 629 | } |
@@ -713,6 +718,7 @@ void elf_release(struct elf_params_t *params) | |||
713 | struct elf_section_t *next_sec = sec->next; | 718 | struct elf_section_t *next_sec = sec->next; |
714 | if(sec->type == EST_LOAD) | 719 | if(sec->type == EST_LOAD) |
715 | free(sec->section); | 720 | free(sec->section); |
721 | free(sec->name); | ||
716 | free(sec); | 722 | free(sec); |
717 | sec = next_sec; | 723 | sec = next_sec; |
718 | } | 724 | } |
diff --git a/utils/imxtools/sbtools/elf.h b/utils/imxtools/sbtools/elf.h index 91e160152c..403bab0712 100644 --- a/utils/imxtools/sbtools/elf.h +++ b/utils/imxtools/sbtools/elf.h | |||
@@ -39,6 +39,7 @@ enum elf_section_type_t | |||
39 | 39 | ||
40 | struct elf_section_t | 40 | struct elf_section_t |
41 | { | 41 | { |
42 | char *name; | ||
42 | uint32_t addr; /* virtual address */ | 43 | uint32_t addr; /* virtual address */ |
43 | uint32_t size; /* virtual size */ | 44 | uint32_t size; /* virtual size */ |
44 | enum elf_section_type_t type; | 45 | enum elf_section_type_t type; |
@@ -77,9 +78,9 @@ typedef void (*elf_printf_fn_t)(void *user, bool error, const char *fmt, ...); | |||
77 | 78 | ||
78 | void elf_init(struct elf_params_t *params); | 79 | void elf_init(struct elf_params_t *params); |
79 | void elf_add_load_section(struct elf_params_t *params, | 80 | void elf_add_load_section(struct elf_params_t *params, |
80 | uint32_t load_addr, uint32_t size, const void *section); | 81 | uint32_t load_addr, uint32_t size, const void *section, const char *name); |
81 | void elf_add_fill_section(struct elf_params_t *params, | 82 | void elf_add_fill_section(struct elf_params_t *params, |
82 | uint32_t fill_addr, uint32_t size, uint32_t pattern); | 83 | uint32_t fill_addr, uint32_t size, uint32_t pattern, const char *name); |
83 | uint32_t elf_translate_virtual_address(struct elf_params_t *params, uint32_t addr); | 84 | uint32_t elf_translate_virtual_address(struct elf_params_t *params, uint32_t addr); |
84 | void elf_translate_addresses(struct elf_params_t *params); | 85 | void elf_translate_addresses(struct elf_params_t *params); |
85 | void elf_simplify(struct elf_params_t *params); | 86 | void elf_simplify(struct elf_params_t *params); |
diff --git a/utils/imxtools/sbtools/sbtoelf.c b/utils/imxtools/sbtools/sbtoelf.c index a13e18b81d..95fc7381a9 100644 --- a/utils/imxtools/sbtools/sbtoelf.c +++ b/utils/imxtools/sbtools/sbtoelf.c | |||
@@ -107,16 +107,20 @@ static void extract_sb_section(struct sb_section_t *sec) | |||
107 | struct elf_params_t elf; | 107 | struct elf_params_t elf; |
108 | elf_init(&elf); | 108 | elf_init(&elf); |
109 | 109 | ||
110 | int bss_idx = 0, text_idx = 0; | ||
111 | char secname[32]; | ||
110 | for(int i = 0; i < sec->nr_insts; i++) | 112 | for(int i = 0; i < sec->nr_insts; i++) |
111 | { | 113 | { |
112 | struct sb_inst_t *inst = &sec->insts[i]; | 114 | struct sb_inst_t *inst = &sec->insts[i]; |
113 | switch(inst->inst) | 115 | switch(inst->inst) |
114 | { | 116 | { |
115 | case SB_INST_LOAD: | 117 | case SB_INST_LOAD: |
116 | elf_add_load_section(&elf, inst->addr, inst->size, inst->data); | 118 | sprintf(secname, ".text%d", text_idx++); |
119 | elf_add_load_section(&elf, inst->addr, inst->size, inst->data, secname); | ||
117 | break; | 120 | break; |
118 | case SB_INST_FILL: | 121 | case SB_INST_FILL: |
119 | elf_add_fill_section(&elf, inst->addr, inst->size, inst->pattern); | 122 | sprintf(secname, ".bss%d", bss_idx++); |
123 | elf_add_fill_section(&elf, inst->addr, inst->size, inst->pattern, secname); | ||
120 | break; | 124 | break; |
121 | case SB_INST_CALL: | 125 | case SB_INST_CALL: |
122 | case SB_INST_JUMP: | 126 | case SB_INST_JUMP: |
@@ -124,6 +128,7 @@ static void extract_sb_section(struct sb_section_t *sec) | |||
124 | extract_elf_section(&elf, elf_count++, sec->identifier); | 128 | extract_elf_section(&elf, elf_count++, sec->identifier); |
125 | elf_release(&elf); | 129 | elf_release(&elf); |
126 | elf_init(&elf); | 130 | elf_init(&elf); |
131 | bss_idx = text_idx = 0; | ||
127 | break; | 132 | break; |
128 | default: | 133 | default: |
129 | /* ignore mode and nop */ | 134 | /* ignore mode and nop */ |
@@ -166,16 +171,20 @@ static void extract_sb1_file(struct sb1_file_t *file) | |||
166 | struct elf_params_t elf; | 171 | struct elf_params_t elf; |
167 | elf_init(&elf); | 172 | elf_init(&elf); |
168 | 173 | ||
174 | int bss_idx = 0, text_idx = 0; | ||
175 | char secname[32]; | ||
169 | for(int i = 0; i < file->nr_insts; i++) | 176 | for(int i = 0; i < file->nr_insts; i++) |
170 | { | 177 | { |
171 | struct sb1_inst_t *inst = &file->insts[i]; | 178 | struct sb1_inst_t *inst = &file->insts[i]; |
172 | switch(inst->cmd) | 179 | switch(inst->cmd) |
173 | { | 180 | { |
174 | case SB1_INST_LOAD: | 181 | case SB1_INST_LOAD: |
175 | elf_add_load_section(&elf, inst->addr, inst->size, inst->data); | 182 | sprintf(secname, ".text%d", text_idx++); |
183 | elf_add_load_section(&elf, inst->addr, inst->size, inst->data, secname); | ||
176 | break; | 184 | break; |
177 | case SB1_INST_FILL: | 185 | case SB1_INST_FILL: |
178 | elf_add_fill_section(&elf, inst->addr, inst->size, inst->pattern); | 186 | sprintf(secname, ".bss%d", bss_idx++); |
187 | elf_add_fill_section(&elf, inst->addr, inst->size, inst->pattern, secname); | ||
179 | break; | 188 | break; |
180 | case SB1_INST_CALL: | 189 | case SB1_INST_CALL: |
181 | case SB1_INST_JUMP: | 190 | case SB1_INST_JUMP: |