#include static inline void scc_ir_sym_to_sccf_sym(const scc_cfg_symbol_t *symbol, sccf_sym_t *sym) { switch (symbol->kind) { case SCC_CFG_SYMBOL_KIND_DATA: sym->sccf_sym_type = SCCF_SYM_TYPE_DATA; break; case SCC_CFG_SYMBOL_KIND_FUNC: sym->sccf_sym_type = SCCF_SYM_TYPE_FUNC; break; case SCC_CFG_SYMBOL_KIND_EXTERN: sym->sccf_sym_type = SCCF_SYM_TYPE_EXTERN; break; } switch (symbol->linkage) { case SCC_CFG_SYMBOL_LINK_GLOABL: sym->sccf_sym_bind = SCCF_SYM_BIND_GLOBAL; break; case SCC_CFG_SYMBOL_LINK_LOCAL: sym->sccf_sym_bind = SCCF_SYM_BIND_LOCAL; break; default: break; } } static inline void scc_ir_symbol_to_sect_data(const scc_cfg_symbol_t *symbol, sccf_sect_data_t *sect_data) { // scc_vec_foreach(value->data.const_array.fields, j) { // scc_vec_push(ctx->sect_data, // scc_vec_at(value->data.const_array.fields, j)); // } } void scc_ir2sccf(sccf_builder_t *builder, scc_mir_module_t *mir_module) { // mir_module->symbol_metas // mir_module->cfg_module.funcs sccf_builder_init(builder); sccf_sect_data_t sect_data; scc_vec_init(sect_data); scc_vec_foreach(mir_module->cfg_module.symbols, i) { scc_cfg_symbol_t *symbol = &scc_vec_at(mir_module->cfg_module.symbols, i); if (symbol->name == nullptr) { LOG_ERROR("Symbol name is null"); continue; } sccf_sym_t sym = (sccf_sym_t){ .sccf_sect_offset = scc_vec_size(sect_data), .sccf_sym_size = 4, // FIXME on windows using rel32, on linux using ? }; scc_ir_sym_to_sccf_sym(symbol, &sym); scc_ir_symbol_to_sect_data(symbol, §_data); usize sym_idx = sccf_builder_add_symbol(builder, symbol->name, &sym); Assert(sym_idx != 0); } sccf_sect_data_t sect_code = {0}; scc_vec_init(sect_code); scc_mcode_t mcode = {0}; scc_mcode_init(&mcode, SCC_MCODE_ARCH_X86_64); scc_vec_foreach(mir_module->cfg_module.funcs, i) { if (i == 0) continue; scc_mir_func_t *func = &scc_vec_at(mir_module->cfg_module.funcs, i); sccf_sym_t *sym = sccf_builder_get_symbol_unsafe(builder, func->name); Assert(sym != nullptr); sym->sccf_sect_offset = scc_vec_size(mcode.mcode); scc_vec_foreach(func->bblocks, i) { scc_cfg_bblock_id_t id = scc_vec_at(func->bblocks, i); const scc_cfg_bblock_t *bb = scc_cfg_module_unsafe_get_bblock(&mir_module->cfg_module, id); scc_mir_instr_vec_t *instrs = SCC_MIR_BBLOCK_VALUES(bb); scc_vec_foreach(*instrs, i) { const scc_mir_instr_t *ins = &scc_vec_at(*instrs, i); // FIXME reloc symbol needed scc_ir2mcode_emit_instr(&mcode, ins); } } } scc_vec_unsafe_from_buffer(sect_code, scc_vec_unsafe_get_data(mcode.mcode), scc_vec_size(mcode.mcode)); // u8 *buf = scc_vec_unsafe_get_data(ctx->sect_mcode.mcode); // scc_vec_foreach(ctx->builder->relocs, i) { // sccf_reloc_t *reloc = &scc_vec_at(ctx->builder->relocs, i); // if (reloc->sym_idx == 0) { // Panic("relocate to an invalid symbol"); // } // sccf_sym_t *sym = &scc_vec_at(ctx->builder->symtab, reloc->sym_idx); // if (sym->sccf_sym_type != SCCF_SYM_TYPE_EXTERN) { // Assert(reloc->reloc_type == SCCF_RELOC_TYPE_REL); // if (sym->sccf_sect_type == SCCF_SECT_CODE && // sym->sccf_sym_type == SCCF_SYM_TYPE_FUNC) { // i64 target_off = sym->sccf_sect_offset; // i64 next_off = reloc->offset + reloc->addend; // i32 rel = (i32)(target_off - next_off); // // FIXME 写入到指令的偏移字段(小端) // *(i32 *)(&buf[reloc->offset]) = rel; // reloc->reloc_type = SCCF_RELOC_TYPE_EMPTY; // } // } // } sccf_builder_add_text_section(builder, §_code); sccf_builder_add_data_section(builder, §_data); }