static void extract_elf_section(struct elf_params_t *elf, int count, uint32_t id, struct cmd_file_t *cmd_file, struct cmd_section_t *section, bool is_call, uint32_t arg) { char name[5]; char fileid[16]; char *filename = xmalloc(strlen(g_out_prefix) + 32); sb_fill_section_name(name, id); sb_fill_section_name(fileid, id); sprintf(fileid + strlen(fileid), "%d", count); sprintf(filename, "%s%s.%d.elf", g_out_prefix, name, count); db_add_source(cmd_file, fileid, filename + strlen(g_out_prefix)); db_add_inst_id(section, CMD_LOAD, fileid, 0); if(elf_get_start_addr(elf, NULL)) db_add_inst_id(section, is_call ? CMD_CALL : CMD_JUMP, fileid, arg); if(g_debug) printf("Write boot section %s to %s\n", name, filename); FILE *fd = fopen(filename, "wb"); free(filename); if(fd == NULL) return; if(g_elf_simplify) elf_simplify(elf); elf_write_file(elf, elf_std_write, generic_std_printf, fd); 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_elf_section(struct elf_params_t *elf, int count, uint32_t id) { 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); if(fd == NULL) return ; elf_write_file(elf, elf_write, elf_printf, fd); fclose(fd); }
static void extract_sb_section(struct sb_section_t *sec, struct cmd_file_t *cmd_file) { struct cmd_section_t *db_sec = db_add_section(cmd_file, sec->identifier, sec->is_data); db_add_int_opt(&db_sec->opt_list, "alignment", sec->alignment); db_add_int_opt(&db_sec->opt_list, "cleartext", sec->is_cleartext); db_add_int_opt(&db_sec->opt_list, "sectionFlags", sec->other_flags); 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); db_add_source(cmd_file, sec_name, filename + strlen(g_out_prefix)); db_sec->source_id = strdup(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); 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: sprintf(secname, ".text%d", text_idx++); elf_add_load_section(&elf, inst->addr, inst->size, inst->data, secname); break; case SB_INST_FILL: 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: elf_set_start_addr(&elf, inst->addr); extract_elf_section(&elf, elf_count++, sec->identifier, cmd_file, db_sec, inst->inst == SB_INST_CALL, inst->argument); elf_release(&elf); elf_init(&elf); bss_idx = text_idx = 0; break; default: /* ignore mode and nop */ break; } } if(!elf_is_empty(&elf)) extract_elf_section(&elf, elf_count, sec->identifier, cmd_file, db_sec, false, 0); elf_release(&elf); }