mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 13:15:18 -05:00
sbtools: make code aware of elf section names
Change-Id: I7ab657959e38d2fcb2c7e6d9858facfb83101423
This commit is contained in:
parent
da8ebcec2f
commit
76446dda45
3 changed files with 39 additions and 23 deletions
|
|
@ -18,9 +18,11 @@
|
|||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#define _POSIX_C_SOURCE 200809L /* for strdup */
|
||||
#include "elf.h"
|
||||
#include "misc.h"
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Definitions
|
||||
|
|
@ -190,10 +192,11 @@ static struct elf_segment_t *elf_add_segment(struct elf_params_t *params)
|
|||
}
|
||||
|
||||
void elf_add_load_section(struct elf_params_t *params,
|
||||
uint32_t load_addr, uint32_t size, const void *section)
|
||||
uint32_t load_addr, uint32_t size, const void *section, const char *name)
|
||||
{
|
||||
struct elf_section_t *sec = elf_add_section(params);
|
||||
|
||||
sec->name = strdup(name);
|
||||
sec->type = EST_LOAD;
|
||||
sec->addr = load_addr;
|
||||
sec->size = size;
|
||||
|
|
@ -202,7 +205,7 @@ void elf_add_load_section(struct elf_params_t *params,
|
|||
}
|
||||
|
||||
void elf_add_fill_section(struct elf_params_t *params,
|
||||
uint32_t fill_addr, uint32_t size, uint32_t pattern)
|
||||
uint32_t fill_addr, uint32_t size, uint32_t pattern, const char *name)
|
||||
{
|
||||
if(pattern != 0x00)
|
||||
{
|
||||
|
|
@ -212,6 +215,7 @@ void elf_add_fill_section(struct elf_params_t *params,
|
|||
|
||||
struct elf_section_t *sec = elf_add_section(params);
|
||||
|
||||
sec->name = strdup(name);
|
||||
sec->type = EST_FILL;
|
||||
sec->addr = fill_addr;
|
||||
sec->size = size;
|
||||
|
|
@ -282,6 +286,7 @@ void elf_simplify(struct elf_params_t *params)
|
|||
memcpy(data + cur_sec->size, sections[i].section, sections[i].size);
|
||||
free(cur_sec->section);
|
||||
free(sections[i].section);
|
||||
free(sections[i].name);
|
||||
cur_sec->section = data;
|
||||
cur_sec->size += sections[i].size;
|
||||
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,
|
|||
|
||||
write(user, 0, &ehdr, sizeof ehdr);
|
||||
|
||||
/* allocate enough size to hold any combinaison of .text/.bss in the string table:
|
||||
/* allocate enough size for the string table:
|
||||
* - one empty name ("\0")
|
||||
* - at most N names of the form ".textXXXX\0" or ".bssXXXX\0"
|
||||
* - one name ".shstrtab\0" */
|
||||
char *strtbl_content = malloc(1 + strlen(".shstrtab") + 1 +
|
||||
phnum * (strlen(".textXXXX") + 1));
|
||||
* - one name ".shstrtab\0"
|
||||
* - all section names with zeroes */
|
||||
size_t strtbl_size = 1+ strlen(".shstrtab") + 1;
|
||||
sec = params->first_section;
|
||||
while(sec)
|
||||
{
|
||||
strtbl_size += strlen(sec->name) + 1;
|
||||
sec = sec->next;
|
||||
}
|
||||
|
||||
char *strtbl_content = malloc(strtbl_size);
|
||||
|
||||
strtbl_content[0] = '\0';
|
||||
strcpy(&strtbl_content[1], ".shstrtab");
|
||||
|
|
@ -487,21 +499,14 @@ void elf_write_file(struct elf_params_t *params, elf_write_fn_t write,
|
|||
offset += sizeof(Elf32_Shdr);
|
||||
}
|
||||
|
||||
uint32_t text_idx = 0;
|
||||
uint32_t bss_idx = 0;
|
||||
while(sec)
|
||||
{
|
||||
shdr.sh_name = strtbl_index;
|
||||
strtbl_index += 1 + sprintf(&strtbl_content[strtbl_index], "%s", sec->name);
|
||||
if(sec->type == EST_LOAD)
|
||||
{
|
||||
strtbl_index += 1 + sprintf(&strtbl_content[strtbl_index], ".text%d", text_idx++);
|
||||
shdr.sh_type = SHT_PROGBITS;
|
||||
}
|
||||
else
|
||||
{
|
||||
strtbl_index += 1 + sprintf(&strtbl_content[strtbl_index], ".bss%d", bss_idx++);
|
||||
shdr.sh_type = SHT_NOBITS;
|
||||
}
|
||||
shdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR;
|
||||
shdr.sh_addr = sec->addr;
|
||||
shdr.sh_offset = sec->offset;
|
||||
|
|
@ -610,7 +615,7 @@ bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read,
|
|||
void *data = xmalloc(shdr.sh_size);
|
||||
if(!read(user, shdr.sh_offset, data, shdr.sh_size))
|
||||
error_printf("error read self section data\n");
|
||||
elf_add_load_section(params, shdr.sh_addr, shdr.sh_size, data);
|
||||
elf_add_load_section(params, shdr.sh_addr, shdr.sh_size, data, &strtab[shdr.sh_name]);
|
||||
free(data);
|
||||
|
||||
if(strtab)
|
||||
|
|
@ -618,7 +623,7 @@ bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read,
|
|||
}
|
||||
else if(shdr.sh_type == SHT_NOBITS && shdr.sh_flags & SHF_ALLOC)
|
||||
{
|
||||
elf_add_fill_section(params, shdr.sh_addr, shdr.sh_size, 0);
|
||||
elf_add_fill_section(params, shdr.sh_addr, shdr.sh_size, 0, &strtab[shdr.sh_name]);
|
||||
if(strtab)
|
||||
printf(user, false, "create fill segment for %s\n", &strtab[shdr.sh_name]);
|
||||
}
|
||||
|
|
@ -713,6 +718,7 @@ void elf_release(struct elf_params_t *params)
|
|||
struct elf_section_t *next_sec = sec->next;
|
||||
if(sec->type == EST_LOAD)
|
||||
free(sec->section);
|
||||
free(sec->name);
|
||||
free(sec);
|
||||
sec = next_sec;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ enum elf_section_type_t
|
|||
|
||||
struct elf_section_t
|
||||
{
|
||||
char *name;
|
||||
uint32_t addr; /* virtual address */
|
||||
uint32_t size; /* virtual size */
|
||||
enum elf_section_type_t type;
|
||||
|
|
@ -77,9 +78,9 @@ typedef void (*elf_printf_fn_t)(void *user, bool error, const char *fmt, ...);
|
|||
|
||||
void elf_init(struct elf_params_t *params);
|
||||
void elf_add_load_section(struct elf_params_t *params,
|
||||
uint32_t load_addr, uint32_t size, const void *section);
|
||||
uint32_t load_addr, uint32_t size, const void *section, const char *name);
|
||||
void elf_add_fill_section(struct elf_params_t *params,
|
||||
uint32_t fill_addr, uint32_t size, uint32_t pattern);
|
||||
uint32_t fill_addr, uint32_t size, uint32_t pattern, const char *name);
|
||||
uint32_t elf_translate_virtual_address(struct elf_params_t *params, uint32_t addr);
|
||||
void elf_translate_addresses(struct elf_params_t *params);
|
||||
void elf_simplify(struct elf_params_t *params);
|
||||
|
|
|
|||
|
|
@ -107,16 +107,20 @@ static void extract_sb_section(struct sb_section_t *sec)
|
|||
struct elf_params_t elf;
|
||||
elf_init(&elf);
|
||||
|
||||
int bss_idx = 0, text_idx = 0;
|
||||
char secname[32];
|
||||
for(int i = 0; i < sec->nr_insts; i++)
|
||||
{
|
||||
struct sb_inst_t *inst = &sec->insts[i];
|
||||
switch(inst->inst)
|
||||
{
|
||||
case SB_INST_LOAD:
|
||||
elf_add_load_section(&elf, inst->addr, inst->size, inst->data);
|
||||
sprintf(secname, ".text%d", text_idx++);
|
||||
elf_add_load_section(&elf, inst->addr, inst->size, inst->data, secname);
|
||||
break;
|
||||
case SB_INST_FILL:
|
||||
elf_add_fill_section(&elf, inst->addr, inst->size, inst->pattern);
|
||||
sprintf(secname, ".bss%d", bss_idx++);
|
||||
elf_add_fill_section(&elf, inst->addr, inst->size, inst->pattern, secname);
|
||||
break;
|
||||
case SB_INST_CALL:
|
||||
case SB_INST_JUMP:
|
||||
|
|
@ -124,6 +128,7 @@ static void extract_sb_section(struct sb_section_t *sec)
|
|||
extract_elf_section(&elf, elf_count++, sec->identifier);
|
||||
elf_release(&elf);
|
||||
elf_init(&elf);
|
||||
bss_idx = text_idx = 0;
|
||||
break;
|
||||
default:
|
||||
/* ignore mode and nop */
|
||||
|
|
@ -166,16 +171,20 @@ static void extract_sb1_file(struct sb1_file_t *file)
|
|||
struct elf_params_t elf;
|
||||
elf_init(&elf);
|
||||
|
||||
int bss_idx = 0, text_idx = 0;
|
||||
char secname[32];
|
||||
for(int i = 0; i < file->nr_insts; i++)
|
||||
{
|
||||
struct sb1_inst_t *inst = &file->insts[i];
|
||||
switch(inst->cmd)
|
||||
{
|
||||
case SB1_INST_LOAD:
|
||||
elf_add_load_section(&elf, inst->addr, inst->size, inst->data);
|
||||
sprintf(secname, ".text%d", text_idx++);
|
||||
elf_add_load_section(&elf, inst->addr, inst->size, inst->data, secname);
|
||||
break;
|
||||
case SB1_INST_FILL:
|
||||
elf_add_fill_section(&elf, inst->addr, inst->size, inst->pattern);
|
||||
sprintf(secname, ".bss%d", bss_idx++);
|
||||
elf_add_fill_section(&elf, inst->addr, inst->size, inst->pattern, secname);
|
||||
break;
|
||||
case SB1_INST_CALL:
|
||||
case SB1_INST_JUMP:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue