From: yu.dongliang <18588496441@163.com> Date: Sat, 10 Jan 2026 12:55:47 +0000 (+0800) Subject: asm: ../lib/x64/_start.s ok X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=60f0faa7cf0337ad4e5dc93204c4e9343edcb017;p=scf.git asm: ../lib/x64/_start.s ok --- diff --git a/asm/1.s b/asm/1.s index c184d42..ab14439 100644 --- a/asm/1.s +++ b/asm/1.s @@ -3,11 +3,12 @@ main: push %rbp - leaq hello, %rdi + movq pointer, %rdi xorq %rax, %rax call printf pop %rbp ret .data +pointer: .quad hello hello: .asciz "hello world\n" diff --git a/asm/scf_asm.c b/asm/scf_asm.c index 6ac4408..2cc9756 100644 --- a/asm/scf_asm.c +++ b/asm/scf_asm.c @@ -1,6 +1,8 @@ #include"scf_asm.h" #include"scf_symtab.h" +void _x64_set_offset_for_jmps(scf_vector_t* text); + int scf_asm_open(scf_asm_t** pasm) { if (!pasm) @@ -152,6 +154,8 @@ static int __asm_add_text(scf_elf_context_t* elf, scf_asm_t* _asm) if (!text) return -ENOMEM; + _x64_set_offset_for_jmps(_asm->text); + for (i = 0; i < _asm->text->size; i++) { inst = _asm->text->data[i]; @@ -346,14 +350,14 @@ static int __asm_add_rela_data(scf_elf_context_t* elf, scf_asm_t* _asm) if (relas->size > 0) { scf_elf_section_t s = {0}; - s.name = ".rela.text"; + s.name = ".rela.data"; s.sh_type = SHT_RELA; s.sh_flags = SHF_INFO_LINK; s.sh_addralign = 8; s.data = NULL; s.data_len = 0; s.sh_link = 0; - s.sh_info = ASM_SHNDX_TEXT; + s.sh_info = ASM_SHNDX_DATA; ret = scf_elf_add_rela_section(elf, &s, relas); } @@ -406,16 +410,9 @@ int scf_asm_to_obj(scf_asm_t* _asm, const char* obj, const char* arch) if (ret < 0) goto error; - scf_elf_sym_t* sym; - int i; - - for (i = 0; i < _asm->symtab->size; i++) { - sym = _asm->symtab->data[i]; - - ret = scf_elf_add_sym(elf, sym, ".symtab"); - if (ret < 0) - goto error; - } + ret = scf_elf_add_syms(elf, _asm->symtab, ".symtab"); + if (ret < 0) + goto error; ret = scf_elf_write_rel(elf); error: diff --git a/asm/scf_asm.h b/asm/scf_asm.h index 2bcc75d..dffcf9a 100644 --- a/asm/scf_asm.h +++ b/asm/scf_asm.h @@ -41,6 +41,7 @@ struct dfa_asm_s { scf_lex_word_t* label; scf_lex_word_t* global; + scf_lex_word_t* fill; scf_OpCode_t* opcode; scf_inst_data_t operands[4]; diff --git a/asm/scf_dfa_inst.c b/asm/scf_dfa_inst.c index 4b2d223..feb6422 100644 --- a/asm/scf_dfa_inst.c +++ b/asm/scf_dfa_inst.c @@ -27,11 +27,25 @@ static int _inst_is_global(scf_dfa_t* dfa, void* word) return SCF_LEX_WORD_ASM_GLOBAL == w->type; } -static int _inst_is_asciz(scf_dfa_t* dfa, void* word) +static int _inst_is_fill(scf_dfa_t* dfa, void* word) { scf_lex_word_t* w = word; - return SCF_LEX_WORD_ASM_ASCIZ == w->type; + return SCF_LEX_WORD_ASM_FILL == w->type; +} + +static int _inst_is_type(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_ASM_BYTE <= w->type && SCF_LEX_WORD_ASM_ASCIZ >= w->type; +} + +static int _inst_is_number(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_CONST_CHAR <= w->type && SCF_LEX_WORD_CONST_DOUBLE >= w->type; } static int _inst_is_str(scf_dfa_t* dfa, void* word) @@ -95,7 +109,18 @@ static int _inst_action_global(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_NEXT_WORD; } -static int _inst_action_asciz(scf_dfa_t* dfa, scf_vector_t* words, void* data) +static int _inst_action_fill(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_asm_t* _asm = dfa->priv; + dfa_asm_t* d = data; + scf_lex_word_t* w = words->data[words->size - 1]; + + d->fill = w; + + return SCF_DFA_NEXT_WORD; +} + +static int _inst_action_type(scf_dfa_t* dfa, scf_vector_t* words, void* data) { scf_asm_t* _asm = dfa->priv; dfa_asm_t* d = data; @@ -108,6 +133,135 @@ static int _inst_action_asciz(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_NEXT_WORD; } +static int _inst_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_asm_t* _asm = dfa->priv; + dfa_asm_t* d = data; + scf_lex_word_t* w = words->data[words->size - 1]; + scf_lex_word_t* w2; + scf_instruction_t* inst; + + w2 = dfa->ops->pop_word(dfa); + dfa->ops->push_word(dfa, w2); + + if (d->opcode) { + switch (w2->type) { + case SCF_LEX_WORD_LP: + d->operands[d->i].disp = w->data.u64; + d->operands[d->i].flag = 1; + break; + + case SCF_LEX_WORD_RP: + d->operands[d->i].scale = w->data.i; + d->operands[d->i].flag = 1; + break; + + case SCF_LEX_WORD_ID: + case SCF_LEX_WORD_COMMA: + case SCF_LEX_WORD_LF: + if (d->n_lp != d->n_rp) { + scf_loge("'(' not equal to ')' in file: %s, line: %d\n", w->file->data, w->line); + return SCF_DFA_ERROR; + } + + d->operands[d->i].imm = w->data.u64; + d->operands[d->i].imm_size = 8; + d->operands[d->i].flag = 0; + + if (SCF_LEX_WORD_ID == w2->type) { + if (SCF_X64_JZ > d->opcode->type || SCF_X64_JMP < d->opcode->type) { + scf_loge("opcode '%s' MUST be jcc/jmp, in file: %s, line: %d\n", w->text->data, w->file->data, w->line); + return SCF_DFA_ERROR; + } + + switch (w2->text->data[0]) { + case 'b': + d->operands[d->i].imm <<= 8; + d->operands[d->i].imm |= 0x1; + break; + case 'f': + d->operands[d->i].imm <<= 8; + d->operands[d->i].imm |= 0x2; + break; + default: + scf_loge("the char followed a number label MUST be 'b' or 'f', but real '%c' in file: %s, line: %d\n", + w2->text->data[0], w->file->data, w->line); + return SCF_DFA_ERROR; + break; + }; + + w2 = dfa->ops->pop_word(dfa); + dfa->ops->free_word(w2); + w2 = NULL; + } + + d->i++; + break; + default: + scf_loge("number '%s', w2: %s, file: %s, line: %d\n", w->text->data, w2->text->data, w->file->data, w->line); + return -1; + break; + }; + + } else if (d->fill) { + switch (w2->type) { + case SCF_LEX_WORD_COMMA: + case SCF_LEX_WORD_LF: + if (d->n_lp != d->n_rp) { + scf_loge("'(' not equal to ')' in file: %s, line: %d\n", w->file->data, w->line); + return SCF_DFA_ERROR; + } + + d->operands[d->i].imm = w->data.u64; + d->operands[d->i].flag = 0; + d->i++; + break; + default: + scf_loge("number '%s', w2: %s, file: %s, line: %d\n", w->text->data, w2->text->data, w->file->data, w->line); + return -1; + break; + }; + + } else if (SCF_LEX_WORD_LF == w2->type || SCF_LEX_WORD_COMMA == w2->type) { + int n; + switch (d->type) { + case SCF_LEX_WORD_ASM_BYTE: + n = 1; + break; + case SCF_LEX_WORD_ASM_WORD: + n = 2; + break; + + case SCF_LEX_WORD_ASM_LONG: + n = 4; + break; + case SCF_LEX_WORD_ASM_QUAD: + n = 8; + break; + default: + scf_loge("const number '%s' MUST be '.byte', '.word', '.long' or '.quad' type, file: %s, line: %d\n", + w->text->data, w->file->data, w->line); + return -1; + break; + }; + + inst = calloc(1, sizeof(scf_instruction_t)); + if (!inst) + return -ENOMEM; + + memcpy(inst->code, (uint8_t*)&w->data, n); + inst->len = n; + + X64_INST_ADD_CHECK(_asm->current, inst, NULL); + if (d->label) { + inst->label = d->label; + d ->label = NULL; + } + } + + return SCF_DFA_NEXT_WORD; +} + static int _inst_action_str(scf_dfa_t* dfa, scf_vector_t* words, void* data) { scf_asm_t* _asm = dfa->priv; @@ -148,7 +302,7 @@ static int _inst_action_str(scf_dfa_t* dfa, scf_vector_t* words, void* data) } } - X64_INST_ADD_CHECK(_asm->current, inst); + X64_INST_ADD_CHECK(_asm->current, inst, NULL); if (d->label) { inst->label = d->label; d ->label = NULL; @@ -193,6 +347,54 @@ static int _inst_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data scf_lex_word_free(w2); return ret; } + + } else { + w2 = dfa->ops->pop_word(dfa); + dfa->ops->push_word(dfa, w2); + + if (SCF_LEX_WORD_LF == w2->type || SCF_LEX_WORD_COMMA == w2->type) { + + if (SCF_LEX_WORD_ASM_QUAD != d->type) { + scf_loge("the type of label '%s' MUST be .quad, file: %s, line: %d\n", + w->text->data, w->file->data, w->line); + return -1; + } + + scf_instruction_t* inst = calloc(1, sizeof(scf_instruction_t)); + if (!inst) + return -ENOMEM; + inst->len = 8; + X64_INST_ADD_CHECK(_asm->current, inst, NULL); + + if (d->label) { + inst->label = d->label; + d ->label = NULL; + } + + scf_rela_t* rela = calloc(1, sizeof(scf_rela_t)); + if (!rela) + return -ENOMEM; + + rela->name = scf_string_clone(w->text); + if (!rela->name) { + scf_rela_free(rela); + return -ENOMEM; + } + + rela->inst = inst; + rela->type = R_X86_64_64; + + int ret; + if (_asm->current == _asm->text) + ret = scf_vector_add(_asm->text_relas, rela); + else + ret = scf_vector_add(_asm->data_relas, rela); + + if (ret < 0) { + scf_rela_free(rela); + return ret; + } + } } return SCF_DFA_NEXT_WORD; @@ -249,6 +451,26 @@ static int _inst_action_reg(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_NEXT_WORD; } +static int _inst_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + dfa_asm_t* d = data; + + d->n_lp++; + return SCF_DFA_NEXT_WORD; +} + +static int _inst_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + dfa_asm_t* d = data; + + if (++d->n_rp == d->n_lp) { + d->operands[d->i].flag = 1; + d->i++; + } + + return SCF_DFA_NEXT_WORD; +} + static int _inst_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data) { scf_asm_t* _asm = dfa->priv; @@ -294,6 +516,7 @@ static int _inst_action_colon(scf_dfa_t* dfa, scf_vector_t* words, void* data) } } + scf_logi("w->text->data: %s, w->data.u32: %d, w->type: %d\n", w->text->data, w->data.u32, w->type); d->label = scf_lex_word_clone(w); if (!d->label) return -ENOMEM; @@ -301,109 +524,221 @@ static int _inst_action_colon(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_NEXT_WORD; } -static int _inst_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data) +static int __inst_op2(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w) { - scf_asm_t* _asm = dfa->priv; - dfa_asm_t* d = data; - scf_lex_word_t* w = words->data[words->size - 1]; + scf_x64_OpCode_t* opcode = (scf_x64_OpCode_t*)d->opcode; + scf_instruction_t* inst = NULL; + scf_inst_data_t* id0 = &d->operands[0]; + scf_inst_data_t* id1 = &d->operands[1]; - if (d->opcode) { - scf_instruction_t* inst; - scf_x64_OpCode_t* opcode = (scf_x64_OpCode_t*)d->opcode; - scf_inst_data_t* id0; - scf_inst_data_t* id1; + int OpBytes = opcode->OpBytes; + int RegBytes = opcode->RegBytes; + int EG = opcode->EG; - int OpBytes = opcode->OpBytes; - int RegBytes = opcode->RegBytes; - int EG = opcode->EG; + if (__inst_data_is_reg(id0)) { + OpBytes = id0->base->bytes; - if (2 == d->i) { - id0 = &d->operands[0]; - id1 = &d->operands[1]; + if (__inst_data_is_reg(id1)) { + RegBytes = id1->base->bytes; - if (__inst_data_is_reg(id0)) { - OpBytes = id0->base->bytes; + opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E2G); + if (!opcode) { + opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_G2E); - if (__inst_data_is_reg(id1)) { - RegBytes = id1->base->bytes; + if (!opcode) { + scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line); + return SCF_DFA_ERROR; + } - opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E2G); - if (!opcode) { - scf_loge("valid opcode '%s' NOT found, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line); - return SCF_DFA_ERROR; - } + inst = x64_make_inst_G2E(opcode, id1->base, id0->base); + } else + inst = x64_make_inst_E2G(opcode, id1->base, id0->base); - inst = x64_make_inst_E2G(opcode, id1->base, id0->base); - X64_INST_ADD_CHECK(_asm->current, inst); + X64_INST_ADD_CHECK(_asm->current, inst, NULL); + } + } else if (__inst_data_is_const(id0)) { + uint64_t imm = id0->imm; + + if (imm >> 32) + OpBytes = 8; + else if (imm >> 16) + OpBytes = 4; + else if (imm >> 8) + OpBytes = 2; + else + OpBytes = 1; + + if (__inst_data_is_reg(id1)) { + RegBytes = id1->base->bytes; + + int i; + for (i = OpBytes; i <= RegBytes; i <<= 1) { + opcode = x64_find_OpCode(d->opcode->type, i, RegBytes, SCF_X64_I2E); + if (opcode) { + inst = x64_make_inst_I2E(opcode, id1->base, (uint8_t*)&imm, i); + break; } + } - } else if (__inst_data_is_reg(id1)) { - RegBytes = id1->base->bytes; + if (i > RegBytes) { + for (i = OpBytes; i <= RegBytes; i <<= 1) { + opcode = x64_find_OpCode(d->opcode->type, i, RegBytes, SCF_X64_I2G); + if (opcode) { + inst = x64_make_inst_I2G(opcode, id1->base, (uint8_t*)&imm, i); + break; + } + } - opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E2G); - if (!opcode) { - scf_loge("valid opcode '%s' NOT found, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line); + if (i > RegBytes) { + scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line); return SCF_DFA_ERROR; } + } - scf_rela_t* rela = NULL; + X64_INST_ADD_CHECK(_asm->current, inst, NULL); + } + + } else if (__inst_data_is_reg(id1)) { + RegBytes = id1->base->bytes; + OpBytes = RegBytes; + + scf_logi("OpBytes: %d, RegBytes: %d\n", OpBytes, RegBytes); + + opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E2G); + if (!opcode) { + scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line); + return SCF_DFA_ERROR; + } + + int32_t disp = id0->disp; + if (id0->label) + disp = 0x1000; // make disp to 4bytes, only for disp from a label - inst = x64_make_inst_L2G(&rela, opcode, id1->base); - X64_INST_ADD_CHECK(_asm->current, inst); - X64_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id0->label->text); + if (id1->index) + inst = x64_make_inst_SIB2G(opcode, id1->base, id0->base, id0->index, id0->scale, disp); + else + inst = x64_make_inst_P2G(opcode, id1->base, id0->base, disp); + X64_INST_ADD_CHECK(_asm->current, inst, NULL); + + if (id0->label) { + scf_rela_t* rela = calloc(1, sizeof(scf_rela_t)); + if (!rela) + return -ENOMEM; + + *(uint32_t*)(inst->code + inst->len - 4) = 0; + + rela->inst_offset = inst->len - 4; + X64_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id0->label->text); + } + } else { + scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line); + return SCF_DFA_ERROR; + } + + *__inst = inst; + return 0; +} + +static int __inst_op1(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w) +{ + scf_x64_OpCode_t* opcode = (scf_x64_OpCode_t*)d->opcode; + scf_instruction_t* inst = NULL; + scf_inst_data_t* id = &d->operands[0]; + + int OpBytes = opcode->OpBytes; + int RegBytes = opcode->RegBytes; + int EG = opcode->EG; + + if (__inst_data_is_reg(id)) { + OpBytes = id->base->bytes; + + opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_G); + if (!opcode) { + opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E); + if (!opcode) { + scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line); + return SCF_DFA_ERROR; } - } else if (1 == d->i) { - id0 = &d->operands[0]; + inst = x64_make_inst_E(opcode, id->base); + } else + inst = x64_make_inst_G(opcode, id->base); + X64_INST_ADD_CHECK(_asm->current, inst, NULL); - if (__inst_data_is_reg(id0)) { - OpBytes = id0->base->bytes; + } else { + scf_rela_t* rela = NULL; - opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_G); - if (!opcode) { - opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E); - if (!opcode) { - scf_loge("valid opcode '%s' NOT found, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line); - return SCF_DFA_ERROR; - } + if (SCF_X64_CALL == d->opcode->type + || (SCF_X64_JZ <= d->opcode->type && SCF_X64_JMP >= d->opcode->type)) { + uint32_t disp = 0; - inst = x64_make_inst_E(opcode, id0->base); - } else - inst = x64_make_inst_G(opcode, id0->base); - X64_INST_ADD_CHECK(_asm->current, inst); + if (!id->label) + disp = id->imm; - } else { - scf_rela_t* rela = NULL; - uint32_t disp = 0; - - if (SCF_X64_CALL == d->opcode->type) { - opcode = x64_find_OpCode(d->opcode->type, 4, 4, SCF_X64_I); - inst = x64_make_inst_I(opcode, (uint8_t*)&disp, 4); - X64_INST_ADD_CHECK(_asm->current, inst); - - rela = calloc(1, sizeof(scf_rela_t)); - if (!rela) - return -ENOMEM; - - rela->inst_offset = 1; - X64_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id0->label->text); - } else { - opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E); - if (!opcode) { - scf_loge("valid opcode '%s' NOT found, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line); - return SCF_DFA_ERROR; - } + opcode = x64_find_OpCode(d->opcode->type, 4, 4, SCF_X64_I); + inst = x64_make_inst_I(opcode, (uint8_t*)&disp, 4); + X64_INST_ADD_CHECK(_asm->current, inst, NULL); - inst = x64_make_inst_L(&rela, opcode); - X64_INST_ADD_CHECK(_asm->current, inst); - X64_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id0->label->text); - } + if (id->label) { + rela = calloc(1, sizeof(scf_rela_t)); + if (!rela) + return -ENOMEM; + + rela->inst_offset = inst->len - 4; + scf_logw("rela->inst_offset: %d, inst->len: %d\n", rela->inst_offset, inst->len); + X64_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id->label->text); } } else { - inst = x64_make_inst(opcode, 8); - X64_INST_ADD_CHECK(_asm->current, inst); + opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E); + if (!opcode) { + scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line); + return SCF_DFA_ERROR; + } + + inst = x64_make_inst_L(&rela, opcode); + X64_INST_ADD_CHECK(_asm->current, inst, rela); + X64_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id->label->text); } + } + + *__inst = inst; + return 0; +} + +static int _inst_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_asm_t* _asm = dfa->priv; + dfa_asm_t* d = data; + scf_lex_word_t* w = words->data[words->size - 1]; + scf_instruction_t* inst = NULL; + + if (d->opcode) { + scf_x64_OpCode_t* opcode = (scf_x64_OpCode_t*)d->opcode; + scf_inst_data_t* id0; + + int OpBytes = opcode->OpBytes; + int RegBytes = opcode->RegBytes; + int EG = opcode->EG; + + int ret = 0; + switch (d->i) { + case 2: + ret = __inst_op2(&inst, _asm, d, w); + break; + case 1: + ret = __inst_op1(&inst, _asm, d, w); + break; + case 0: + inst = x64_make_inst(opcode, 8); + X64_INST_ADD_CHECK(_asm->current, inst, NULL); + break; + default: + break; + }; + + if (ret < 0) + return ret; if (d->label) { inst->label = d->label; @@ -412,6 +747,45 @@ static int _inst_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_instruction_print(inst); d->opcode = NULL; + + } else if (d->fill) { + if (d->i < 3) { + scf_loge(".fill needs 3 operands, file: %s, line: %d\n", d->fill->file->data, d->fill->line); + return SCF_DFA_ERROR; + } + + int64_t n = d->operands[0].imm; + int64_t size = d->operands[1].imm; + uint64_t imm = d->operands[2].imm; + int64_t i; + + inst = calloc(1, sizeof(scf_instruction_t)); + if (!inst) + return -ENOMEM; + + if (n * size <= sizeof(inst->code)) { + for (i = 0; i < n; i++) + memcpy(inst->code + i * size, (uint8_t*)&imm, size); + + inst->len = n * size; + } else { + inst->bin = scf_string_alloc(); + if (inst->bin) { + scf_instruction_free(inst); + return -ENOMEM; + } + + for (i = 0; i < n; i++) { + int ret = scf_string_cat_cstr_len(inst->bin, (uint8_t*)&imm, size); + if (ret < 0) { + scf_instruction_free(inst); + return -ENOMEM; + } + } + } + + X64_INST_ADD_CHECK(_asm->current, inst, NULL); + d->fill = NULL; } for (int i = 0; i < 4; i++) { @@ -431,14 +805,166 @@ static int _inst_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_OK; } +static int _inst_action_hash(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_asm_t* _asm = dfa->priv; + dfa_asm_t* d = data; + scf_lex_word_t* w = words->data[words->size - 1]; + + while (w = dfa->ops->pop_word(dfa)) + { + if (SCF_LEX_WORD_LF == w->type) { + dfa->ops->push_word(dfa, w); + break; + } + + dfa->ops->free_word(w); + } + + return SCF_DFA_NEXT_WORD; +} + +int _x64_set_offset_for_jmps(scf_vector_t* text) +{ + scf_instruction_t* inst; + scf_instruction_t* dst; + int i; + int j; + + for (i = 0; i < text->size; i++) { + inst = text->data[i]; + + if (!inst->OpCode) + continue; + + if (inst->OpCode->type != SCF_X64_CALL + && (inst->OpCode->type < SCF_X64_JZ || inst->OpCode->type > SCF_X64_JMP)) + continue; + + int32_t bytes = 0; + uint32_t label = *(uint32_t*)(inst->code + inst->len - 4); + uint32_t flag = label & 0xff; + label >>= 8; + + switch (flag) { + case 1: + for (j = i; j >= 0; j--) { + dst = text->data[j]; + + if (dst->label + && scf_lex_is_const_integer(dst->label) + && dst->label->data.u32 == label) { + inst->next = dst; + break; + } + } + + if (j < 0) { + scf_loge("number label %d NOT found\n", label); + return -1; + } + break; + + case 2: + for (j = i + 1; j < text->size; j++) { + dst = text->data[j]; + + if (dst->label + && scf_lex_is_const_integer(dst->label) + && dst->label->data.u32 == label) { + inst->next = dst; + break; + } + } + + if (j >= text->size) { + scf_loge("number label %d NOT found\n", label); + return -1; + } + break; + default: + break; + }; + } + + while (1) { + int drop_bytes = 0; + + for (i = 0; i < text->size; i++) { + inst = text->data[i]; + + if (!inst->OpCode || !inst->next) + continue; + + if (inst->OpCode->type != SCF_X64_CALL + && (inst->OpCode->type < SCF_X64_JZ || inst->OpCode->type > SCF_X64_JMP)) + continue; + + int32_t bytes = 0; + uint32_t label = *(uint32_t*)(inst->code + inst->len - 4); + uint32_t front = label & 0xff; + label >>= 8; + + if (front) { + for (j = i + 1; j < text->size; j++) { + dst = text->data[j]; + + if (dst == inst->next) + break; + + if (dst->len > 0) + bytes += dst->len; + else if (dst->bin) + bytes += dst->bin->len; + } + } else { + for (j = i; j >= 0; j--) { + dst = text->data[j]; + + if (dst->len > 0) + bytes -= dst->len; + else if (dst->bin) + bytes -= dst->bin->len; + + if (dst == inst->next) + break; + } + } + + scf_x64_OpCode_t* opcode = (scf_x64_OpCode_t*)inst->OpCode; + int n_bytes = 4; + + if (SCF_X64_CALL != opcode->type) { + if (-128 <= bytes && bytes <= 127) + n_bytes = 1; + + opcode = x64_find_OpCode(opcode->type, n_bytes, n_bytes, SCF_X64_I); + } + + int old_len = inst->len; + x64_make_inst_I2(inst, opcode, (uint8_t*)&bytes, n_bytes); + + int diff = old_len - inst->len; + assert(diff >= 0); + + drop_bytes += diff; + } + + if (0 == drop_bytes) + break; + } +} + static int _dfa_init_module_inst(scf_dfa_t* dfa) { SCF_DFA_MODULE_NODE(dfa, inst, text, _inst_is_text, _inst_action_text); SCF_DFA_MODULE_NODE(dfa, inst, data, _inst_is_data, _inst_action_data); SCF_DFA_MODULE_NODE(dfa, inst, global, _inst_is_global, _inst_action_global); + SCF_DFA_MODULE_NODE(dfa, inst, fill, _inst_is_fill, _inst_action_fill); - SCF_DFA_MODULE_NODE(dfa, inst, asciz, _inst_is_asciz, _inst_action_asciz); + SCF_DFA_MODULE_NODE(dfa, inst, type, _inst_is_type, _inst_action_type); SCF_DFA_MODULE_NODE(dfa, inst, str, _inst_is_str, _inst_action_str); + SCF_DFA_MODULE_NODE(dfa, inst, number, _inst_is_number, _inst_action_number); SCF_DFA_MODULE_NODE(dfa, inst, identity, scf_dfa_is_identity, _inst_action_identity); SCF_DFA_MODULE_NODE(dfa, inst, colon, scf_dfa_is_colon, _inst_action_colon); @@ -447,8 +973,12 @@ static int _dfa_init_module_inst(scf_dfa_t* dfa) SCF_DFA_MODULE_NODE(dfa, inst, reg, _inst_is_reg, _inst_action_reg); SCF_DFA_MODULE_NODE(dfa, inst, percent, _inst_is_percent, scf_dfa_action_next); + SCF_DFA_MODULE_NODE(dfa, inst, lp, scf_dfa_is_lp, _inst_action_lp); + SCF_DFA_MODULE_NODE(dfa, inst, rp, scf_dfa_is_rp, _inst_action_rp); + SCF_DFA_MODULE_NODE(dfa, inst, comma, scf_dfa_is_comma, _inst_action_comma); SCF_DFA_MODULE_NODE(dfa, inst, LF, scf_dfa_is_LF, _inst_action_LF); + SCF_DFA_MODULE_NODE(dfa, inst, HASH, scf_dfa_is_hash, _inst_action_hash); scf_asm_t* _asm = dfa->priv; dfa_asm_t* d = _asm->dfa_data; @@ -463,29 +993,37 @@ static int _dfa_init_syntax_inst(scf_dfa_t* dfa) SCF_DFA_GET_MODULE_NODE(dfa, inst, text, text); SCF_DFA_GET_MODULE_NODE(dfa, inst, data, data); SCF_DFA_GET_MODULE_NODE(dfa, inst, global, global); + SCF_DFA_GET_MODULE_NODE(dfa, inst, fill, fill); SCF_DFA_GET_MODULE_NODE(dfa, inst, identity, identity); SCF_DFA_GET_MODULE_NODE(dfa, inst, colon, colon); - SCF_DFA_GET_MODULE_NODE(dfa, inst, asciz, asciz); + SCF_DFA_GET_MODULE_NODE(dfa, inst, type, type); SCF_DFA_GET_MODULE_NODE(dfa, inst, str, str); + SCF_DFA_GET_MODULE_NODE(dfa, inst, number, number); SCF_DFA_GET_MODULE_NODE(dfa, inst, opcode, opcode); SCF_DFA_GET_MODULE_NODE(dfa, inst, reg, reg); SCF_DFA_GET_MODULE_NODE(dfa, inst, percent, percent); + SCF_DFA_GET_MODULE_NODE(dfa, inst, lp, lp); + SCF_DFA_GET_MODULE_NODE(dfa, inst, rp, rp); SCF_DFA_GET_MODULE_NODE(dfa, inst, comma, comma); SCF_DFA_GET_MODULE_NODE(dfa, inst, LF, LF); + SCF_DFA_GET_MODULE_NODE(dfa, inst, HASH, HASH); // asm syntax scf_vector_add(dfa->syntaxes, text); scf_vector_add(dfa->syntaxes, data); scf_vector_add(dfa->syntaxes, global); + scf_vector_add(dfa->syntaxes, fill); scf_vector_add(dfa->syntaxes, opcode); scf_vector_add(dfa->syntaxes, identity); + scf_vector_add(dfa->syntaxes, number); - scf_vector_add(dfa->syntaxes, asciz); + scf_vector_add(dfa->syntaxes, type); + scf_vector_add(dfa->syntaxes, HASH); scf_vector_add(dfa->syntaxes, LF); // .text .data @@ -502,18 +1040,33 @@ static int _dfa_init_syntax_inst(scf_dfa_t* dfa) // label: scf_dfa_node_add_child(identity, colon); + scf_dfa_node_add_child(number, colon); scf_dfa_node_add_child(colon, LF); // .asciz - scf_dfa_node_add_child(asciz, str); + scf_dfa_node_add_child(type, str); + scf_dfa_node_add_child(type, number); + scf_dfa_node_add_child(type, identity); + scf_dfa_node_add_child(str, LF); + scf_dfa_node_add_child(number, LF); + scf_dfa_node_add_child(identity, LF); // asm instruction scf_dfa_node_add_child(opcode, identity); - + scf_dfa_node_add_child(opcode, number); scf_dfa_node_add_child(opcode, reg); + + scf_dfa_node_add_child(identity, comma); + scf_dfa_node_add_child(number, comma); scf_dfa_node_add_child(reg, comma); + + scf_dfa_node_add_child(comma, identity); + scf_dfa_node_add_child(comma, number); scf_dfa_node_add_child(comma, reg); + + scf_dfa_node_add_child(identity, LF); + scf_dfa_node_add_child(number, LF); scf_dfa_node_add_child(reg, LF); // %reg of 'AT & T' @@ -521,6 +1074,23 @@ static int _dfa_init_syntax_inst(scf_dfa_t* dfa) scf_dfa_node_add_child(opcode, percent); scf_dfa_node_add_child(comma, percent); + // memory addr such as: (rax), 8(rax), disp(rax, rcx, 8), + scf_dfa_node_add_child(opcode, lp); + scf_dfa_node_add_child(identity, lp); + scf_dfa_node_add_child(number, lp); + + scf_dfa_node_add_child(lp, percent); + scf_dfa_node_add_child(lp, reg); + scf_dfa_node_add_child(lp, comma); // ( , rcx, 8), empty base == 0 + + scf_dfa_node_add_child(reg, rp); + scf_dfa_node_add_child(number, rp); + scf_dfa_node_add_child(rp, comma); + scf_dfa_node_add_child(rp, LF); + + // .fill + scf_dfa_node_add_child(fill, number); + return SCF_DFA_OK; } diff --git a/core/scf_lex_word.h b/core/scf_lex_word.h index 0e21194..a1f0b3e 100644 --- a/core/scf_lex_word.h +++ b/core/scf_lex_word.h @@ -76,6 +76,7 @@ enum scf_lex_words SCF_LEX_WORD_LF, // '\n', line feed, LF SCF_LEX_WORD_HASH, // # hash SCF_LEX_WORD_HASH2, // ## hash2 + SCF_LEX_WORD_DOLLAR, // $ dollar SCF_LEX_WORD_COMMA, // , comma SCF_LEX_WORD_SEMICOLON, // ; diff --git a/elf/scf_elf.c b/elf/scf_elf.c index 76e5f29..1d5c020 100644 --- a/elf/scf_elf.c +++ b/elf/scf_elf.c @@ -124,6 +124,22 @@ int scf_elf_add_sym(scf_elf_context_t* elf, const scf_elf_sym_t* sym, const char return -1; } +int scf_elf_add_syms(scf_elf_context_t* elf, const scf_vector_t* syms, const char* sh_name) +{ + scf_elf_sym_t* sym; + int i; + + for (i = 0; i < syms->size; i++) { + sym = syms->data[i]; + + int ret = scf_elf_add_sym(elf, sym, sh_name); + if (ret < 0) + return ret; + } + + return 0; +} + int scf_elf_add_section(scf_elf_context_t* elf, const scf_elf_section_t* section) { if (elf && section) { diff --git a/elf/scf_elf.h b/elf/scf_elf.h index c810fc9..b3599aa 100644 --- a/elf/scf_elf.h +++ b/elf/scf_elf.h @@ -92,9 +92,10 @@ int scf_elf_open (scf_elf_context_t** pelf, const char* machine, const char* pat int scf_elf_open2(scf_elf_context_t* elf, const char* machine); int scf_elf_close(scf_elf_context_t* elf); -int scf_elf_add_sym (scf_elf_context_t* elf, const scf_elf_sym_t* sym, const char* sh_name); -int scf_elf_add_section(scf_elf_context_t* elf, const scf_elf_section_t* section); +int scf_elf_add_sym (scf_elf_context_t* elf, const scf_elf_sym_t* sym, const char* sh_name); +int scf_elf_add_syms(scf_elf_context_t* elf, const scf_vector_t* syms, const char* sh_name); +int scf_elf_add_section (scf_elf_context_t* elf, const scf_elf_section_t* section); int scf_elf_add_rela_section(scf_elf_context_t* elf, const scf_elf_section_t* section, scf_vector_t* relas); int scf_elf_add_dyn_need(scf_elf_context_t* elf, const char* soname); int scf_elf_add_dyn_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela); diff --git a/lex/scf_lex.c b/lex/scf_lex.c index 5c8a2ff..7ef03b9 100644 --- a/lex/scf_lex.c +++ b/lex/scf_lex.c @@ -679,10 +679,8 @@ int __lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword) || '\r' == c->c || '\t' == c->c || ' ' == c->c || '\\' == c->c) { - if ('\n' == c->c) { - lex->nb_lines++; - lex->pos = 0; - + if ('\n' == c->c) + { if (SCF_UTF8_LF == c->flag || lex->asm_flag) { w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_LF); @@ -691,8 +689,14 @@ int __lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword) free(c); c = NULL; + + lex->nb_lines++; + lex->pos = 0; return 0; } + + lex->nb_lines++; + lex->pos = 0; } else lex->pos++; @@ -914,7 +918,41 @@ int __lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword) return _lex_macro(lex); } + if ('$' == c->c && lex->asm_flag) + { + free(c); + c = _lex_pop_char(lex); + if (!c) + return -1; + + if ('0' <= c->c && '9' >= c->c) + return _lex_number(lex, pword, c); + + if ('_' == c->c + || ('a' <= c->c && 'z' >= c->c) + || ('A' <= c->c && 'Z' >= c->c) + || (0x4e00 <= c->c && 0x9fa5 >= c->c)) { // support China chars + + _lex_push_char(lex, c); + + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_DOLLAR); + if (!w) + return -ENOMEM; + + w->text = scf_string_cstr("$"); + if (!w->text) { + scf_lex_word_free(w); + return -ENOMEM; + } + + *pword = w; + return 0; + } + } + scf_loge("unknown char: %c, utf: %#x, in file: %s, line: %d\n", c->c, c->c, lex->file->data, lex->nb_lines); + + free(c); return -1; } @@ -1469,7 +1507,14 @@ int scf_lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword) case SCF_LEX_WORD_KEY_DEFINE: ret = __parse_macro_define(lex); break; + default: + if (lex->asm_flag) { + scf_lex_push_word(lex, w1); + *pword = w; + return 0; + } + scf_loge("unknown macro '%s', file: %s, line: %d\n", w1->text->data, w1->file->data, w1->line); ret = -1; break; diff --git a/native/x64/scf_x64.c b/native/x64/scf_x64.c index ced05ba..7ec69c3 100644 --- a/native/x64/scf_x64.c +++ b/native/x64/scf_x64.c @@ -154,7 +154,7 @@ static int _x64_save_rabi(scf_function_t* f) #define X64_SAVE_RABI(offset, rabi) \ do { \ inst = x64_make_inst_G2P(mov, rbp, offset, rabi); \ - X64_INST_ADD_CHECK(f->init_code->instructions, inst); \ + X64_INST_ADD_CHECK(f->init_code->instructions, inst, NULL); \ f->init_code_bytes += inst->len; \ } while (0) @@ -220,12 +220,12 @@ static int _x64_function_finish(scf_function_t* f) if (f->bp_used_flag || f->vla_flag || f->call_flag) { inst = x64_make_inst_G2E(mov, rsp, rbp); - X64_INST_ADD_CHECK(end->instructions, inst); + X64_INST_ADD_CHECK(end->instructions, inst, NULL); end->inst_bytes += inst->len; bb ->code_bytes += inst->len; inst = x64_make_inst_G(pop, rbp); - X64_INST_ADD_CHECK(end->instructions, inst); + X64_INST_ADD_CHECK(end->instructions, inst, NULL); end->inst_bytes += inst->len; bb ->code_bytes += inst->len; } @@ -245,11 +245,11 @@ static int _x64_function_finish(scf_function_t* f) if (f->bp_used_flag || f->vla_flag || f->call_flag) { inst = x64_make_inst_G(push, rbp); - X64_INST_ADD_CHECK(f->init_code->instructions, inst); + X64_INST_ADD_CHECK(f->init_code->instructions, inst, NULL); f->init_code_bytes += inst->len; inst = x64_make_inst_G2E(mov, rbp, rsp); - X64_INST_ADD_CHECK(f->init_code->instructions, inst); + X64_INST_ADD_CHECK(f->init_code->instructions, inst, NULL); f->init_code_bytes += inst->len; if (f->callee_saved_size & 0xf) { @@ -264,7 +264,7 @@ static int _x64_function_finish(scf_function_t* f) local, f->local_vars_size, f->callee_saved_size); inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&local, 4); - X64_INST_ADD_CHECK(f->init_code->instructions, inst); + X64_INST_ADD_CHECK(f->init_code->instructions, inst, NULL); f->init_code_bytes += inst->len; int err = _x64_save_rabi(f); @@ -273,7 +273,7 @@ static int _x64_function_finish(scf_function_t* f) } inst = x64_make_inst(ret, 8); - X64_INST_ADD_CHECK(end->instructions, inst); + X64_INST_ADD_CHECK(end->instructions, inst, NULL); end->inst_bytes += inst->len; bb ->code_bytes += inst->len; diff --git a/native/x64/scf_x64_inst.c b/native/x64/scf_x64_inst.c index c98b96f..51c6b9b 100644 --- a/native/x64/scf_x64_inst.c +++ b/native/x64/scf_x64_inst.c @@ -107,7 +107,6 @@ static int _x64_inst_call_stack_size(scf_3ac_code_t* c) static int _x64_inst_call_argv(scf_3ac_code_t* c, scf_function_t* f) { scf_register_t* rsp = x64_find_register("rsp"); - scf_x64_OpCode_t* lea; scf_x64_OpCode_t* mov; scf_x64_OpCode_t* movx; @@ -205,11 +204,11 @@ static int _x64_inst_call_argv(scf_3ac_code_t* c, scf_function_t* f) if (!rd) { if (movx) { inst = x64_make_inst_E2G(movx, rs, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } inst = x64_make_inst_G2P(mov, rsp, v->sp_offset, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); continue; } @@ -222,12 +221,12 @@ static int _x64_inst_call_argv(scf_3ac_code_t* c, scf_function_t* f) if (!X64_COLOR_CONFLICT(rd->color, rs->color)) { if (movx) { inst = x64_make_inst_E2G(movx, rs, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } rd = x64_find_register_color_bytes(rd->color, rs->bytes); inst = x64_make_inst_G2E(mov, rd, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else if (movx) { inst = x64_make_inst_E2G(movx, rs, rs); @@ -241,7 +240,7 @@ static int _x64_inst_call_argv(scf_3ac_code_t* c, scf_function_t* f) } for (i = 0; i < nb_movx; i++) { - X64_INST_ADD_CHECK(c->instructions, inst_movx[i]); + X64_INST_ADD_CHECK(c->instructions, inst_movx[i], NULL); } return nb_floats; @@ -307,7 +306,6 @@ static int _x64_call_update_dsts(scf_3ac_code_t* c, scf_function_t* f, scf_regis scf_3ac_operand_t* dst; scf_dag_node_t* dn; scf_variable_t* v; - scf_register_t* rd; scf_register_t* rs; scf_x64_OpCode_t* mov; @@ -401,7 +399,7 @@ static int _x64_call_update_dsts(scf_3ac_code_t* c, scf_function_t* f, scf_regis int valid = _x64_dst_reg_valid(rd, updated_regs, nb_updated, idx_int, nb_int); if (valid) { inst = x64_make_inst_G2E(mov, rd, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); assert(nb_updated < max_updated); @@ -428,8 +426,6 @@ static int _x64_call_update_dsts(scf_3ac_code_t* c, scf_function_t* f, scf_regis dn->color = rs->color; dn->loaded = 1; } else { - scf_rela_t* rela = NULL; - if (0 == v->bp_offset && !v->global_flag && !v->local_flag) { int size = f->local_vars_size + dst_size; @@ -445,8 +441,10 @@ static int _x64_call_update_dsts(scf_3ac_code_t* c, scf_function_t* f, scf_regis scf_logd("v->bp_offset: %d, local_flag: %d, tmp_flag: %d, rs->name: %s\n", v->bp_offset, v->local_flag, v->tmp_flag, rs->name); } + scf_rela_t* rela = NULL; + inst = x64_make_inst_G2M(&rela, mov, dn->var, NULL, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, dn->var, NULL); } } @@ -462,7 +460,6 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) scf_x64_context_t* x64 = ctx->priv; scf_function_t* f = x64->f; - scf_3ac_operand_t* src0 = c->srcs->data[0]; scf_variable_t* var_pf = src0->dag_node->var; scf_function_t* pf = var_pf->func_ptr; @@ -514,9 +511,9 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) int32_t stack_size = _x64_inst_call_stack_size(c); if (stack_size > 0) { - sub = x64_find_OpCode(SCF_X64_SUB, 4,4, SCF_X64_I2E); + sub = x64_find_OpCode(SCF_X64_SUB, 4,4, SCF_X64_I2E); inst_rsp = x64_make_inst_I2E(sub, rsp, (uint8_t*)&stack_size, 4); - X64_INST_ADD_CHECK(c->instructions, inst_rsp); + X64_INST_ADD_CHECK(c->instructions, inst_rsp, NULL); } ret = _x64_inst_call_argv(c, f); @@ -528,7 +525,7 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) mov = x64_find_OpCode(SCF_X64_MOV, 4,4, SCF_X64_I2G); inst = x64_make_inst_I2G(mov, eax, (uint8_t*)&imm, sizeof(imm)); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); scf_register_t* saved_regs[X64_ABI_CALLER_SAVES_NB]; @@ -550,7 +547,7 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) int32_t offset = 0; call = x64_find_OpCode(SCF_X64_CALL, 4,4, SCF_X64_I); inst = x64_make_inst_I(call, (uint8_t*)&offset, 4); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst->OpCode = (scf_OpCode_t*)call; @@ -576,14 +573,14 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) } inst = x64_make_inst_E(call, r_pf); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst->OpCode = (scf_OpCode_t*)call; } else { scf_rela_t* rela = NULL; inst = x64_make_inst_M(&rela, call, var_pf, NULL); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, pf); inst->OpCode = (scf_OpCode_t*)call; @@ -593,7 +590,7 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) if (stack_size > 0) { add = x64_find_OpCode(SCF_X64_ADD, 4, 4, SCF_X64_I2E); inst = x64_make_inst_I2E(add, rsp, (uint8_t*)&stack_size, 4); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } int nb_updated = 0; @@ -654,8 +651,8 @@ static int _x64_inst_unary(scf_native_t* ctx, scf_3ac_code_t* c, int OpCode_type scf_instruction_t* inst = NULL; scf_register_t* rd = NULL; scf_variable_t* var = dst->dag_node->var; - scf_x64_OpCode_t* OpCode = x64_find_OpCode(OpCode_type, var->size, var->size, SCF_X64_E); + if (!OpCode) { scf_loge("\n"); return -1; @@ -664,13 +661,12 @@ static int _x64_inst_unary(scf_native_t* ctx, scf_3ac_code_t* c, int OpCode_type if (dst->dag_node->color > 0) { X64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); inst = x64_make_inst_E(OpCode, rd); - X64_INST_ADD_CHECK(c->instructions, inst); - + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { scf_rela_t* rela = NULL; inst = x64_make_inst_M(&rela, OpCode, var, NULL); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, var, NULL); } @@ -698,8 +694,8 @@ static int _x64_inst_unary_assign(scf_native_t* ctx, scf_3ac_code_t* c, int OpCo scf_instruction_t* inst = NULL; scf_register_t* rs = NULL; scf_variable_t* var = src->dag_node->var; - scf_x64_OpCode_t* OpCode = x64_find_OpCode(OpCode_type, var->size, var->size, SCF_X64_E); + if (!OpCode) { scf_loge("\n"); return -1; @@ -708,7 +704,7 @@ static int _x64_inst_unary_assign(scf_native_t* ctx, scf_3ac_code_t* c, int OpCo if (src->dag_node->color > 0) { X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); inst = x64_make_inst_E(OpCode, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else if (0 == src->dag_node->color) { scf_loge("\n"); @@ -717,7 +713,7 @@ static int _x64_inst_unary_assign(scf_native_t* ctx, scf_3ac_code_t* c, int OpCo scf_rela_t* rela = NULL; inst = x64_make_inst_M(&rela, OpCode, var, NULL); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, var, NULL); } @@ -776,17 +772,14 @@ static int _x64_inst_neg_handler(scf_native_t* ctx, scf_3ac_code_t* c) X64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); inst = x64_make_inst_E2G(pxor, rd, rd); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); if (src->dag_node->color > 0) { X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); inst = x64_make_inst_E2G(sub, rd, rs); - X64_INST_ADD_CHECK(c->instructions, inst); - + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { - scf_rela_t* rela = NULL; - v = src->dag_node->var; if (0 == src->dag_node->color) { @@ -795,8 +788,10 @@ static int _x64_inst_neg_handler(scf_native_t* ctx, scf_3ac_code_t* c) v->tmp_flag = 0; } + scf_rela_t* rela = NULL; + inst = x64_make_inst_M2G(&rela, sub, rd, NULL, v); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL); } @@ -851,7 +846,7 @@ static int _x64_inst_inc_float(scf_function_t* f, scf_3ac_code_t* c, int INC) X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); inst = x64_make_inst_M2G(&rela, OpCode, rs, NULL, v1); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, v1, NULL); return 0; } @@ -903,12 +898,12 @@ static int _x64_inst_inc(scf_native_t* ctx, scf_3ac_code_t* c, int INC, int ADD) if (src->dag_node->color > 0) { X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); inst = x64_make_inst_I2E(OpCode, rs, (uint8_t*)&v->data_size, imm_size); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { scf_rela_t* rela = NULL; inst = x64_make_inst_I2M(&rela, OpCode, v, NULL, (uint8_t*)&v->data_size, imm_size); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL); } @@ -916,12 +911,12 @@ static int _x64_inst_inc(scf_native_t* ctx, scf_3ac_code_t* c, int INC, int ADD) if (src->dag_node->color > 0) { X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); inst = x64_make_inst_E(OpCode, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { scf_rela_t* rela = NULL; inst = x64_make_inst_M(&rela, OpCode, v, NULL); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL); } } @@ -1017,7 +1012,7 @@ static int _x64_inst_assign_array_index(scf_native_t* ctx, scf_3ac_code_t* c, in else inst = x64_make_inst_I2P(OpCode, sib.base, sib.disp, (uint8_t*)&vs->data, size); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } @@ -1043,10 +1038,10 @@ static int _x64_inst_assign_array_index(scf_native_t* ctx, scf_3ac_code_t* c, in if (sib.index) { inst = x64_make_inst_G2SIB(OpCode, sib.base, sib.index, sib.scale, sib.disp, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { inst = x64_make_inst_G2P(OpCode, sib.base, sib.disp, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } return 0; } @@ -1126,10 +1121,10 @@ static int _x64_inst_array_index(scf_native_t* ctx, scf_3ac_code_t* c, int lea_f if (sib.index) { inst = x64_make_inst_SIB2G(OpCode, rd, sib.base, sib.index, sib.scale, sib.disp); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { inst = x64_make_inst_P2G(OpCode, rd, sib.base, sib.disp); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } return 0; } @@ -1194,7 +1189,7 @@ static int _x64_inst_address_of_handler(scf_native_t* ctx, scf_3ac_code_t* c) lea = x64_find_OpCode(SCF_X64_LEA, 8,8, SCF_X64_E2G); inst = x64_make_inst_M2G(&rela, lea, rd, NULL, src->dag_node->var); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->dag_node->var, NULL); return 0; } @@ -1533,21 +1528,21 @@ static int _x64_inst_dump_handler(scf_native_t* ctx, scf_3ac_code_t* c) X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); inst = x64_make_inst_G2E(mov, rsi, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); scf_rela_t* rela = NULL; inst = x64_make_inst_M2G(&rela, lea, rdi, NULL, msg->dag_node->var); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, msg->dag_node->var, NULL); inst = x64_make_inst_G2E(xor, rax, rax); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); // call printf() to show msg uint32_t imm = 0; inst = x64_make_inst_I(call, (uint8_t*)&imm, sizeof(imm)); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); rela = calloc(1, sizeof(scf_rela_t)); if (!rela) @@ -1556,10 +1551,10 @@ static int _x64_inst_dump_handler(scf_native_t* ctx, scf_3ac_code_t* c) X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, logf->dag_node->var->func_ptr); inst = x64_make_inst_G2E(xor, rax, rax); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_G2P(mov, rax, 0, rax); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } @@ -1602,14 +1597,14 @@ static int _x64_inst_vla_alloc_handler(scf_native_t* ctx, scf_3ac_code_t* c) uint32_t imm = 0xf; inst = x64_make_inst_I2E(add, rs, (uint8_t*)&imm, sizeof(imm)); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); imm = ~0xf; inst = x64_make_inst_I2E(and, rs, (uint8_t*)&imm, sizeof(imm)); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_E2G(sub, rsp, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); int ret = x64_save_var(src->dag_node, c, f); if (ret < 0) @@ -1618,7 +1613,7 @@ static int _x64_inst_vla_alloc_handler(scf_native_t* ctx, scf_3ac_code_t* c) X64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); inst = x64_make_inst_G2E(mov, rd, rsp); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } @@ -1652,10 +1647,10 @@ static int _x64_inst_vla_free_handler(scf_native_t* ctx, scf_3ac_code_t* c) X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); inst = x64_make_inst_E2G(add, rsp, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_G2E(xor, rs, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return x64_save_var(src->dag_node, c, f); } @@ -1756,14 +1751,14 @@ static int _x64_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c) if (rd->bytes > size) { inst = x64_make_inst_E2G(mov, rd, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } } else { X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); if (!X64_COLOR_CONFLICT(rd->color, rs->color) || rd->bytes > size) { inst = x64_make_inst_E2G(mov, rd, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } } } else if (0 == src->dag_node->color) { @@ -1774,10 +1769,10 @@ static int _x64_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c) mov = x64_find_OpCode(SCF_X64_MOV, rd->bytes, rd->bytes, SCF_X64_I2G); inst = x64_make_inst_I2G(mov, rd, (uint8_t*)&v->data, rd->bytes); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { inst = x64_make_inst_M2G(&rela, mov, rd, NULL, v); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL); } } @@ -1829,7 +1824,7 @@ static int _x64_inst_memset_handler(scf_native_t* ctx, scf_3ac_code_t* c) if (0 == dn->color) { \ mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_I2G); \ inst = x64_make_inst_I2G(mov, r, (uint8_t*)&dn->var->data, size); \ - X64_INST_ADD_CHECK(c->instructions, inst); \ + X64_INST_ADD_CHECK(c->instructions, inst, NULL); \ \ } else { \ if (dn->color < 0) \ @@ -1839,7 +1834,7 @@ static int _x64_inst_memset_handler(scf_native_t* ctx, scf_3ac_code_t* c) if (!X64_COLOR_CONFLICT(rd->color, r->color)) { \ mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_G2E); \ inst = x64_make_inst_G2E(mov, r, rd); \ - X64_INST_ADD_CHECK(c->instructions, inst); \ + X64_INST_ADD_CHECK(c->instructions, inst, NULL); \ } \ } \ } while (0) @@ -1850,7 +1845,7 @@ static int _x64_inst_memset_handler(scf_native_t* ctx, scf_3ac_code_t* c) stos = x64_find_OpCode(SCF_X64_STOS, 1, 8, SCF_X64_G); inst = x64_make_inst(stos, 1); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } @@ -2094,13 +2089,13 @@ static int _x64_inst_push_rets_handler(scf_native_t* ctx, scf_3ac_code_t* c) r = x64_find_register_type_id_bytes(0, x64_abi_ret_regs[i], 8); inst = x64_make_inst_G(push, r); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } if (n & 0x1) { r = x64_find_register_type_id_bytes(0, x64_abi_ret_regs[n - 1], 8); inst = x64_make_inst_G(push, r); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } return 0; } @@ -2132,14 +2127,14 @@ static int _x64_inst_pop_rets_handler(scf_native_t* ctx, scf_3ac_code_t* c) if (n & 0x1) { r = x64_find_register_type_id_bytes(0, x64_abi_ret_regs[n - 1], 8); inst = x64_make_inst_G(pop, r); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } for (i = n - 1; i >= 0; i--) { r = x64_find_register_type_id_bytes(0, x64_abi_ret_regs[i], 8); inst = x64_make_inst_G(pop, r); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } return 0; @@ -2194,33 +2189,32 @@ static int _x64_inst_va_start_handler(scf_native_t* ctx, scf_3ac_code_t* c) X64_SELECT_REG_CHECK(&rptr, ptr->dag_node, c, f, 0); inst = x64_make_inst_P2G(lea, rptr, rbp, offset_int); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_G2P(mov, rap, 0, rptr); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_P2G(lea, rptr, rbp, offset_float); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_G2P(mov, rap, 8, rptr); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_P2G(lea, rptr, rbp, offset_others); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_G2P(mov, rap, 16, rptr); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); mov = x64_find_OpCode(SCF_X64_MOV, 4, 8, SCF_X64_I2E); - inst = x64_make_inst_I2P(mov, rap, 24, (uint8_t*)&f->args_int, 4); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_I2P(mov, rap, 32, (uint8_t*)&f->args_float, 4); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } @@ -2259,22 +2253,22 @@ static int _x64_inst_va_end_handler(scf_native_t* ctx, scf_3ac_code_t* c) X64_SELECT_REG_CHECK(&rptr, ptr->dag_node, c, f, 0); inst = x64_make_inst_G2E(xor, rptr, rptr); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_G2P(mov, rap, 0, rptr); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_G2P(mov, rap, 8, rptr); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_G2P(mov, rap, 16, rptr); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_G2P(mov, rap, 24, rptr); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_G2P(mov, rap, 32, rptr); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); ptr->dag_node->var->tmp_flag = 0; ptr->dag_node->color = 0; @@ -2342,22 +2336,22 @@ static int _x64_inst_va_arg_handler(scf_native_t* ctx, scf_3ac_code_t* c) } inst = x64_make_inst_I2P(cmp, rap, idx_offset, (uint8_t*)&nints, 4); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst_jge = x64_make_inst_I(jge, (uint8_t*)&offset, sizeof(offset)); - X64_INST_ADD_CHECK(c->instructions, inst_jge); + X64_INST_ADD_CHECK(c->instructions, inst_jge, NULL); inst = x64_make_inst_P2G(mov, rptr, rap, ptr_offset); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); offset += inst->len; inst = x64_make_inst_I2P(sub, rap, ptr_offset, (uint8_t*)&incptr, 4); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); offset += inst->len; inst_jmp = x64_make_inst_I(jmp, (uint8_t*)&offset, sizeof(offset)); - X64_INST_ADD_CHECK(c->instructions, inst_jmp); + X64_INST_ADD_CHECK(c->instructions, inst_jmp, NULL); offset += inst_jmp->len; uint8_t* p = (uint8_t*)&offset; @@ -2367,18 +2361,18 @@ static int _x64_inst_va_arg_handler(scf_native_t* ctx, scf_3ac_code_t* c) offset = 0; inst = x64_make_inst_P2G(mov, rptr, rap, 16); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); offset += inst->len; inst = x64_make_inst_I2P(add, rap, 16, (uint8_t*)&incptr, 4); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); offset += inst->len; for (i = 0; i < 4; i++) inst_jmp->code[jmp->nb_OpCodes + i] = p[i]; inst = x64_make_inst_P(inc, rap, idx_offset, 8); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); if (is_float) { if (4 == size) @@ -2391,8 +2385,7 @@ static int _x64_inst_va_arg_handler(scf_native_t* ctx, scf_3ac_code_t* c) mov2 = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_E2G); inst = x64_make_inst_P2G(mov2, rd, rptr, 0); - X64_INST_ADD_CHECK(c->instructions, inst); - + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } diff --git a/native/x64/scf_x64_inst_binary.c b/native/x64/scf_x64_inst_binary.c index c2c5f5b..a292950 100644 --- a/native/x64/scf_x64_inst_binary.c +++ b/native/x64/scf_x64_inst_binary.c @@ -36,16 +36,17 @@ static int _binary_assign_sib_float(scf_register_t* rb, scf_register_t* ri, int3 return ret; } - mov = x64_find_OpCode(mov_type, v->size, v->size, SCF_X64_E2G); + mov = x64_find_OpCode(mov_type, v->size, v->size, SCF_X64_E2G); if (ri) inst = x64_make_inst_SIB2G(mov, rs, rb, ri, scale, disp); else inst = x64_make_inst_P2G(mov, rs, rb, disp); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); OpCode = x64_find_OpCode(OpCode_type, v->size, v->size, SCF_X64_E2G); inst = x64_make_inst_M2G(&rela, OpCode, rs, NULL, src->var); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); + X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL); end: mov = x64_find_OpCode(mov_type, v->size, v->size, SCF_X64_G2E); @@ -53,19 +54,18 @@ end: inst = x64_make_inst_G2SIB(mov, rb, ri, scale, disp, rs); else inst = x64_make_inst_G2P(mov, rb, disp, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } static int _binary_assign_sib_int(x64_sib_t* sib, scf_dag_node_t* src, scf_3ac_code_t* c, scf_function_t* f, int OpCode_type) { - scf_variable_t* v = src->var; - scf_register_t* rs = NULL; - - scf_register_t* rb = sib->base; - scf_register_t* ri = sib->index; - int32_t scale = sib->scale; - int32_t disp = sib->disp; + scf_variable_t* v = src->var; + scf_register_t* rs = NULL; + scf_register_t* rb = sib->base; + scf_register_t* ri = sib->index; + int32_t scale = sib->scale; + int32_t disp = sib->disp; scf_x64_OpCode_t* OpCode; scf_instruction_t* inst; @@ -82,7 +82,7 @@ static int _binary_assign_sib_int(x64_sib_t* sib, scf_dag_node_t* src, scf_3ac_c inst = x64_make_inst_I2SIB(OpCode, rb, ri, scale, disp, (uint8_t*)&v->data, dsize); else inst = x64_make_inst_I2P(OpCode, rb, disp, (uint8_t*)&v->data, dsize); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } @@ -108,7 +108,7 @@ static int _binary_assign_sib_int(x64_sib_t* sib, scf_dag_node_t* src, scf_3ac_c inst = x64_make_inst_G2SIB(OpCode, rb, ri, scale, disp, rs); else inst = x64_make_inst_G2P(OpCode, rb, disp, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } @@ -122,7 +122,6 @@ static int _binary_SIB2G(scf_native_t* ctx, scf_3ac_code_t* c, int OpCode_type, scf_x64_context_t* x64 = ctx->priv; scf_function_t* f = x64->f; - scf_3ac_operand_t* dst = c->dsts->data[0]; scf_3ac_operand_t* base = c->srcs->data[0]; scf_3ac_operand_t* index = c->srcs->data[c->srcs->size - 1]; @@ -142,7 +141,6 @@ static int _binary_SIB2G(scf_native_t* ctx, scf_3ac_code_t* c, int OpCode_type, scf_variable_t* vd = dst ->dag_node->var; scf_variable_t* vb = base ->dag_node->var; scf_variable_t* vi = index->dag_node->var; - scf_register_t* rd = NULL; x64_sib_t sib = {0}; @@ -165,18 +163,18 @@ static int _binary_SIB2G(scf_native_t* ctx, scf_3ac_code_t* c, int OpCode_type, int is_float = scf_variable_float(vd); if (is_float) { if (SCF_VAR_FLOAT == vd->type) - mov = x64_find_OpCode(SCF_X64_MOVSS, rd->bytes, rd->bytes, SCF_X64_E2G); + mov = x64_find_OpCode(SCF_X64_MOVSS, rd->bytes, rd->bytes, SCF_X64_E2G); else if (SCF_VAR_DOUBLE == vd->type) - mov = x64_find_OpCode(SCF_X64_MOVSD, rd->bytes, rd->bytes, SCF_X64_E2G); + mov = x64_find_OpCode(SCF_X64_MOVSD, rd->bytes, rd->bytes, SCF_X64_E2G); } else - mov = x64_find_OpCode(SCF_X64_MOV, rd->bytes, rd->bytes, SCF_X64_E2G); + mov = x64_find_OpCode(SCF_X64_MOV, rd->bytes, rd->bytes, SCF_X64_E2G); if (sib.index) { inst = x64_make_inst_SIB2G(mov, rd, sib.base, sib.index, sib.scale, sib.disp); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { inst = x64_make_inst_P2G(mov, rd, sib.base, sib.disp); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } return 0; } @@ -233,18 +231,18 @@ int x64_assign_dereference(scf_native_t* ctx, scf_3ac_code_t* c) if (!src || !src->dag_node) return -EINVAL; - scf_variable_t* b = base->dag_node->var; - assert(b->nb_pointers > 0 || b->nb_dimentions > 0 || b->type >= SCF_STRUCT); - if (!c->instructions) { c->instructions = scf_vector_alloc(); if (!c->instructions) return -ENOMEM; } + scf_variable_t* b = base->dag_node->var; scf_variable_t* v = src->dag_node->var; x64_sib_t sib = {0}; + assert(b->nb_pointers > 0 || b->nb_dimentions > 0 || b->type >= SCF_STRUCT); + int ret = x64_dereference_reg(&sib, base->dag_node, NULL, c, f); if (ret < 0) return ret; @@ -334,19 +332,19 @@ int x64_assign_pointer(scf_native_t* ctx, scf_3ac_code_t* c) r = x64_find_register_color_bytes(rs->color, 8); inst = x64_make_inst_G(push, r); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_I2G(mov, rs, (uint8_t*)&mask, dsize); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); if (sib.index) inst = x64_make_inst_G2SIB(and, sib.base, sib.index, sib.scale, sib.disp, rs); else inst = x64_make_inst_G2P(and, sib.base, sib.disp, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_G(pop, r); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); int imm = (rs->bytes << 3) - vm->bit_size; assert(imm > 0); @@ -355,14 +353,14 @@ int x64_assign_pointer(scf_native_t* ctx, scf_3ac_code_t* c) shr = x64_find_OpCode(SCF_X64_SHR, 1, rs->bytes, SCF_X64_I2E); inst = x64_make_inst_I2E(shl, rs, (uint8_t*)&imm, 1); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); imm -= vm->bit_offset; assert(imm >= 0); if (imm > 0) { inst = x64_make_inst_I2E(shr, rs, (uint8_t*)&imm, 1); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } mov = x64_find_OpCode(SCF_X64_OR, dsize, dsize, SCF_X64_G2E); @@ -377,7 +375,7 @@ int x64_assign_pointer(scf_native_t* ctx, scf_3ac_code_t* c) inst = x64_make_inst_G2SIB(mov, sib.base, sib.index, sib.scale, sib.disp, rs); else inst = x64_make_inst_G2P(mov, sib.base, sib.disp, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } @@ -396,7 +394,6 @@ int x64_inst_pointer(scf_native_t* ctx, scf_3ac_code_t* c, int lea_flag) scf_x64_context_t* x64 = ctx->priv; scf_function_t* f = x64->f; - scf_3ac_operand_t* dst = c->dsts->data[0]; scf_3ac_operand_t* base = c->srcs->data[0]; scf_3ac_operand_t* member = c->srcs->data[1]; @@ -416,7 +413,6 @@ int x64_inst_pointer(scf_native_t* ctx, scf_3ac_code_t* c, int lea_flag) scf_variable_t* vd = dst->dag_node->var; scf_variable_t* vb = base ->dag_node->var; scf_variable_t* vm = member->dag_node->var; - scf_register_t* rd = NULL; x64_sib_t sib = {0}; @@ -456,10 +452,10 @@ int x64_inst_pointer(scf_native_t* ctx, scf_3ac_code_t* c, int lea_flag) if (sib.index) { inst = x64_make_inst_SIB2G(mov, rd, sib.base, sib.index, sib.scale, sib.disp); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { inst = x64_make_inst_P2G(mov, rd, sib.base, sib.disp); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } if (vm->bit_size > 0) { @@ -471,12 +467,12 @@ int x64_inst_pointer(scf_native_t* ctx, scf_3ac_code_t* c, int lea_flag) if (imm > 0) { inst = x64_make_inst_I2E(shl, rd, (uint8_t*)&imm, 1); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } imm += vm->bit_offset; inst = x64_make_inst_I2E(shr, rd, (uint8_t*)&imm, 1); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } return 0; diff --git a/native/x64/scf_x64_inst_cmp.c b/native/x64/scf_x64_inst_cmp.c index 84c40f9..55d8711 100644 --- a/native/x64/scf_x64_inst_cmp.c +++ b/native/x64/scf_x64_inst_cmp.c @@ -13,8 +13,8 @@ static int _inst_cmp(scf_dag_node_t* src0, scf_dag_node_t* src1, scf_3ac_code_t* scf_x64_OpCode_t* cmp; scf_instruction_t* inst; - scf_register_t* rs1; - scf_register_t* rs0 = NULL; + scf_register_t* rs1; + scf_register_t* rs0 = NULL; scf_rela_t* rela = NULL; X64_SELECT_REG_CHECK(&rs0, src0, c, f, 1); @@ -35,7 +35,7 @@ static int _inst_cmp(scf_dag_node_t* src0, scf_dag_node_t* src1, scf_3ac_code_t* X64_SELECT_REG_CHECK(&rs1, src1, c, f, 1); inst = x64_make_inst_E2G(cmp, rs0, rs1); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } } else { @@ -44,7 +44,7 @@ static int _inst_cmp(scf_dag_node_t* src0, scf_dag_node_t* src1, scf_3ac_code_t* if (cmp) { inst = x64_make_inst_I2E(cmp, rs0, (uint8_t*)&src1->var->data, src1_size); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } @@ -54,7 +54,7 @@ static int _inst_cmp(scf_dag_node_t* src0, scf_dag_node_t* src1, scf_3ac_code_t* cmp = x64_find_OpCode(SCF_X64_CMP, rs0->bytes, src1_size, SCF_X64_G2E); inst = x64_make_inst_G2E(cmp, rs0, rs1); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); src1->loaded = 0; src1->color = 0; @@ -68,10 +68,10 @@ static int _inst_cmp(scf_dag_node_t* src0, scf_dag_node_t* src1, scf_3ac_code_t* if (src1->color > 0) { X64_SELECT_REG_CHECK(&rs1, src1, c, f, 1); inst = x64_make_inst_E2G(cmp, rs0, rs1); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { inst = x64_make_inst_M2G(&rela, cmp, rs0, NULL, src1->var); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, src1->var, NULL); } @@ -98,13 +98,13 @@ static int _inst_set(int setcc_type, scf_dag_node_t* dst, scf_3ac_code_t* c, scf mov = x64_find_OpCode(SCF_X64_MOV, rd->bytes, rd->bytes, SCF_X64_I2G); inst = x64_make_inst_I2G(mov, rd, (uint8_t*)&imm, rd->bytes); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); rd = x64_find_register_color_bytes(rd->color, 1); } inst = x64_make_inst_E(setcc, rd); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } @@ -141,7 +141,7 @@ int x64_inst_teq(scf_native_t* ctx, scf_3ac_code_t* c) test = x64_find_OpCode(SCF_X64_TEST, v->size, v->size, SCF_X64_G2E); inst = x64_make_inst_G2E(test, rs, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } diff --git a/native/x64/scf_x64_inst_common.c b/native/x64/scf_x64_inst_common.c index c5df00f..cdd4fbd 100644 --- a/native/x64/scf_x64_inst_common.c +++ b/native/x64/scf_x64_inst_common.c @@ -56,8 +56,8 @@ static int _x64_inst_op2_imm(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_ { scf_x64_OpCode_t* OpCode; scf_instruction_t* inst; - scf_register_t* rd = NULL; - scf_register_t* rs = NULL; + scf_register_t* rd = NULL; + scf_register_t* rs = NULL; scf_rela_t* rela = NULL; assert( scf_variable_const(src->var)); @@ -81,7 +81,6 @@ static int _x64_inst_op2_imm(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_ } if (dst->color > 0) { - if (SCF_X64_MOV == OpCode_type) X64_SELECT_REG_CHECK(&rd, dst, c, f, 0); else @@ -90,14 +89,14 @@ static int _x64_inst_op2_imm(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_ OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_I2G); if (OpCode) { inst = x64_make_inst_I2G(OpCode, rd, (uint8_t*)&src->var->data, src_size); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_I2E); if (OpCode) { inst = x64_make_inst_I2E(OpCode, rd, (uint8_t*)&src->var->data, src_size); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } @@ -112,7 +111,7 @@ static int _x64_inst_op2_imm(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_ X64_SELECT_REG_CHECK(&rs, src, c, f, 1); inst = x64_make_inst_G2E(OpCode, rd, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); src->color = 0; src->loaded = 0; @@ -124,7 +123,7 @@ static int _x64_inst_op2_imm(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_ OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_I2E); if (OpCode) { inst = x64_make_inst_I2M(&rela, OpCode, dst->var, NULL, (uint8_t*)&src->var->data, src_size); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL); return 0; } @@ -140,7 +139,7 @@ static int _x64_inst_op2_imm(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_ X64_SELECT_REG_CHECK(&rs, src, c, f, 1); inst = x64_make_inst_G2M(&rela, OpCode, dst->var, NULL, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL); src->color = 0; @@ -157,7 +156,7 @@ static int _x64_inst_op2_imm_str(int OpCode_type, scf_dag_node_t* dst, scf_dag_n return -EINVAL; } - scf_register_t* rd = NULL; + scf_register_t* rd = NULL; scf_instruction_t* inst = NULL; scf_x64_OpCode_t* lea = x64_find_OpCode(SCF_X64_LEA, 8, 8, SCF_X64_E2G); scf_rela_t* rela = NULL; @@ -175,7 +174,7 @@ static int _x64_inst_op2_imm_str(int OpCode_type, scf_dag_node_t* dst, scf_dag_n src->var->tmp_flag = 0; inst = x64_make_inst_M2G(&rela, lea, rd, NULL, src->var); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL); return 0; } @@ -223,8 +222,7 @@ int x64_inst_op2(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_t* src, scf_ OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_G2E); if (OpCode) { inst = x64_make_inst_G2E(OpCode, rd, rs); - X64_INST_ADD_CHECK(c->instructions, inst); - + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_E2G); if (!OpCode) { @@ -233,7 +231,7 @@ int x64_inst_op2(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_t* src, scf_ } inst = x64_make_inst_E2G(OpCode, rd, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } } else { OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_E2G); @@ -243,7 +241,7 @@ int x64_inst_op2(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_t* src, scf_ } inst = x64_make_inst_M2G(&rela, OpCode, rd, NULL, src->var); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL); } @@ -259,8 +257,8 @@ int x64_inst_movx(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, s scf_x64_OpCode_t* xor; scf_instruction_t* inst; - scf_register_t* rs; - scf_register_t* rd = NULL; + scf_register_t* rs; + scf_register_t* rd = NULL; X64_SELECT_REG_CHECK(&rd, dst, c, f, 0); @@ -274,7 +272,7 @@ int x64_inst_movx(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, s assert(4 == src->var->size); xor = x64_find_OpCode(SCF_X64_XOR, 8, 8, SCF_X64_G2E); inst = x64_make_inst_G2E(xor, rd, rd); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); movx = x64_find_OpCode(SCF_X64_MOV, 4, 4, SCF_X64_E2G); } @@ -282,7 +280,7 @@ int x64_inst_movx(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, s if (src->color > 0) { X64_SELECT_REG_CHECK(&rs, src, c, f, 0); inst = x64_make_inst_E2G(movx, rd, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else if (0 == src->color) { // get the rd's low bits register @@ -290,16 +288,16 @@ int x64_inst_movx(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, s mov = x64_find_OpCode(SCF_X64_MOV, src->var->size, src->var->size, SCF_X64_I2G); inst = x64_make_inst_I2G(mov, rs, (uint8_t*)&src->var->data, src->var->size); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_E2G(movx, rd, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { scf_rela_t* rela = NULL; inst = x64_make_inst_M2G(&rela, movx, rd, NULL, src->var); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL); } @@ -309,7 +307,6 @@ int x64_inst_movx(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, s int x64_inst_float_cast(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, scf_function_t* f) { scf_x64_OpCode_t* OpCode; - scf_instruction_t* inst; scf_register_t* rs = NULL; scf_register_t* rd = NULL; @@ -351,19 +348,19 @@ int x64_inst_float_cast(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t X64_SELECT_REG_CHECK(&rs, src, c, f, 1); - inst = x64_make_inst_E2G(OpCode, rd, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + inst = x64_make_inst_E2G(OpCode, rd, rs); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else if (src->color > 0) { X64_SELECT_REG_CHECK(&rs, src, c, f, 1); inst = x64_make_inst_E2G(OpCode, rd, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { scf_rela_t* rela = NULL; inst = x64_make_inst_M2G(&rela, OpCode, rd, NULL, src->var); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL); } @@ -392,7 +389,6 @@ int x64_inst_jmp(scf_native_t* ctx, scf_3ac_code_t* c, int OpCode_type) scf_instruction_t* inst = x64_make_inst_I(jcc, (uint8_t*)&offset, sizeof(offset)); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } - diff --git a/native/x64/scf_x64_inst_div.c b/native/x64/scf_x64_inst_div.c index 5400f1d..9de5722 100644 --- a/native/x64/scf_x64_inst_div.c +++ b/native/x64/scf_x64_inst_div.c @@ -44,7 +44,7 @@ int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_G2E); inst = x64_make_inst_G2E(mov, rl, rd); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } if (rd->id != rh->id) { @@ -65,7 +65,7 @@ int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_E2G); inst = x64_make_inst_M2G(&rela, mov, rl, NULL, dst->var); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL); } @@ -73,24 +73,23 @@ int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c div = x64_find_OpCode(SCF_X64_IDIV, size, size, SCF_X64_E); cdq = x64_find_OpCode_by_type(SCF_X64_CDQ); inst = x64_make_inst(cdq, size << 1); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { div = x64_find_OpCode(SCF_X64_DIV, size, size, SCF_X64_E); xor = x64_find_OpCode(SCF_X64_XOR, size, size, SCF_X64_G2E); inst = x64_make_inst_G2E(xor, rh, rh); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } if (src->color > 0) { X64_SELECT_REG_CHECK(&rs, src, c, f, 1); inst = x64_make_inst_E(div, rs); - X64_INST_ADD_CHECK(c->instructions, inst); - + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { scf_rela_t* rela = NULL; inst = x64_make_inst_M(&rela, div, src->var, NULL); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL); } @@ -104,14 +103,14 @@ int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c if (rd->id != result->id) { mov = x64_find_OpCode(SCF_X64_MOV, rd->bytes, rd->bytes, SCF_X64_G2E); inst = x64_make_inst_G2E(mov, rd, result); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } } else { scf_rela_t* rela = NULL; mov = x64_find_OpCode(SCF_X64_MOV, dst->var->size, dst->var->size, SCF_X64_G2E); inst = x64_make_inst_G2M(&rela, mov, dst->var, NULL, result); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL); } diff --git a/native/x64/scf_x64_inst_mul.c b/native/x64/scf_x64_inst_mul.c index 72527f5..6e20ce8 100644 --- a/native/x64/scf_x64_inst_mul.c +++ b/native/x64/scf_x64_inst_mul.c @@ -12,15 +12,15 @@ static int _int_mul_src(scf_x64_OpCode_t* mul, scf_register_t* rh, scf_dag_node_ mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_I2G); inst = x64_make_inst_I2G(mov, rh, (uint8_t*)&src->var->data, size); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_E(mul, rh); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { scf_rela_t* rela = NULL; inst = x64_make_inst_M(&rela, mul, src->var, NULL); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL); } @@ -87,23 +87,23 @@ int x64_inst_int_mul(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c if (rd->id == rl->id) { inst = x64_make_inst_E(mul, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else if (rs->id == rl->id) { inst = x64_make_inst_E(mul, rd); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { inst = x64_make_inst_G2E(mov, rl, rd); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_E(mul, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } } else { if (rd->id != rl->id) { inst = x64_make_inst_G2E(mov, rl, rd); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } int ret = _int_mul_src(mul, rh, src, c, f); @@ -116,18 +116,18 @@ int x64_inst_int_mul(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c if (rs->id != rl->id) { inst = x64_make_inst_G2E(mov, rl, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } inst = x64_make_inst_M(&rela, mul, dst->var, NULL); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL); } else { mov2 = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_E2G); inst = x64_make_inst_M2G(&rela, mov2, rl, NULL, dst->var); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL); int ret = _int_mul_src(mul, rh, src, c, f); @@ -139,11 +139,11 @@ int x64_inst_int_mul(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c if (rd) { if (rd->id != rl->id) { inst = x64_make_inst_G2E(mov, rd, rl); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } } else { inst = x64_make_inst_G2M(&rela, mov, dst->var, NULL, rl); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL); } diff --git a/native/x64/scf_x64_inst_shift.c b/native/x64/scf_x64_inst_shift.c index 9c801ae..855ad92 100644 --- a/native/x64/scf_x64_inst_shift.c +++ b/native/x64/scf_x64_inst_shift.c @@ -25,20 +25,20 @@ static int _shift_count(scf_dag_node_t* count, scf_3ac_code_t* c, scf_function_t mov = x64_find_OpCode(SCF_X64_MOV, 1, 1, SCF_X64_G2E); inst = x64_make_inst_G2E(mov, cl, rc); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } } else if (count->color < 0) { - scf_rela_t* rela = NULL; - ret = x64_overflow_reg(cl, c, f); if (ret < 0) { scf_loge("\n"); return ret; } + scf_rela_t* rela = NULL; + mov = x64_find_OpCode(SCF_X64_MOV, 1, 1, SCF_X64_E2G); inst = x64_make_inst_M2G(&rela, mov, cl, NULL, count->var); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, count->var, NULL); } @@ -59,8 +59,7 @@ static int _x64_shift(scf_native_t* ctx, scf_3ac_code_t* c, scf_dag_node_t* dst, return -ENOMEM; } - scf_register_t* rd = NULL; - + scf_register_t* rd = NULL; scf_instruction_t* inst; scf_x64_OpCode_t* mov; scf_x64_OpCode_t* shift; @@ -77,11 +76,11 @@ static int _x64_shift(scf_native_t* ctx, scf_3ac_code_t* c, scf_dag_node_t* dst, if (0 != count->color) { shift = x64_find_OpCode(OpCode_type, 1, dst->var->size, SCF_X64_G2E); inst = x64_make_inst_E(shift, rd); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { shift = x64_find_OpCode(OpCode_type, 1, dst->var->size, SCF_X64_I2E); - inst = x64_make_inst_I2E(shift, rd, (uint8_t*)&count->var->data, 1); - X64_INST_ADD_CHECK(c->instructions, inst); + inst = x64_make_inst_I2E(shift, rd, (uint8_t*)&count->var->data, 1); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } } else { scf_rela_t* rela = NULL; @@ -89,12 +88,12 @@ static int _x64_shift(scf_native_t* ctx, scf_3ac_code_t* c, scf_dag_node_t* dst, if (0 != count->color) { shift = x64_find_OpCode(OpCode_type, 1, dst->var->size, SCF_X64_G2E); inst = x64_make_inst_M(&rela, shift, dst->var, NULL); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL); } else { shift = x64_find_OpCode(OpCode_type, 1, dst->var->size, SCF_X64_I2E); inst = x64_make_inst_I2M(&rela, shift, dst->var, NULL, (uint8_t*)&count->var->data, 1); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL); } } diff --git a/native/x64/scf_x64_inst_unary.c b/native/x64/scf_x64_inst_unary.c index 708505f..8ee5358 100644 --- a/native/x64/scf_x64_inst_unary.c +++ b/native/x64/scf_x64_inst_unary.c @@ -15,7 +15,7 @@ static int _unary_assign_sib(x64_sib_t* sib, int size, scf_3ac_code_t* c, scf_fu inst = x64_make_inst_SIB(OpCode, sib->base, sib->index, sib->scale, sib->disp, size); else inst = x64_make_inst_P(OpCode, sib->base, sib->disp, size); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); return 0; } diff --git a/native/x64/scf_x64_inst_util.c b/native/x64/scf_x64_inst_util.c index 33d8266..1c3f461 100644 --- a/native/x64/scf_x64_inst_util.c +++ b/native/x64/scf_x64_inst_util.c @@ -39,6 +39,7 @@ static scf_instruction_t* _x64_make_OpCode(scf_x64_OpCode_t* OpCode, int bytes, case SCF_X64_POP: case SCF_X64_RET: case SCF_X64_CALL: + case SCF_X64_SYSCALL: case SCF_X64_CVTSS2SD: break; @@ -155,14 +156,23 @@ static int _x64_make_disp(scf_rela_t** prela, scf_instruction_t* inst, uint32_t scf_ModRM_setRM(&ModRM, base); - if (SCF_X64_RM_EBP != base - && SCF_X64_RM_ESP != base - && SCF_X64_RM_R12 != base - && SCF_X64_RM_R13 != base - && 0 == disp) { - scf_ModRM_setMod(&ModRM, SCF_X64_MOD_BASE); - inst->code[inst->len++] = ModRM; - return 0; + if (0 == disp) { + if (SCF_X64_RM_ESP == base || SCF_X64_RM_R12 == base) { + scf_ModRM_setMod(&ModRM, SCF_X64_MOD_BASE); + inst->code[inst->len++] = ModRM; + + uint8_t SIB = 0; + scf_SIB_setBase(&SIB, base); + scf_SIB_setIndex(&SIB, base); + scf_SIB_setScale(&SIB, SCF_X64_SIB_SCALE1); + inst->code[inst->len++] = SIB; + return 0; + + } else if (SCF_X64_RM_EBP != base && SCF_X64_RM_R13 != base) { + scf_ModRM_setMod(&ModRM, SCF_X64_MOD_BASE); + inst->code[inst->len++] = ModRM; + return 0; + } } if (disp <= 127 && disp >= -128) { diff --git a/native/x64/scf_x64_opcode.c b/native/x64/scf_x64_opcode.c index d1aa505..f67b5d2 100644 --- a/native/x64/scf_x64_opcode.c +++ b/native/x64/scf_x64_opcode.c @@ -173,6 +173,11 @@ scf_x64_OpCode_t x64_OpCodes[] = { {SCF_X64_LEA, "lea", 1, {0x8d, 0x0, 0x0},1, 8,8, SCF_X64_E2G, 0,0, 0,{0,0}}, {SCF_X64_LEA, "leaq", 1, {0x8d, 0x0, 0x0},1, 8,8, SCF_X64_E2G, 0,0, 0,{0,0}}, + {SCF_X64_MOV, "movb", 2, {0x88, 0x0, 0x0},1, 1,1, SCF_X64_G2E, 0,0, 0,{0,0}}, + {SCF_X64_MOV, "movw", 2, {0x89, 0x0, 0x0},1, 2,2, SCF_X64_G2E, 0,0, 0,{0,0}}, + {SCF_X64_MOV, "movl", 2, {0x89, 0x0, 0x0},1, 4,4, SCF_X64_G2E, 0,0, 0,{0,0}}, + {SCF_X64_MOV, "movq", 2, {0x89, 0x0, 0x0},1, 8,8, SCF_X64_G2E, 0,0, 0,{0,0}}, + {SCF_X64_MOV, "mov", 2, {0x88, 0x0, 0x0},1, 1,1, SCF_X64_G2E, 0,0, 0,{0,0}}, {SCF_X64_MOV, "mov", 2, {0x89, 0x0, 0x0},1, 2,2, SCF_X64_G2E, 0,0, 0,{0,0}}, {SCF_X64_MOV, "mov", 2, {0x89, 0x0, 0x0},1, 4,4, SCF_X64_G2E, 0,0, 0,{0,0}}, @@ -233,6 +238,11 @@ scf_x64_OpCode_t x64_OpCodes[] = { {SCF_X64_CMP, "cmp", 2, {0x83, 0x0, 0x0},1, 1,4, SCF_X64_I2E, 7,1, 0,{0,0}}, {SCF_X64_CMP, "cmp", 2, {0x83, 0x0, 0x0},1, 1,8, SCF_X64_I2E, 7,1, 0,{0,0}}, + {SCF_X64_TEST, "testb", 2, {0x84, 0x0, 0x0},1, 1,1, SCF_X64_G2E, 0,0, 0,{0,0}}, + {SCF_X64_TEST, "testw", 2, {0x85, 0x0, 0x0},1, 2,2, SCF_X64_G2E, 0,0, 0,{0,0}}, + {SCF_X64_TEST, "testl", 2, {0x85, 0x0, 0x0},1, 4,4, SCF_X64_G2E, 0,0, 0,{0,0}}, + {SCF_X64_TEST, "testq", 2, {0x85, 0x0, 0x0},1, 8,8, SCF_X64_G2E, 0,0, 0,{0,0}}, + {SCF_X64_TEST, "test", 2, {0x84, 0x0, 0x0},1, 1,1, SCF_X64_G2E, 0,0, 0,{0,0}}, {SCF_X64_TEST, "test", 2, {0x85, 0x0, 0x0},1, 2,2, SCF_X64_G2E, 0,0, 0,{0,0}}, {SCF_X64_TEST, "test", 2, {0x85, 0x0, 0x0},1, 4,4, SCF_X64_G2E, 0,0, 0,{0,0}}, @@ -294,11 +304,15 @@ scf_x64_OpCode_t x64_OpCodes[] = { {SCF_X64_CVTTSD2SI, "cvttsd2si", 8, {0xf2, 0x0f, 0x2c},3, 8,4, SCF_X64_E2G, 0,0, 0,{0,0}}, {SCF_X64_CVTTSD2SI, "cvttsd2si", 8, {0xf2, 0x0f, 0x2c},3, 8,8, SCF_X64_E2G, 0,0, 0,{0,0}}, - {SCF_X64_JZ, "jz", 2, {0x74, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}}, + {SCF_X64_JZ, "jz", 2, {0x74, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}}, {SCF_X64_JZ, "jz", 6, {0x0f, 0x84, 0x0},2, 4,4, SCF_X64_I, 0,0, 0,{0,0}}, + {SCF_X64_JZ, "je", 2, {0x74, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}}, + {SCF_X64_JZ, "je", 6, {0x0f, 0x84, 0x0},2, 4,4, SCF_X64_I, 0,0, 0,{0,0}}, - {SCF_X64_JNZ, "jnz", 2, {0x75, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}}, + {SCF_X64_JNZ, "jnz", 2, {0x75, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}}, {SCF_X64_JNZ, "jnz", 6, {0x0f, 0x85, 0x0},2, 4,4, SCF_X64_I, 0,0, 0,{0,0}}, + {SCF_X64_JNZ, "jne", 2, {0x75, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}}, + {SCF_X64_JNZ, "jne", 6, {0x0f, 0x85, 0x0},2, 4,4, SCF_X64_I, 0,0, 0,{0,0}}, {SCF_X64_JG, "jg", 2, {0x7f, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}}, {SCF_X64_JG, "jg", 6, {0x0f, 0x8f,0x0},1, 4,4, SCF_X64_I, 0,0, 0,{0,0}}, @@ -326,7 +340,8 @@ scf_x64_OpCode_t x64_OpCodes[] = { {SCF_X64_JMP, "jmp", 2, {0xeb, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}}, {SCF_X64_JMP, "jmp", 5, {0xe9, 0x0, 0x0},1, 4,4, SCF_X64_I, 0,0, 0,{0,0}}, - {SCF_X64_JMP, "jmp", 2, {0xff, 0x0, 0x0},1, 8,8, SCF_X64_E, 4,1, 0,{0,0}}, + + {SCF_X64_SYSCALL, "syscall", 2, {0xf, 0x5, 0x0},2, 8,8, SCF_X64_G, 0,0, 0,{0,0}}, }; scf_x64_OpCode_t* x64_find_OpCode_by_type(const int type) diff --git a/native/x64/scf_x64_opcode.h b/native/x64/scf_x64_opcode.h index cef6d64..0e45f98 100644 --- a/native/x64/scf_x64_opcode.h +++ b/native/x64/scf_x64_opcode.h @@ -61,7 +61,7 @@ scf_instruction_t* x64_make_inst_I2L(scf_rela_t** prela, scf_x64_OpCode_t* OpCo scf_instruction_t* x64_make_inst_G2L(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_register_t* r_src); scf_instruction_t* x64_make_inst_L2G(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_register_t* r_dst); -#define X64_INST_ADD_CHECK(vec, inst) \ +#define X64_INST_ADD_CHECK(vec, inst, rela) \ do { \ if (!(inst)) { \ scf_loge("\n"); \ @@ -70,7 +70,8 @@ scf_instruction_t* x64_make_inst_L2G(scf_rela_t** prela, scf_x64_OpCode_t* OpCo int ret = scf_vector_add((vec), (inst)); \ if (ret < 0) { \ scf_loge("\n"); \ - free(inst); \ + scf_instruction_free(inst); \ + scf_rela_free(rela); \ return ret; \ } \ } while (0) @@ -87,7 +88,7 @@ scf_instruction_t* x64_make_inst_L2G(scf_rela_t** prela, scf_x64_OpCode_t* OpCo int ret = scf_vector_add((vec), (rela)); \ if (ret < 0) { \ scf_loge("\n"); \ - free(rela); \ + scf_rela_free(rela); \ return ret; \ } \ } \ diff --git a/native/x64/scf_x64_reg.c b/native/x64/scf_x64_reg.c index a83fb6a..efcc9aa 100644 --- a/native/x64/scf_x64_reg.c +++ b/native/x64/scf_x64_reg.c @@ -159,7 +159,7 @@ int x64_caller_save_regs(scf_3ac_code_t* c, const char* regs[], int nb_regs, int inst = x64_make_inst_G2P(movsd, rsp, size + stack_size, r2); else { inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&imm, 4); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_G2P(movsd, rsp, 0, r2); } @@ -169,7 +169,7 @@ int x64_caller_save_regs(scf_3ac_code_t* c, const char* regs[], int nb_regs, int else inst = x64_make_inst_G(push, r2); } - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); saved_regs[n++] = r2; size += 8; @@ -183,7 +183,7 @@ int x64_caller_save_regs(scf_3ac_code_t* c, const char* regs[], int nb_regs, int inst = x64_make_inst_G2P(movsd, rsp, size + stack_size, r2); else { inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&imm, 4); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_G2P(movsd, rsp, 0, r2); } @@ -193,7 +193,7 @@ int x64_caller_save_regs(scf_3ac_code_t* c, const char* regs[], int nb_regs, int else inst = x64_make_inst_G(push, r2); } - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); saved_regs[n++] = r2; size += 8; @@ -254,15 +254,15 @@ int x64_pop_regs(scf_vector_t* instructions, scf_register_t** regs, int nb_regs, if (i == nb_updated) { if (X64_COLOR_TYPE(r2->color)) { inst = x64_make_inst_P2G(movsd, r2, rsp, 0); - X64_INST_ADD_CHECK(instructions, inst); + X64_INST_ADD_CHECK(instructions, inst, NULL); inst = x64_make_inst_I2E(add, rsp, (uint8_t*)&imm, 4); } else inst = x64_make_inst_G(pop, r2); - X64_INST_ADD_CHECK(instructions, inst); + X64_INST_ADD_CHECK(instructions, inst, NULL); } else { inst = x64_make_inst_I2E(add, rsp, (uint8_t*)&imm, 4); - X64_INST_ADD_CHECK(instructions, inst); + X64_INST_ADD_CHECK(instructions, inst, NULL); } } return 0; @@ -408,7 +408,7 @@ int x64_save_var2(scf_dag_node_t* dn, scf_register_t* r, scf_3ac_code_t* c, scf_ } inst = x64_make_inst_G2M(&rela, mov, v, NULL, r); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL); end: @@ -714,7 +714,7 @@ int x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G); inst = x64_make_inst_M2G(&rela, lea, r, NULL, v); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, v->func_ptr); } else { @@ -722,7 +722,7 @@ int x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf xor = x64_find_OpCode(SCF_X64_XOR, size, size, SCF_X64_G2E); inst = x64_make_inst_G2E(xor, r, r); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } } else if (scf_variable_const_string(v)) { @@ -736,7 +736,7 @@ int x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G); inst = x64_make_inst_M2G(&rela, lea, r, NULL, v); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL); } else if (v->nb_dimentions > 0) { @@ -747,13 +747,13 @@ int x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G); inst = x64_make_inst_M2G(&rela, lea, r, NULL, v); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL); } else { mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_I2G); inst = x64_make_inst_I2G(mov, r, (uint8_t*)&v->data, size); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } return 0; @@ -829,7 +829,7 @@ int x64_load_reg(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_f } inst = x64_make_inst_M2G(&rela, mov, r, NULL, dn->var); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, rela); X64_RELA_ADD_CHECK(f->data_relas, rela, c, dn->var, NULL); dn->loaded = 1; @@ -1059,12 +1059,12 @@ int x64_array_index_reg(x64_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* in if (scf_variable_signed(index->var)) { mov = x64_find_OpCode(SCF_X64_MOVSX, ri->bytes, ri2->bytes, SCF_X64_E2G); inst = x64_make_inst_E2G(mov, ri2, ri); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else if (ri->bytes <= 2) { mov = x64_find_OpCode(SCF_X64_MOVZX, ri->bytes, ri2->bytes, SCF_X64_E2G); inst = x64_make_inst_E2G(mov, ri2, ri); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } else { assert(4 == ri->bytes); @@ -1096,7 +1096,7 @@ int x64_array_index_reg(x64_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* in mov = x64_find_OpCode(SCF_X64_MOV, 8, 8, SCF_X64_G2E); inst = x64_make_inst_G2E(mov, rs, ri2); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); shl = x64_find_OpCode(SCF_X64_SHL, 1, 8, SCF_X64_I2E); add = x64_find_OpCode(SCF_X64_ADD, 8, 8, SCF_X64_G2E); @@ -1119,17 +1119,17 @@ int x64_array_index_reg(x64_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* in count -= i; inst = x64_make_inst_I2E(shl, rs, (uint8_t*)&count, 1); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); inst = x64_make_inst_G2E(add, rs, ri2); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); count = i; } if (count > 0) { inst = x64_make_inst_I2E(shl, rs, (uint8_t*)&count, 1); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); } ri = rs; @@ -1205,7 +1205,7 @@ int x64_push_callee_regs(scf_3ac_code_t* c, scf_function_t* f) if (j < N) { inst = x64_make_inst_G(push, r); - X64_INST_ADD_CHECK(f->init_code->instructions, inst); + X64_INST_ADD_CHECK(f->init_code->instructions, inst, NULL); f->init_code_bytes += inst->len; } @@ -1242,7 +1242,7 @@ int x64_pop_callee_regs(scf_3ac_code_t* c, scf_function_t* f) if (j < N) { inst = x64_make_inst_G(pop, r); - X64_INST_ADD_CHECK(c->instructions, inst); + X64_INST_ADD_CHECK(c->instructions, inst, NULL); bb->code_bytes += inst->len; f->callee_saved_size += 8; diff --git a/native/x64/scf_x64_util.h b/native/x64/scf_x64_util.h index da4fc06..caa7775 100644 --- a/native/x64/scf_x64_util.h +++ b/native/x64/scf_x64_util.h @@ -126,6 +126,8 @@ enum scf_x64_OpCode_types { SCF_X64_JMP, + SCF_X64_SYSCALL, + SCF_X64_NB }; diff --git a/parse/scf_parse.c b/parse/scf_parse.c index d4cca22..fc05258 100644 --- a/parse/scf_parse.c +++ b/parse/scf_parse.c @@ -2075,16 +2075,9 @@ int scf_parse_write_elf(scf_parse_t* parse, scf_vector_t* functions, scf_vector_ goto error; } - scf_elf_sym_t* sym; - int i; - - for (i = 0; i < parse->symtab->size; i++) { - sym = parse->symtab->data[i]; - - ret = scf_elf_add_sym(elf, sym, ".symtab"); - if (ret < 0) - goto error; - } + ret = scf_elf_add_syms(elf, parse->symtab, ".symtab"); + if (ret < 0) + goto error; ret = scf_elf_write_rel(elf); error: diff --git a/util/scf_string.h b/util/scf_string.h index 040111f..faf1e2f 100644 --- a/util/scf_string.h +++ b/util/scf_string.h @@ -11,6 +11,7 @@ typedef struct { scf_string_t* scf_string_alloc(); +scf_string_t* scf_string_alloc_len(size_t len); scf_string_t* scf_string_clone(scf_string_t* s);