summaryrefslogtreecommitdiff
path: root/utils/sbtools
diff options
context:
space:
mode:
Diffstat (limited to 'utils/sbtools')
-rw-r--r--utils/sbtools/elf.c35
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
343bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read, 358bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read,