diff options
Diffstat (limited to 'utils/sbtools/elf.c')
-rw-r--r-- | utils/sbtools/elf.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/utils/sbtools/elf.c b/utils/sbtools/elf.c index 0acaf8dcd8..de8d9f93c5 100644 --- a/utils/sbtools/elf.c +++ b/utils/sbtools/elf.c | |||
@@ -194,11 +194,6 @@ void elf_write_file(struct elf_params_t *params, elf_write_fn_t write, void *use | |||
194 | Elf32_Shdr shdr; | 194 | Elf32_Shdr shdr; |
195 | memset(&ehdr, 0, EI_NIDENT); | 195 | memset(&ehdr, 0, EI_NIDENT); |
196 | 196 | ||
197 | uint32_t bss_strtbl = 1; | ||
198 | uint32_t text_strtbl = bss_strtbl + strlen(".bss") + 1; | ||
199 | uint32_t shstrtab_strtbl = text_strtbl + strlen(".text") + 1; | ||
200 | uint32_t strtbl_size = shstrtab_strtbl + strlen(".shstrtab") + 1; | ||
201 | |||
202 | while(sec) | 197 | while(sec) |
203 | { | 198 | { |
204 | if(sec->type == EST_LOAD) | 199 | if(sec->type == EST_LOAD) |
@@ -240,6 +235,17 @@ void elf_write_file(struct elf_params_t *params, elf_write_fn_t write, void *use | |||
240 | 235 | ||
241 | write(user, 0, &ehdr, sizeof ehdr); | 236 | write(user, 0, &ehdr, sizeof ehdr); |
242 | 237 | ||
238 | /* allocate enough size to hold any combinaison of .text/.bss in the string table: | ||
239 | * - one empty name ("\0") | ||
240 | * - at most N names of the form ".textXX\0" or ".bssXX\0" | ||
241 | * - one name ".shstrtab\0" */ | ||
242 | char *strtbl_content = malloc(1 + strlen(".shstrtab") + 1 + | ||
243 | phnum * (strlen(".textXX") + 1)); | ||
244 | |||
245 | strtbl_content[0] = '\0'; | ||
246 | strcpy(&strtbl_content[1], ".shstrtab"); | ||
247 | uint32_t strtbl_index = 1 + strlen(".shstrtab") + 1; | ||
248 | |||
243 | uint32_t data_offset = ehdr.e_ehsize + ehdr.e_phnum * ehdr.e_phentsize + | 249 | uint32_t data_offset = ehdr.e_ehsize + ehdr.e_phnum * ehdr.e_phentsize + |
244 | ehdr.e_shnum * ehdr.e_shentsize; | 250 | ehdr.e_shnum * ehdr.e_shentsize; |
245 | 251 | ||
@@ -289,14 +295,22 @@ void elf_write_file(struct elf_params_t *params, elf_write_fn_t write, void *use | |||
289 | 295 | ||
290 | offset += sizeof(Elf32_Shdr); | 296 | offset += sizeof(Elf32_Shdr); |
291 | } | 297 | } |
292 | 298 | ||
299 | uint32_t text_idx = 0; | ||
300 | uint32_t bss_idx = 0; | ||
293 | while(sec) | 301 | while(sec) |
294 | { | 302 | { |
295 | shdr.sh_name = text_strtbl; | 303 | shdr.sh_name = strtbl_index; |
296 | if(sec->type == EST_LOAD) | 304 | if(sec->type == EST_LOAD) |
305 | { | ||
306 | strtbl_index += 1 + sprintf(&strtbl_content[strtbl_index], ".text%d", text_idx++); | ||
297 | shdr.sh_type = SHT_PROGBITS; | 307 | shdr.sh_type = SHT_PROGBITS; |
308 | } | ||
298 | else | 309 | else |
310 | { | ||
311 | strtbl_index += 1 + sprintf(&strtbl_content[strtbl_index], ".bss%d", bss_idx++); | ||
299 | shdr.sh_type = SHT_NOBITS; | 312 | shdr.sh_type = SHT_NOBITS; |
313 | } | ||
300 | shdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR; | 314 | shdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR; |
301 | shdr.sh_addr = sec->addr; | 315 | shdr.sh_addr = sec->addr; |
302 | shdr.sh_offset = sec->offset; | 316 | shdr.sh_offset = sec->offset; |
@@ -313,12 +327,12 @@ void elf_write_file(struct elf_params_t *params, elf_write_fn_t write, void *use | |||
313 | } | 327 | } |
314 | 328 | ||
315 | { | 329 | { |
316 | shdr.sh_name = shstrtab_strtbl; | 330 | shdr.sh_name = 1; |
317 | shdr.sh_type = SHT_STRTAB; | 331 | shdr.sh_type = SHT_STRTAB; |
318 | shdr.sh_flags = 0; | 332 | shdr.sh_flags = 0; |
319 | shdr.sh_addr = 0; | 333 | shdr.sh_addr = 0; |
320 | shdr.sh_offset = strtbl_offset + data_offset; | 334 | shdr.sh_offset = strtbl_offset + data_offset; |
321 | shdr.sh_size = strtbl_size; | 335 | shdr.sh_size = strtbl_index; |
322 | shdr.sh_link = SHN_UNDEF; | 336 | shdr.sh_link = SHN_UNDEF; |
323 | shdr.sh_info = 0; | 337 | shdr.sh_info = 0; |
324 | shdr.sh_addralign = 1; | 338 | shdr.sh_addralign = 1; |
@@ -337,7 +351,8 @@ void elf_write_file(struct elf_params_t *params, elf_write_fn_t write, void *use | |||
337 | sec = sec->next; | 351 | sec = sec->next; |
338 | } | 352 | } |
339 | 353 | ||
340 | write(user, strtbl_offset + data_offset, "\0.bss\0.text\0.shstrtab\0", strtbl_size); | 354 | write(user, strtbl_offset + data_offset, strtbl_content, strtbl_index); |
355 | free(strtbl_content); | ||
341 | } | 356 | } |
342 | 357 | ||
343 | bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read, | 358 | bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read, |