sbtoos: restore elf extraction functionality of sbtoelf

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30882 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Amaury Pouly 2011-11-01 11:26:16 +00:00
parent e36471df9c
commit dd0fffe50f
3 changed files with 80 additions and 15 deletions

View file

@ -571,7 +571,7 @@ static struct sb_section_t *read_section(bool data_sec, uint32_t id, byte *buf,
#undef printf
}
static void fill_section_name(char name[5], uint32_t identifier)
void sb_fill_section_name(char name[5], uint32_t identifier)
{
name[0] = (identifier >> 24) & 0xff;
name[1] = (identifier >> 16) & 0xff;
@ -773,7 +773,7 @@ struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
struct crypto_key_t k;
char *env = getenv("SB_REAL_KEY");
if(!parse_key(&env, &k) || *env)
bug("Invalid SB_REAL_KEY");
bug("Invalid SB_REAL_KEY\n");
memcpy(real_key, k.u.key, 16);
}
@ -801,7 +801,7 @@ struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
struct sb_section_header_t *sec_hdr = (struct sb_section_header_t *)&buf[ofs];
char name[5];
fill_section_name(name, sec_hdr->identifier);
sb_fill_section_name(name, sec_hdr->identifier);
int pos = sec_hdr->offset * BLOCK_SIZE;
int size = sec_hdr->size * BLOCK_SIZE;
int data_sec = !(sec_hdr->flags & SECTION_BOOTABLE);
@ -889,7 +889,7 @@ struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
offset += sizeof(struct sb_instruction_tag_t);
char name[5];
fill_section_name(name, tag->identifier);
sb_fill_section_name(name, tag->identifier);
int pos = offset;
int size = tag->len * BLOCK_SIZE;
int data_sec = !(tag->flags & SECTION_BOOTABLE);
@ -1004,7 +1004,7 @@ void sb_dump(struct sb_file_t *file, void *u, sb_color_printf cprintf)
printf(TREE, "+-");
printf(HEADER, "First Boot Section ID: ");
char name[5];
fill_section_name(name, file->first_boot_sec_id);
sb_fill_section_name(name, file->first_boot_sec_id);
printf(TEXT, "%08x (%s)\n", file->first_boot_sec_id, name);
if(file->real_key)
@ -1035,7 +1035,7 @@ void sb_dump(struct sb_file_t *file, void *u, sb_color_printf cprintf)
printf(HEADER, "Section\n");
printf(TREE,"| +-");
printf(HEADER, "Identifier: ");
fill_section_name(name, sec->identifier);
sb_fill_section_name(name, sec->identifier);
printf(TEXT, "%08x (%s)\n", sec->identifier, name);
printf(TREE, "| +-");
printf(HEADER, "Type: ");

View file

@ -213,6 +213,7 @@ typedef void (*sb_color_printf)(void *u, bool err, color_t c, const char *f, ...
struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
sb_color_printf printf);
void sb_fill_section_name(char name[5], uint32_t identifier);
void sb_dump(struct sb_file_t *file, void *u, sb_color_printf printf);
#endif /* __SB_H__ */

View file

@ -76,12 +76,14 @@ static void elf_write(void *user, uint32_t addr, const void *buf, size_t count)
fwrite(buf, count, 1, f);
}
static void extract_elf_section(struct elf_params_t *elf, int count, const char *prefix,
const char *indent)
static void extract_elf_section(struct elf_params_t *elf, int count, uint32_t id)
{
char *filename = xmalloc(strlen(prefix) + 32);
sprintf(filename, "%s.%d.elf", prefix, count);
printf("%swrite %s\n", indent, filename);
char name[5];
char *filename = xmalloc(strlen(g_out_prefix) + 32);
sb_fill_section_name(name, id);
sprintf(filename, "%s%s.%d.elf", g_out_prefix, name, count);
if(g_debug)
printf("Write boot section %s to %s\n", name, filename);
FILE *fd = fopen(filename, "wb");
free(filename);
@ -92,12 +94,74 @@ static void extract_elf_section(struct elf_params_t *elf, int count, const char
fclose(fd);
}
static void extract_sb_section(struct sb_section_t *sec)
{
if(sec->is_data)
{
char sec_name[5];
char *filename = xmalloc(strlen(g_out_prefix) + 32);
sb_fill_section_name(sec_name, sec->identifier);
sprintf(filename, "%s%s.bin", g_out_prefix, sec_name);
FILE *fd = fopen(filename, "wb");
if(fd == NULL)
bugp("Cannot open %s for writing\n", filename);
if(g_debug)
printf("Write data section %s to %s\n", sec_name, filename);
free(filename);
for(int j = 0; j < sec->nr_insts; j++)
{
assert(sec->insts[j].inst == SB_INST_DATA);
fwrite(sec->insts[j].data, sec->insts[j].size, 1, fd);
}
fclose(fd);
}
int elf_count = 0;
struct elf_params_t elf;
elf_init(&elf);
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);
break;
case SB_INST_FILL:
elf_add_fill_section(&elf, inst->addr, inst->size, inst->pattern);
break;
case SB_INST_CALL:
case SB_INST_JUMP:
elf_set_start_addr(&elf, inst->addr);
extract_elf_section(&elf, elf_count++, sec->identifier);
elf_release(&elf);
elf_init(&elf);
break;
default:
/* ignore mode and nop */
break;
}
}
if(!elf_is_empty(&elf))
extract_elf_section(&elf, elf_count, sec->identifier);
elf_release(&elf);
}
static void extract_sb_file(struct sb_file_t *file)
{
for(int i = 0; i < file->nr_sections; i++)
extract_sb_section(&file->sections[i]);
}
static void usage(void)
{
printf("Usage: sbtoelf [options] sb-file\n");
printf("Options:\n");
printf(" -?/--help\tDisplay this message\n");
printf(" -o <file>\tSet output prefix\n");
printf(" -o <prefix>\tEnable output and set prefix\n");
printf(" -d/--debug\tEnable debug output*\n");
printf(" -k <file>\tAdd key file\n");
printf(" -z\t\tAdd zero key\n");
@ -196,9 +260,6 @@ int main(int argc, char **argv)
}
}
if(g_out_prefix == NULL)
g_out_prefix = "";
if(argc - optind != 1)
{
usage();
@ -208,6 +269,9 @@ int main(int argc, char **argv)
const char *sb_filename = argv[optind];
struct sb_file_t *file = sb_read_file(sb_filename, raw_mode, NULL, sb_printf);
color(OFF);
if(g_out_prefix)
extract_sb_file(file);
if(g_debug)
{
color(GREY);