diff options
Diffstat (limited to 'utils/imxtools/sbtools/elf.c')
-rw-r--r-- | utils/imxtools/sbtools/elf.c | 40 |
1 files changed, 23 insertions, 17 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 | } |