summaryrefslogtreecommitdiff
path: root/utils/imxtools/sbtools/elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/imxtools/sbtools/elf.c')
-rw-r--r--utils/imxtools/sbtools/elf.c40
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
192void elf_add_load_section(struct elf_params_t *params, 194void 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
204void elf_add_fill_section(struct elf_params_t *params, 207void 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 }