{SCF_OP_VA_ARG, "va_arg"},
{SCF_OP_VA_END, "va_end"},
- {SCF_OP_VLA_ALLOC, "vla_alloc"},
- {SCF_OP_VLA_FREE, "vla_free"},
-
{SCF_OP_RETURN, "return"},
{SCF_OP_GOTO, "jmp"},
{SCF_OP_3AC_JB, "jb"},
{SCF_OP_3AC_JBE, "jbe"},
- {SCF_OP_3AC_DUMP, "core_dump"},
{SCF_OP_3AC_NOP, "nop"},
{SCF_OP_3AC_END, "end"},
return ret;
}
- } else if (SCF_OP_VLA_ALLOC == c->op->type) {
-
- dst = c->dsts->data[0];
- ret = scf_dag_get_node(dag, dst->node, &dst->dag_node);
- if (ret < 0)
- return ret;
-
- scf_dag_node_t* alloc = scf_dag_node_alloc(c->op->type, NULL, NULL);
- if (!alloc)
- return -ENOMEM;
- scf_list_add_tail(dag, &alloc->list);
-
- ret = scf_dag_node_add_child(alloc, dst->dag_node);
- if (ret < 0)
- return ret;
-
- for (i = 0; i < c->srcs->size; i++) {
- src = c->srcs->data[i];
-
- ret = scf_dag_get_node(dag, src->node, &src->dag_node);
- if (ret < 0)
- return ret;
-
- ret = scf_dag_node_add_child(alloc, src->dag_node);
- if (ret < 0)
- return ret;
- }
} else if (SCF_OP_3AC_CMP == c->op->type
- || SCF_OP_3AC_TEQ == c->op->type
- || SCF_OP_3AC_DUMP == c->op->type) {
+ || SCF_OP_3AC_TEQ == c->op->type) {
scf_dag_node_t* dn_cmp = scf_dag_node_alloc(c->op->type, NULL, NULL);
continue;
}
#endif
- if (SCF_OP_3AC_DUMP == c->op->type) {
- c->basic_block_start = 1;
- continue;
- }
if (SCF_OP_3AC_END == c->op->type) {
c->basic_block_start = 1;
continue;
}
- if (SCF_OP_3AC_DUMP == c->op->type) {
- bb->dump_flag = 1;
- continue;
- }
-
if (SCF_OP_3AC_END == c->op->type) {
bb->end_flag = 1;
continue;
else if (SCF_OP_RETURN == c->op->type)
bb->ret_flag = 1;
- else if (SCF_OP_VLA_ALLOC == c->op->type) {
- bb->vla_flag = 1;
- f ->vla_flag = 1;
-
- } else if (SCF_OP_VA_START == c->op->type
+ else if (SCF_OP_VA_START == c->op->type
|| SCF_OP_VA_ARG == c->op->type
|| SCF_OP_VA_END == c->op->type)
bb->varg_flag = 1;
uint32_t jmp_flag :1;
uint32_t jcc_flag :1;
uint32_t ret_flag :1;
- uint32_t vla_flag :1;
uint32_t end_flag :1;
uint32_t varg_flag :1;
uint32_t dump_flag :1;
uint32_t visit_flag :1;
uint32_t block_flag :1;
uint32_t native_flag :1;
-
- scf_basic_block_t* vla_free;
};
typedef int (*scf_basic_block_bfs_pt)(scf_basic_block_t* bb, void* data, scf_vector_t* queue);
SCF_OP_POINTER, // -> struct member
SCF_OP_DOT, // . dot
- SCF_OP_VLA_ALLOC, // variable length array, VLA
- SCF_OP_VLA_FREE,
-
SCF_OP_VAR_ARGS, // ... variable args
SCF_OP_VA_START,
SCF_OP_VA_ARG,
+ SCF_OP_VA_COPY,
SCF_OP_VA_END,
// 49
SCF_OP_3AC_RELOAD, // reload a var from memory, only for 3ac & native
SCF_OP_3AC_RESAVE, // resave a var to memory, only for 3ac & native
- SCF_OP_3AC_DUMP,
SCF_OP_3AC_NOP,
SCF_OP_3AC_END,
uint32_t vargs_flag:1;
uint32_t void_flag :1;
uint32_t call_flag :1;
- uint32_t vla_flag :1;
+ uint32_t pic_flag :1;
uint32_t compile_flag:1;
uint32_t native_flag :1;
SCF_LEX_WORD_KEY_NEW, // create class object
SCF_LEX_WORD_KEY_CONTAINER, // container_of
SCF_LEX_WORD_KEY_VA_ARG, // va_arg
+ SCF_LEX_WORD_KEY_VA_COPY, // va_copy
SCF_LEX_WORD_KEY_DEFINED, // #defined
SCF_LEX_WORD_Q_MASK, // ?
{"switch", NULL, SCF_OP_SWITCH, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
{"case", NULL, SCF_OP_CASE, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
{"default", NULL, SCF_OP_DEFAULT, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
-
- {"vla_alloc", NULL, SCF_OP_VLA_ALLOC, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
- {"vla_free", NULL, SCF_OP_VLA_FREE, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
};
scf_operator_t* scf_find_base_operator(const char* name, const int nb_operands)
return _scf_3ac_code_N(h, SCF_OP_RETURN, NULL, nodes, nb_nodes);
}
-static int _scf_dag_op_vla_alloc(scf_list_t* h, scf_dag_node_t* parent, scf_dag_node_t** nodes, int nb_nodes)
-{
- assert(4 == nb_nodes);
- return _scf_3ac_code_N(h, SCF_OP_VLA_ALLOC, nodes[0], nodes + 1, 3);
-}
-
static int _scf_dag_op_cmp(scf_list_t* h, scf_dag_node_t* parent, scf_dag_node_t** nodes, int nb_nodes)
{
assert(2 == nb_nodes);
{SCF_OP_LT, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_lt},
{SCF_OP_LE, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_le},
- {SCF_OP_VLA_ALLOC, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_vla_alloc},
{SCF_OP_RETURN, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_return},
{SCF_OP_3AC_CMP, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_cmp},
{SCF_OP_3AC_TEQ, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_teq},
return 0;
}
-static int _scf_op_vla_alloc(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
-{
- assert(4 == nb_nodes);
-
- scf_handler_data_t* d = data;
- scf_variable_t* v;
- scf_type_t* t;
- scf_node_t* parent = nodes[0]->parent;
- scf_node_t* zero;
-
- t = scf_block_find_type_type(ast->current_block, SCF_VAR_INT);
- v = SCF_VAR_ALLOC_BY_TYPE(NULL, t, 1, 0, NULL);
- if (!v)
- return -ENOMEM;
- v->data.u64 = 0;
- v->const_literal_flag = 1;
-
- zero = scf_node_alloc(NULL, v->type, v);
- scf_variable_free(v);
- v = NULL;
- if (!zero)
- return -ENOMEM;
-
- int ret = scf_node_add_child(parent, zero);
- if (ret < 0) {
- scf_node_free(zero);
- return ret;
- }
-
- scf_3ac_operand_t* dst;
- scf_3ac_code_t* cmp;
- scf_3ac_code_t* jgt;
- scf_3ac_code_t* core;
- scf_node_t* srcs[] = {nodes[1], zero};
-
- cmp = scf_3ac_code_NN(SCF_OP_3AC_CMP, NULL, 0, srcs, 2);
- if (!cmp)
- return -ENOMEM;
-
- jgt = scf_3ac_jmp_code(SCF_OP_3AC_JGT, NULL);
- if (!jgt) {
- scf_3ac_code_free(cmp);
- return -ENOMEM;
- }
-
- core = scf_3ac_code_NN(SCF_OP_3AC_DUMP, NULL, 0, nodes + 1, 3);
- if (!core) {
- scf_3ac_code_free(jgt);
- scf_3ac_code_free(cmp);
- return -ENOMEM;
- }
-
- scf_list_add_tail(d->_3ac_list_head, &cmp->list);
- scf_list_add_tail(d->_3ac_list_head, &jgt->list);
- scf_list_add_tail(d->_3ac_list_head, &core->list);
-
- dst = jgt->dsts->data[0];
- dst->code = core;
-
- ret = scf_vector_add(d->branch_ops->_breaks, jgt);
- if (ret < 0)
- return ret;
-
- return _scf_3ac_code_N(d->_3ac_list_head, SCF_OP_VLA_ALLOC, nodes[0], nodes + 1, 3);
-}
-
static int _scf_op_default(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
return 0;
[SCF_OP_SWITCH ] = _scf_op_switch,
[SCF_OP_CASE ] = _scf_op_case,
[SCF_OP_DEFAULT] = _scf_op_default,
-
- [SCF_OP_VLA_ALLOC] = _scf_op_vla_alloc,
};
scf_operator_handler_pt scf_find_3ac_operator_handler(const int type)
extern scf_optimizer_t scf_optimizer_const_teq;
extern scf_optimizer_t scf_optimizer_loop;
-extern scf_optimizer_t scf_optimizer_vla;
extern scf_optimizer_t scf_optimizer_group;
extern scf_optimizer_t scf_optimizer_generate_loads_saves;
&scf_optimizer_dominators,
&scf_optimizer_loop,
- &scf_optimizer_vla,
&scf_optimizer_group,
&scf_optimizer_generate_loads_saves,
}
}
-void scf_variable_add_array_dimention(scf_variable_t* array, int num, scf_expr_t* vla)
+void scf_variable_add_array_dimention(scf_variable_t* array, int num)
{
assert(array);
array->dimentions = p;
array->dimentions[array->nb_dimentions].num = num;
- array->dimentions[array->nb_dimentions].vla = vla;
array->nb_dimentions++;
}
assert(v->nb_dimentions > 0);
- if (v->vla_flag)
- return sizeof(void*);
-
int capacity = 1;
int j;
#include"scf_lex_word.h"
typedef struct {
- scf_expr_t* vla; // variable length array
- int num; // const length array
+ int num; // const length array
} scf_dimention_t;
struct scf_variable_s {
uint32_t global_flag :1;
uint32_t member_flag :1;
- uint32_t vla_flag :1;
uint32_t arg_flag :1;
uint32_t auto_gc_flag:1;
uint32_t anon_flag :1;
int scf_member_add_index(scf_member_t* m, scf_variable_t* member, int index);
scf_variable_t* scf_variable_alloc(scf_lex_word_t* w, scf_type_t* t);
-scf_variable_t* scf_variable_clone(scf_variable_t* var);
-scf_variable_t* scf_variable_ref(scf_variable_t* var);
-void scf_variable_free(scf_variable_t* var);
+scf_variable_t* scf_variable_clone(scf_variable_t* v);
+scf_variable_t* scf_variable_ref (scf_variable_t* v);
+void scf_variable_free (scf_variable_t* v);
-void scf_variable_print(scf_variable_t* var);
+void scf_variable_print(scf_variable_t* v);
-void scf_variable_add_array_dimention(scf_variable_t* array, int num, scf_expr_t* vla);
+void scf_variable_add_array_dimention(scf_variable_t* array, int num);
void scf_variable_set_array_member(scf_variable_t* array, int index, scf_variable_t* member);
void scf_variable_get_array_member(scf_variable_t* array, int index, scf_variable_t* member);
return v->const_literal_flag;
if (v->nb_pointers + v->nb_dimentions > 0)
- return v->const_literal_flag && !v->vla_flag;
+ return v->const_literal_flag;
return v->const_flag && 0 == v->nb_pointers && 0 == v->nb_dimentions;
}
int scf_elf_add_sym(scf_elf_context_t* elf, const scf_elf_sym_t* sym, const char* sh_name)
{
- if (elf && sym && sh_name) {
-
- if (elf->ops && elf->ops->add_sym)
- return elf->ops->add_sym(elf, sym, sh_name);
- }
+ if (elf && elf->ops && elf->ops->add_sym && sym && sh_name)
+ return elf->ops->add_sym(elf, sym, sh_name);
scf_loge("\n");
return -1;
int scf_elf_add_section(scf_elf_context_t* elf, const scf_elf_section_t* section)
{
- if (elf && section) {
-
- if (elf->ops && elf->ops->add_section)
- return elf->ops->add_section(elf, section);
- }
+ if (elf && elf->ops && elf->ops->add_section && section)
+ return elf->ops->add_section(elf, section);
scf_loge("\n");
return -1;
int scf_elf_add_rela_section(scf_elf_context_t* elf, const scf_elf_section_t* section, scf_vector_t* relas)
{
- if (elf && section && relas) {
-
- if (elf->ops && elf->ops->add_rela_section)
- return elf->ops->add_rela_section(elf, section, relas);
- }
+ if (elf && elf->ops && elf->ops->add_rela_section && section && relas)
+ return elf->ops->add_rela_section(elf, section, relas);
scf_loge("\n");
return -1;
}
-int scf_elf_add_dyn_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela)
+int scf_elf_add_plt_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela)
{
- if (elf && rela) {
+ if (elf && elf->ops && elf->ops->add_plt_rela && rela)
+ return elf->ops->add_plt_rela(elf, rela);
- if (elf->ops && elf->ops->add_dyn_rela)
- return elf->ops->add_dyn_rela(elf, rela);
- }
+ scf_loge("\n");
+ return -1;
+}
+
+int scf_elf_add_got_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela)
+{
+ if (elf && elf->ops && elf->ops->add_got_rela && rela)
+ return elf->ops->add_got_rela(elf, rela);
scf_loge("\n");
return -1;
int scf_elf_add_dyn_need(scf_elf_context_t* elf, const char* soname)
{
- if (elf && soname) {
-
- if (elf->ops && elf->ops->add_dyn_need)
- return elf->ops->add_dyn_need(elf, soname);
- }
+ if (elf && elf->ops && elf->ops->add_dyn_need && soname)
+ return elf->ops->add_dyn_need(elf, soname);
scf_loge("\n");
return -1;
int scf_elf_read_section(scf_elf_context_t* elf, scf_elf_section_t** psection, const char* name)
{
- if (elf && psection && name) {
-
- if (elf->ops && elf->ops->read_section)
- return elf->ops->read_section(elf, psection, name);
- }
+ if (elf && elf->ops && elf->ops->read_section && psection && name)
+ return elf->ops->read_section(elf, psection, name);
scf_loge("\n");
return -1;
int scf_elf_read_syms(scf_elf_context_t* elf, scf_vector_t* syms, const char* sh_name)
{
- if (elf && syms && sh_name) {
-
- if (elf->ops && elf->ops->read_syms)
- return elf->ops->read_syms(elf, syms, sh_name);
- }
+ if (elf && elf->ops && elf->ops->read_syms && syms && sh_name)
+ return elf->ops->read_syms(elf, syms, sh_name);
scf_loge("\n");
return -1;
int scf_elf_read_relas(scf_elf_context_t* elf, scf_vector_t* relas, const char* sh_name)
{
- if (elf && relas && sh_name) {
-
- if (elf->ops && elf->ops->read_relas)
- return elf->ops->read_relas(elf, relas, sh_name);
- }
+ if (elf && elf->ops && elf->ops->read_relas && relas && sh_name)
+ return elf->ops->read_relas(elf, relas, sh_name);
scf_loge("\n");
return -1;
uint8_t st_info;
uint8_t dyn_flag:1;
+ uint8_t got_flag:1;
} scf_elf_sym_t;
typedef struct {
int (*add_rela_section)(scf_elf_context_t* elf, const scf_elf_section_t* section, scf_vector_t* relas);
int (*add_dyn_need)(scf_elf_context_t* elf, const char* soname);
- int (*add_dyn_rela)(scf_elf_context_t* elf, const scf_elf_rela_t* rela);
+ int (*add_plt_rela)(scf_elf_context_t* elf, const scf_elf_rela_t* rela);
+ int (*add_got_rela)(scf_elf_context_t* elf, const scf_elf_rela_t* rela);
int (*write_rel )(scf_elf_context_t* elf);
int (*write_dyn )(scf_elf_context_t* elf, const char* sysroot);
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);
+int scf_elf_add_plt_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela);
+int scf_elf_add_got_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela);
int scf_elf_read_section(scf_elf_context_t* elf, scf_elf_section_t** psection, const char* name);
.add_rela_section = elf32_add_rela_section,
.add_dyn_need = elf32_add_dyn_need,
- .add_dyn_rela = elf32_add_dyn_rela,
+ .add_plt_rela = elf32_add_plt_rela,
+ .add_got_rela = elf32_add_got_rela,
.read_syms = elf32_read_syms,
.read_relas = elf32_read_relas,
got_plt++;
}
- for (i = 0; i < arm32->dyn_relas->size; i++) {
- r = arm32->dyn_relas->data[i];
+ for (i = 0; i < arm32->plt_relas->size; i++) {
+ r = arm32->plt_relas->data[i];
int sym_idx = ELF32_R_SYM(r->r_info);
assert(sym_idx > 0);
.add_rela_section = elf_add_rela_section,
.add_dyn_need = elf_add_dyn_need,
- .add_dyn_rela = elf_add_dyn_rela,
+ .add_plt_rela = elf_add_plt_rela,
+ .add_got_rela = elf_add_got_rela,
.read_syms = elf_read_syms,
.read_relas = elf_read_relas,
got_plt++;
}
- for (i = 0; i < arm64->dyn_relas->size; i++) {
- Elf64_Rela* r = arm64->dyn_relas->data[i];
+ for (i = 0; i < arm64->plt_relas->size; i++) {
+ Elf64_Rela* r = arm64->plt_relas->data[i];
int sym_idx = ELF64_R_SYM(r->r_info);
assert(sym_idx > 0);
int ret;
ef->text = scf_string_alloc();
- if (!ef->text) {
- ret = -ENOMEM;
+ if (!ef->text)
goto text_error;
- }
ef->rodata = scf_string_alloc();
- if (!ef->rodata) {
- ret = -ENOMEM;
+ if (!ef->rodata)
goto rodata_error;
- }
ef->data = scf_string_alloc();
- if (!ef->data) {
- ret = -ENOMEM;
+ if (!ef->data)
goto data_error;
- }
ef->debug_abbrev = scf_string_alloc();
- if (!ef->debug_abbrev) {
- ret = -ENOMEM;
+ if (!ef->debug_abbrev)
goto debug_abbrev_error;
- }
ef->debug_info = scf_string_alloc();
- if (!ef->debug_info) {
- ret = -ENOMEM;
+ if (!ef->debug_info)
goto debug_info_error;
- }
ef->debug_line = scf_string_alloc();
- if (!ef->debug_line) {
- ret = -ENOMEM;
+ if (!ef->debug_line)
goto debug_line_error;
- }
ef->debug_str = scf_string_alloc();
- if (!ef->debug_str) {
- ret = -ENOMEM;
+ if (!ef->debug_str)
goto debug_str_error;
- }
ef->syms = scf_vector_alloc();
- if (!ef->syms) {
- ret = -ENOMEM;
+ if (!ef->syms)
goto syms_error;
- }
ef->text_relas = scf_vector_alloc();
- if (!ef->text_relas) {
- ret = -ENOMEM;
+ if (!ef->text_relas)
goto text_relas_error;
- }
ef->data_relas = scf_vector_alloc();
- if (!ef->data_relas) {
- ret = -ENOMEM;
+ if (!ef->data_relas)
goto data_relas_error;
- }
ef->debug_line_relas = scf_vector_alloc();
- if (!ef->debug_line_relas) {
- ret = -ENOMEM;
+ if (!ef->debug_line_relas)
goto debug_line_relas_error;
- }
ef->debug_info_relas = scf_vector_alloc();
- if (!ef->debug_info_relas) {
- ret = -ENOMEM;
+ if (!ef->debug_info_relas)
goto debug_info_relas_error;
- }
- ef->dyn_syms = scf_vector_alloc();
+ ef->dyn_syms = scf_vector_alloc();
+ if (!ef->dyn_syms)
+ goto dyn_syms_error;
+
ef->dyn_needs = scf_vector_alloc();
- ef->rela_plt = scf_vector_alloc();
+ if (!ef->dyn_needs)
+ goto dyn_needs_error;
+
+ ef->rela_plt = scf_vector_alloc();
+ if (!ef->rela_plt)
+ goto rela_plt_error;
+
+ ef->rela_dyn = scf_vector_alloc();
+ if (!ef->rela_dyn)
+ goto rela_dyn_error;
*pfile = ef;
return 0;
-elf_open_error:
+rela_dyn_error:
+ scf_vector_free(ef->rela_plt);
+rela_plt_error:
+ scf_vector_free(ef->dyn_needs);
+dyn_needs_error:
+ scf_vector_free(ef->dyn_syms);
+dyn_syms_error:
scf_vector_free(ef->debug_info_relas);
debug_info_relas_error:
scf_vector_free(ef->debug_line_relas);
text_error:
if (ef->name)
scf_string_free(ef->name);
+
free(ef);
- return ret;
+ return -ENOMEM;
}
int scf_elf_file_open(scf_elf_file_t** pfile, const char* path, const char* mode, const char* arch)
so->name = scf_string_cstr(path);
- so->dyn_syms = scf_vector_alloc();
- if (!so->dyn_syms)
- return -ENOMEM;
-
- so->rela_plt = scf_vector_alloc();
- if (!so->rela_plt)
- return -ENOMEM;
-
ret = scf_elf_read_syms(so->elf, so->dyn_syms, ".dynsym");
if (ret < 0) {
scf_loge("\n");
scf_vector_clear(ef->syms, sym_free);
scf_vector_free (ef->syms);
+ scf_vector_free (ef->dyn_syms);
+ scf_vector_free (ef->dyn_needs);
+ scf_vector_free (ef->rela_plt);
+ scf_vector_free (ef->rela_dyn);
+
free(ef);
return 0;
}
break;
}
- if (j == dlls->size) {
- scf_loge("linker don't find symbel '%s'\n", sym->name);
+ if (j >= dlls->size)
return -1;
- }
if (pso)
*pso = so;
return 0;
}
-static int link_relas(scf_elf_file_t* exec, char* afiles[], int nb_afiles, char* sofiles[], int nb_sofiles, const char* arch)
+static int link_relas(scf_elf_file_t* exec, char* afiles[], int nb_afiles, char* sofiles[], int nb_sofiles, const char* arch, int dyn_flag)
{
scf_elf_rela_t* rela = NULL;
scf_elf_sym_t* sym = NULL;
sym = exec->syms->data[sym_idx - 1];
+ scf_logd("sym: %s, ELF64_R_TYPE: %ld\n", sym->name, ELF64_R_TYPE(rela->r_info));
+
uint32_t offset = 0;
uint32_t size = 0;
continue;
}
+ int got_flag = 0;
+
ret = _find_so_sym(&so, dlls, sym);
- if (ret < 0) {
- scf_loge("\n");
+
+ if (!strcmp(arch, "x64")) {
+
+ switch (ELF64_R_TYPE(rela->r_info))
+ {
+ case R_X86_64_GOTPCREL:
+ got_flag = 1;
+ break;
+
+ default:
+ if (ret < 0 && !dyn_flag) {
+ scf_loge("linker don't find symbol '%s'\n", sym->name);
+ return -1;
+ }
+ break;
+ };
+
+ } else if (ret < 0) {
+ scf_loge("linker don't find symbol '%s'\n", sym->name);
return -1;
}
+
sym->dyn_flag = 1;
int j;
free(sym2);
return -ENOMEM;
}
- sym2->st_info = ELF64_ST_INFO(STB_GLOBAL, STT_FUNC);
+ sym2->st_info = ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE);
sym2->dyn_flag = 1;
+ sym2->got_flag = got_flag;
if (scf_vector_add(exec->dyn_syms, sym2) < 0) {
scf_loge("\n");
}
}
- scf_vector_add_unique(exec->dyn_needs, so);
+ if (so)
+ scf_vector_add_unique(exec->dyn_needs, so);
+
scf_vector_del(exec->text_relas, rela);
- scf_vector_add(exec->rela_plt, rela);
+
+ if (got_flag)
+ scf_vector_add(exec->rela_dyn, rela);
+ else
+ scf_vector_add(exec->rela_plt, rela);
if (64 == bits)
rela->r_info = ELF64_R_INFO(j + 1, ELF64_R_TYPE(rela->r_info));
else
rela->r_info = ELF32_R_INFO(j + 1, ELF32_R_TYPE(rela->r_info));
- scf_logd("j: %d, sym: %s, r_offset: %#lx, r_addend: %ld\n", j,
- sym->name, rela->r_offset, rela->r_addend);
+ scf_logi("j: %d, sym: %s, r_offset: %#lx, r_addend: %ld, got_flag: %d\n", j,
+ sym->name, rela->r_offset, rela->r_addend, got_flag);
}
for (i = 0; i < exec->data_relas->size; i++) {
return ret;
}
- ret = link_relas(exec, (char**)afiles->data, afiles->size, (char**)sofiles->data, sofiles->size, arch);
+ ret = link_relas(exec, (char**)afiles->data, afiles->size, (char**)sofiles->data, sofiles->size, arch, dyn_flag);
if (ret < 0) {
scf_loge("\n");
return ret;
}
}
+ for (i = 0; i < exec->rela_dyn->size; i++) {
+ rela = exec->rela_dyn->data[i];
+
+ if (scf_elf_add_got_rela(exec->elf, rela) < 0) {
+ scf_loge("\n");
+ return -1;
+ }
+ }
+
for (i = 0; i < exec->rela_plt->size; i++) {
rela = exec->rela_plt->data[i];
- if (scf_elf_add_dyn_rela(exec->elf, rela) < 0) {
+ if (scf_elf_add_plt_rela(exec->elf, rela) < 0) {
scf_loge("\n");
return -1;
}
scf_vector_t* dyn_syms;
scf_vector_t* rela_plt;
+ scf_vector_t* rela_dyn;
scf_vector_t* dyn_needs;
} scf_elf_file_t;
.add_rela_section = elf_add_rela_section,
.add_dyn_need = elf_add_dyn_need,
- .add_dyn_rela = elf_add_dyn_rela,
+ .add_plt_rela = elf_add_plt_rela,
+ .add_got_rela = elf_add_got_rela,
.read_syms = elf_read_syms,
.read_relas = elf_read_relas,
got_plt++;
}
- for (i = 0; i < naja->dyn_relas->size; i++) {
- Elf64_Rela* r = naja->dyn_relas->data[i];
+ for (i = 0; i < naja->plt_relas->size; i++) {
+ Elf64_Rela* r = naja->plt_relas->data[i];
int sym_idx = ELF64_R_SYM(r->r_info);
assert(sym_idx > 0);
xsym->sym.st_info = sym->st_info;
xsym->dyn_flag = sym->dyn_flag;
+ xsym->got_flag = sym->got_flag;
int ret = scf_vector_add(vec, xsym);
if (ret < 0) {
return 0;
}
-int elf_add_dyn_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela)
+static int __add_elf_rela(scf_vector_t* vec, const scf_elf_rela_t* rela)
{
- elf_native_t* e = elf->priv;
-
- if (!e || !elf->fp)
- return -1;
-
- if (!e->dyn_relas) {
- e->dyn_relas = scf_vector_alloc();
- if (!e->dyn_relas)
- return -ENOMEM;
- }
-
Elf64_Rela* r = calloc(1, sizeof(Elf64_Rela));
if (!r)
return -ENOMEM;
- if (scf_vector_add(e->dyn_relas, r) < 0) {
+ if (scf_vector_add(vec, r) < 0) {
free(r);
return -ENOMEM;
}
r->r_offset = rela->r_offset;
r->r_addend = rela->r_addend;
r->r_info = rela->r_info;
-
return 0;
}
+int elf_add_got_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela)
+{
+ elf_native_t* e = elf->priv;
+
+ if (!e || !elf->fp)
+ return -1;
+
+ if (!e->got_relas) {
+ e->got_relas = scf_vector_alloc();
+ if (!e->got_relas)
+ return -ENOMEM;
+ }
+
+ return __add_elf_rela(e->got_relas, rela);
+}
+
+int elf_add_plt_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela)
+{
+ elf_native_t* e = elf->priv;
+
+ if (!e || !elf->fp)
+ return -1;
+
+ if (!e->plt_relas) {
+ e->plt_relas = scf_vector_alloc();
+ if (!e->plt_relas)
+ return -ENOMEM;
+ }
+
+ return __add_elf_rela(e->plt_relas, rela);
+}
+
int elf_read_relas(scf_elf_context_t* elf, scf_vector_t* relas, const char* sh_name)
{
elf_native_t* e = elf->priv;
}
}
}
-
Elf64_Sym sym;
int index;
- uint8_t dyn_flag:1;
+ int plt_got_index;
+
+ uint8_t dyn_flag:1;
+ uint8_t got_flag:1;
} elf_sym_t;
typedef struct {
scf_vector_t* dynsyms;
scf_vector_t* dyn_needs;
- scf_vector_t* dyn_relas;
+ scf_vector_t* plt_relas;
+ scf_vector_t* got_relas;
int n_plts;
+ int n_gots;
elf_section_t* gnu_hash;
elf_section_t* interp;
elf_section_t* dynsym;
elf_section_t* dynstr;
+ elf_section_t* rela_dyn;
elf_section_t* rela_plt;
elf_section_t* plt;
elf_section_t* dynamic;
elf_section_t* got_plt;
+ elf_section_t* got;
} elf_native_t;
int elf_read_section (scf_elf_context_t* elf, scf_elf_section_t** psection, const char* name);
int elf_add_dyn_need(scf_elf_context_t* elf, const char* soname);
-int elf_add_dyn_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela);
+int elf_add_plt_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela);
+int elf_add_got_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela);
int elf_read_phdrs (scf_elf_context_t* elf, scf_vector_t* phdrs);
int elf_read_relas (scf_elf_context_t* elf, scf_vector_t* relas, const char* sh_name);
}
#endif
-
return 0;
}
-int elf32_add_dyn_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela)
+static int __add_elf32_rela(scf_vector_t* vec, const scf_elf_rela_t* rela)
{
- elf_native_t* e = elf->priv;
-
- if (!e || !elf->fp)
- return -1;
-
- if (!e->dyn_relas) {
- e->dyn_relas = scf_vector_alloc();
- if (!e->dyn_relas)
- return -ENOMEM;
- }
-
Elf32_Rela* r = calloc(1, sizeof(Elf32_Rela));
if (!r)
return -ENOMEM;
- if (scf_vector_add(e->dyn_relas, r) < 0) {
+ if (scf_vector_add(vec, r) < 0) {
free(r);
return -ENOMEM;
}
return 0;
}
+int elf32_add_got_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela)
+{
+ elf_native_t* e = elf->priv;
+
+ if (!e || !elf->fp)
+ return -1;
+
+ if (!e->got_relas) {
+ e->got_relas = scf_vector_alloc();
+ if (!e->got_relas)
+ return -ENOMEM;
+ }
+
+ return __add_elf32_rela(e->got_relas, rela);
+}
+
+int elf32_add_plt_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela)
+{
+ elf_native_t* e = elf->priv;
+
+ if (!e || !elf->fp)
+ return -1;
+
+ if (!e->plt_relas) {
+ e->plt_relas = scf_vector_alloc();
+ if (!e->plt_relas)
+ return -ENOMEM;
+ }
+
+ return __add_elf32_rela(e->plt_relas, rela);
+}
+
int elf32_read_relas(scf_elf_context_t* elf, scf_vector_t* relas, const char* sh_name)
{
elf_native_t* e = elf->priv;
}
}
}
-
} elf_sym_t;
typedef struct {
- Elf32_Ehdr eh;
+ Elf32_Ehdr eh;
- Elf32_Shdr sh_null;
+ Elf32_Shdr sh_null;
- scf_vector_t* sections;
- scf_vector_t* phdrs;
+ scf_vector_t* sections;
+ scf_vector_t* phdrs;
- Elf32_Shdr sh_symtab;
- scf_vector_t* symbols;
+ Elf32_Shdr sh_symtab;
+ scf_vector_t* symbols;
- Elf32_Shdr sh_strtab;
+ Elf32_Shdr sh_strtab;
- Elf32_Shdr sh_shstrtab;
- scf_string_t* sh_shstrtab_data;
+ Elf32_Shdr sh_shstrtab;
+ scf_string_t* sh_shstrtab_data;
- scf_vector_t* dynsyms;
- scf_vector_t* dyn_needs;
- scf_vector_t* dyn_relas;
+ scf_vector_t* dynsyms;
+ scf_vector_t* dyn_needs;
+ scf_vector_t* plt_relas;
+ scf_vector_t* got_relas;
+ int n_plts;
+ int n_gots;
+
+ elf_section_t* gnu_hash;
elf_section_t* interp;
elf_section_t* dynsym;
elf_section_t* dynstr;
- elf_section_t* gnu_version;
- elf_section_t* gnu_version_r;
+ elf_section_t* rela_dyn;
elf_section_t* rela_plt;
elf_section_t* plt;
elf_section_t* dynamic;
elf_section_t* got_plt;
+ elf_section_t* got;
} elf_native_t;
int elf32_read_section (scf_elf_context_t* elf, scf_elf_section_t** psection, const char* name);
int elf32_add_dyn_need(scf_elf_context_t* elf, const char* soname);
-int elf32_add_dyn_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela);
+int elf32_add_plt_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela);
+int elf32_add_got_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela);
int elf32_read_phdrs (scf_elf_context_t* elf, scf_vector_t* phdrs);
int elf32_read_relas (scf_elf_context_t* elf, scf_vector_t* relas, const char* sh_name);
}
#endif
-
|| ds_index == rs->sh.sh_info)
continue;
- if (!strcmp(rs->name->data, ".rela.plt"))
+ if (!strcmp(rs->name->data, ".rela.plt") || !strcmp(rs->name->data, ".rela.dyn"))
continue;
s = x64->sections->data[rs->sh.sh_info - 1];
- scf_logd("s: %s, rs: %s, rs->sh.sh_info: %u\n", s->name->data, rs->name->data, rs->sh.sh_info);
+ scf_logi("s: %s, rs: %s, rs->sh.sh_info: %u\n", s->name->data, rs->name->data, rs->sh.sh_info);
assert(!strcmp(s->name->data, rs->name->data + 5));
if (SHT_RELA != s->sh.sh_type)
continue;
- if (!strcmp(s->name->data, ".rela.plt"))
+ if (!strcmp(s->name->data, ".rela.plt") || !strcmp(s->name->data, ".rela.dyn"))
continue;
assert(s->data_len % sizeof(Elf64_Rela) == 0);
int nb_phdrs = 3;
if (x64->dynsyms && x64->dynsyms->size > 0) {
- x64->n_plts = x64->dynsyms->size;
+ x64->n_plts = 0;
+ x64->n_gots = 0;
+
+ elf_sym_t* sym;
+ int i;
+
+ for (i = 0; i < x64->dynsyms->size; i++) {
+ sym = x64->dynsyms->data[i];
+
+ if (sym->got_flag)
+ sym->plt_got_index = x64->n_gots++;
+ else
+ sym->plt_got_index = x64->n_plts++;
+ }
+
+ scf_logw("n_plts: %d, n_gots: %d\n", x64->n_plts, x64->n_gots);
__x64_elf_add_dyn(x64, sysroot);
nb_phdrs = 6;
elf_section_t* crela = NULL;
elf_section_t* drela = NULL;
elf_sym_t* sym;
-
int ret;
- int i;
_x64_elf_process_sections(x64, §ion_offset, &cs, &ros, &ds, &crela, &drela);
// write null section header
fwrite(&x64->sh_null, sizeof(x64->sh_null), 1, elf->fp);
- // write user's section header
+ // write user's section headers
section_offset = phdr_offset + sizeof(Elf64_Phdr) * nb_phdrs;
_x64_elf_write_section_headers(elf, nb_sections, section_offset, strtab_offset, shstrtab_offset);
__x64_elf_write_rodata(elf, r_base, ros->offset, ros->data_len);
if (6 == nb_phdrs) {
- __x64_elf_write_data (elf, rw_base, x64->dynamic->offset, x64->dynamic->data_len + x64->got_plt->data_len + ds->data_len);
+ uint64_t ds_len = x64->dynamic->data_len + ds->data_len;
+
+ if (x64->got_plt)
+ ds_len += x64->got_plt->data_len;
+
+ if (x64->got)
+ ds_len += x64->got->data_len;
+
+ __x64_elf_write_data (elf, rw_base, x64->dynamic->offset, ds_len);
__x64_elf_write_dynamic(elf, rw_base, x64->dynamic->offset, x64->dynamic->data_len);
- } else {
+ } else
__x64_elf_write_data(elf, rw_base, ds->offset, ds->data_len);
- }
#endif
elf_write_sections(elf);
return -ENOMEM;
}
- x64->n_plts = x64->dynsyms->size;
+ x64->n_plts = 0;
+ x64->n_gots = 0;
+
+ for (i = 0; i < x64->dynsyms->size; i++) {
+ sym = x64->dynsyms->data[i];
+
+ if (sym->got_flag)
+ sym->plt_got_index = x64->n_gots++;
+ else
+ sym->plt_got_index = x64->n_plts++;
+ }
+
+ scf_logw("n_plts: %d, n_gots: %d\n", x64->n_plts, x64->n_gots);
for (i = 0; i < x64->symbols->size; i++) {
sym = x64->symbols->data[i];
- if (ELF64_ST_INFO(STB_GLOBAL, STT_FUNC) != sym->sym.st_info)
- continue;
+ if (ELF64_ST_INFO(STB_GLOBAL, STT_FUNC) == sym->sym.st_info) {
+ if (!entry)
+ entry = sym;
- if (!entry)
- entry = sym;
+ } else if (ELF64_ST_INFO(STB_GLOBAL, STT_OBJECT) != sym->sym.st_info)
+ continue;
ret = scf_vector_add(x64->dynsyms, sym);
if (ret < 0)
// write null section header
fwrite(&x64->sh_null, sizeof(x64->sh_null), 1, elf->fp);
- // write user's section header
+ // write user's section headers
section_offset = phdr_offset + sizeof(Elf64_Phdr) * nb_phdrs;
_x64_elf_write_section_headers(elf, nb_sections, section_offset, strtab_offset, shstrtab_offset);
__x64_elf_write_text (elf, rx_base, 0, cs->offset + cs->data_len);
__x64_elf_write_rodata(elf, r_base, ros->offset, ros->data_len);
+ uint64_t ds_len = x64->dynamic->data_len + ds->data_len;
+
if (x64->got_plt)
- __x64_elf_write_data(elf, rw_base, x64->dynamic->offset, x64->dynamic->data_len + x64->got_plt->data_len + ds->data_len);
- else
- __x64_elf_write_data(elf, rw_base, x64->dynamic->offset, x64->dynamic->data_len + ds->data_len);
+ ds_len += x64->got_plt->data_len;
+
+ if (x64->got)
+ ds_len += x64->got->data_len;
+
+ __x64_elf_write_data(elf, rw_base, x64->dynamic->offset, ds_len);
__x64_elf_write_dynamic(elf, rw_base, x64->dynamic->offset, x64->dynamic->data_len);
.add_rela_section = elf_add_rela_section,
.add_dyn_need = elf_add_dyn_need,
- .add_dyn_rela = elf_add_dyn_rela,
+ .add_plt_rela = elf_add_plt_rela,
+ .add_got_rela = elf_add_got_rela,
.read_syms = elf_read_syms,
.read_relas = elf_read_relas,
#define HASH_BUCKETS 3
#define HASH_BLOOMS 1
- int n_syms = x64->dynsyms->size - x64->n_plts;
+ int n_syms = x64->dynsyms->size - x64->n_plts - x64->n_gots;
int len = sizeof(uint32_t) * 4 + sizeof(uint64_t) * HASH_BLOOMS
+ sizeof(uint32_t) * HASH_BUCKETS
return 0;
}
+static int _x64_elf_add_got(elf_native_t* x64, elf_section_t** ps)
+{
+ elf_section_t* s;
+
+ s = calloc(1, sizeof(elf_section_t));
+ if (!s)
+ return -ENOMEM;
+
+ s->name = scf_string_cstr(".got");
+ if (!s->name) {
+ free(s);
+ return -ENOMEM;
+ }
+
+ s->data = calloc(x64->n_gots, sizeof(void*));
+ if (!s->data) {
+ scf_string_free(s->name);
+ free(s);
+ return -ENOMEM;
+ }
+ s->data_len = x64->n_gots * sizeof(void*);
+
+ s->index = 1;
+
+ s->sh.sh_type = SHT_PROGBITS;
+ s->sh.sh_flags = SHF_ALLOC | SHF_WRITE;
+ s->sh.sh_addralign = 8;
+
+ int ret = scf_vector_add(x64->sections, s);
+ if (ret < 0) {
+ scf_string_free(s->name);
+ free(s->data);
+ free(s);
+ return -ENOMEM;
+ }
+
+ *ps = s;
+ return 0;
+}
+
+static int _x64_elf_add_rela_dyn(elf_native_t* x64, elf_section_t** ps)
+{
+ elf_section_t* s;
+
+ s = calloc(1, sizeof(elf_section_t));
+ if (!s)
+ return -ENOMEM;
+
+ s->name = scf_string_cstr(".rela.dyn");
+ if (!s->name) {
+ free(s);
+ return -ENOMEM;
+ }
+
+ s->data = calloc(x64->n_gots, sizeof(Elf64_Rela));
+ if (!s->data) {
+ scf_string_free(s->name);
+ free(s);
+ return -ENOMEM;
+ }
+ s->data_len = x64->n_gots * sizeof(Elf64_Rela);
+
+ s->index = 1;
+
+ s->sh.sh_type = SHT_RELA;
+ s->sh.sh_flags = SHF_ALLOC | SHF_INFO_LINK;
+ s->sh.sh_addralign = 8;
+ s->sh.sh_entsize = sizeof(Elf64_Rela);
+
+ int ret = scf_vector_add(x64->sections, s);
+ if (ret < 0) {
+ scf_string_free(s->name);
+ free(s->data);
+ free(s);
+ return -ENOMEM;
+ }
+
+ *ps = s;
+ return 0;
+}
+
static int _x64_elf_add_rela_plt(elf_native_t* x64, elf_section_t** ps)
{
elf_section_t* s;
".dynsym",
".dynstr",
// ".gnu.version_r",
+ ".rela.dyn",
".rela.plt",
".plt",
".dynamic",
".got.plt",
+ ".got",
".data",
};
// _x64_elf_add_gnu_version_r(x64, &x64->gnu_version_r);
+ _x64_elf_add_rela_dyn(x64, &x64->rela_dyn);
_x64_elf_add_rela_plt(x64, &x64->rela_plt);
_x64_elf_add_plt(x64, &x64->plt);
- _x64_elf_add_dynamic(x64, &x64->dynamic, 4);
+ _x64_elf_add_dynamic(x64, &x64->dynamic, 6);
_x64_elf_add_got_plt(x64, &x64->got_plt);
+ _x64_elf_add_got (x64, &x64->got);
scf_string_t* str = scf_string_alloc();
i = x64->dyn_needs->size;
- dyns[i ].d_tag = DT_STRTAB;
- dyns[i + 1].d_tag = DT_SYMTAB;
- dyns[i + 2].d_tag = DT_STRSZ;
- dyns[i + 3].d_tag = DT_SYMENT;
- dyns[i + 4].d_tag = DT_PLTGOT;
- dyns[i + 5].d_tag = DT_PLTRELSZ;
- dyns[i + 6].d_tag = DT_PLTREL;
- dyns[i + 7].d_tag = DT_JMPREL;
-// dyns[i + 8].d_tag = DT_VERNEED;
-// dyns[i + 9].d_tag = DT_VERNEEDNUM;
-// dyns[i +10].d_tag = DT_VERSYM;
- dyns[i +8].d_tag = DT_NULL;
-
- dyns[i].d_un.d_ptr = (uintptr_t)x64->dynstr;
- dyns[i + 1].d_un.d_ptr = (uintptr_t)x64->dynsym;
- dyns[i + 2].d_un.d_val = str->len;
- dyns[i + 3].d_un.d_val = sizeof(Elf64_Sym);
- dyns[i + 4].d_un.d_ptr = (uintptr_t)x64->got_plt;
- dyns[i + 5].d_un.d_ptr = sizeof(Elf64_Rela);
- dyns[i + 6].d_un.d_ptr = DT_RELA;
- dyns[i + 7].d_un.d_ptr = (uintptr_t)x64->rela_plt;
-// dyns[i + 8].d_un.d_ptr = (uintptr_t)x64->gnu_version_r;
-// dyns[i + 9].d_un.d_ptr = 1;
-// dyns[i +10].d_un.d_ptr = (uintptr_t)x64->gnu_version;
- dyns[i +8].d_un.d_ptr = 0;
+ dyns[i ].d_tag = DT_STRTAB;
+ dyns[i + 1].d_tag = DT_SYMTAB;
+ dyns[i + 2].d_tag = DT_STRSZ;
+ dyns[i + 3].d_tag = DT_SYMENT;
+ dyns[i + 4].d_tag = DT_PLTGOT;
+ dyns[i + 5].d_tag = DT_PLTRELSZ;
+ dyns[i + 6].d_tag = DT_PLTREL;
+ dyns[i + 7].d_tag = DT_JMPREL;
+#if 0
+ dyns[i + 8].d_tag = DT_VERNEED;
+ dyns[i + 9].d_tag = DT_VERNEEDNUM;
+ dyns[i + 10].d_tag = DT_VERSYM;
+#endif
+ dyns[i + 8].d_tag = DT_RELA;
+ dyns[i + 9].d_tag = DT_RELASZ;
+ dyns[i + 10].d_tag = DT_RELAENT;
+ dyns[i + 11].d_tag = DT_NULL;
+
+ dyns[i ].d_un.d_ptr = (uintptr_t)x64->dynstr;
+ dyns[i + 1].d_un.d_ptr = (uintptr_t)x64->dynsym;
+ dyns[i + 2].d_un.d_val = str->len;
+ dyns[i + 3].d_un.d_val = sizeof(Elf64_Sym);
+ dyns[i + 4].d_un.d_ptr = (uintptr_t)x64->got_plt;
+ dyns[i + 5].d_un.d_ptr = sizeof(Elf64_Rela);
+ dyns[i + 6].d_un.d_ptr = DT_RELA;
+ dyns[i + 7].d_un.d_ptr = (uintptr_t)x64->rela_plt;
+#if 0
+ dyns[i + 8].d_un.d_ptr = (uintptr_t)x64->gnu_version_r;
+ dyns[i + 9].d_un.d_ptr = 1;
+ dyns[i + 10].d_un.d_ptr = (uintptr_t)x64->gnu_version;
+#endif
+ dyns[i + 8].d_un.d_ptr = (uintptr_t)x64->rela_dyn;
+ dyns[i + 9].d_un.d_ptr = x64->rela_dyn->data_len;
+ dyns[i + 10].d_un.d_ptr = sizeof(Elf64_Rela);
+ dyns[i + 11].d_un.d_ptr = 0;
x64->dynstr->data = str->data;
x64->dynstr->data_len = str->len;
str->data = NULL;
str->len = 0;
str->capacity = 0;
+
scf_string_free(str);
str = NULL;
x64->gnu_version_r->link = x64->dynstr;
x64->gnu_version_r->info = x64->interp;
#endif
+ x64->rela_dyn->link = x64->dynsym;
+ x64->rela_dyn->info = x64->got;
__x64_section_update_index2(x64, sh_names, sizeof(sh_names) / sizeof(sh_names[0]));
".gnu.hash",
".dynsym",
".dynstr",
+ ".rela.dyn",
".rela.plt",
".plt",
".dynamic",
".got.plt",
+ ".got",
".data",
};
if (x64->dyn_needs) {
__x64_section_update_index(x64, sizeof(sh_names_plt) / sizeof(sh_names_plt[0]));
+ _x64_elf_add_rela_dyn(x64, &x64->rela_dyn);
_x64_elf_add_rela_plt(x64, &x64->rela_plt);
_x64_elf_add_plt (x64, &x64->plt);
- _x64_elf_add_dynamic (x64, &x64->dynamic, 4);
+ _x64_elf_add_dynamic (x64, &x64->dynamic, 6);
_x64_elf_add_got_plt (x64, &x64->got_plt);
+ _x64_elf_add_got (x64, &x64->got);
} else {
__x64_section_update_index(x64, sizeof(sh_names) / sizeof(sh_names[0]));
scf_string_t* str = scf_string_alloc();
char c = '\0';
- int j = x64->n_plts;
+ int j = x64->n_plts + x64->n_gots;
int i;
scf_string_cat_cstr_len(str, &c, 1);
dyns[i + 4].d_un.d_val = sizeof(Elf64_Sym);
if (x64->dyn_needs) {
- dyns[i + 5].d_tag = DT_PLTGOT;
- dyns[i + 6].d_tag = DT_PLTRELSZ;
- dyns[i + 7].d_tag = DT_PLTREL;
- dyns[i + 8].d_tag = DT_JMPREL;
-
- dyns[i + 5].d_un.d_ptr = (uintptr_t)x64->got_plt;
- dyns[i + 6].d_un.d_ptr = x64->rela_plt->data_len;
- dyns[i + 7].d_un.d_ptr = DT_RELA;
- dyns[i + 8].d_un.d_ptr = (uintptr_t)x64->rela_plt;
-
- dyns[i + 9].d_tag = DT_NULL;
- dyns[i + 9].d_un.d_ptr = 0;
+ dyns[i + 5].d_tag = DT_PLTGOT;
+ dyns[i + 6].d_tag = DT_PLTRELSZ;
+ dyns[i + 7].d_tag = DT_PLTREL;
+ dyns[i + 8].d_tag = DT_JMPREL;
+ dyns[i + 5].d_un.d_ptr = (uintptr_t)x64->got_plt;
+ dyns[i + 6].d_un.d_ptr = x64->rela_plt->data_len;
+ dyns[i + 7].d_un.d_ptr = DT_RELA;
+ dyns[i + 8].d_un.d_ptr = (uintptr_t)x64->rela_plt;
+
+ dyns[i + 9].d_tag = DT_RELA;
+ dyns[i + 10].d_tag = DT_RELASZ;
+ dyns[i + 11].d_tag = DT_RELAENT;
+ dyns[i + 9].d_un.d_ptr = (uintptr_t)x64->rela_dyn;
+ dyns[i + 10].d_un.d_ptr = x64->rela_dyn->data_len;
+ dyns[i + 11].d_un.d_ptr = sizeof(Elf64_Rela);
+
+ dyns[i + 12].d_tag = DT_NULL;
+ dyns[i + 12].d_un.d_ptr = 0;
} else {
- dyns[i + 5].d_tag = DT_NULL;
- dyns[i + 5].d_un.d_ptr = 0;
+ dyns[i + 5].d_tag = DT_NULL;
+ dyns[i + 5].d_un.d_ptr = 0;
}
x64->dynstr->data = str->data;
str->data = NULL;
str->len = 0;
str->capacity = 0;
+
scf_string_free(str);
str = NULL;
x64->rela_plt->link = x64->dynsym;
x64->rela_plt->info = x64->got_plt;
+ x64->rela_dyn->link = x64->dynsym;
+ x64->rela_dyn->info = x64->got;
+
__x64_section_update_index2(x64, sh_names_plt, sizeof(sh_names_plt) / sizeof(sh_names_plt[0]));
} else
__x64_section_update_index2(x64, sh_names, sizeof(sh_names) / sizeof(sh_names[0]));
case DT_SYMTAB:
case DT_STRTAB:
case DT_JMPREL:
+ case DT_RELA:
case DT_VERSYM:
dtags[i].d_un.d_ptr = s->offset + rx_base;
s->sh.sh_addr = s->offset + rx_base;
x64->rela_plt->sh.sh_addr = rx_base + x64->rela_plt->offset;
x64->dynamic->sh.sh_addr = rw_base + x64->dynamic->offset;
x64->got_plt->sh.sh_addr = rw_base + x64->got_plt->offset;
- x64->plt->sh.sh_addr = rx_base + x64->plt->offset;
+ x64-> plt->sh.sh_addr = rx_base + x64-> plt->offset;
scf_logd("rw_base: %#lx, offset: %#lx\n", rw_base, x64->got_plt->offset);
scf_logd("got_addr: %#lx\n", x64->got_plt->sh.sh_addr);
Elf64_Rela* rela_plt = (Elf64_Rela*)x64->rela_plt->data;
- Elf64_Sym* dynsym = (Elf64_Sym* )x64->dynsym->data;
- uint64_t* got_plt = (uint64_t* )x64->got_plt->data;
- uint8_t* plt = (uint8_t* )x64->plt->data;
+ uint64_t* got_plt = (uint64_t* )x64-> got_plt->data;
+ uint8_t* plt = (uint8_t* )x64-> plt->data;
uint64_t got_addr = x64->got_plt->sh.sh_addr + 8;
- uint64_t plt_addr = x64->plt->sh.sh_addr;
- int32_t offset = got_addr - plt_addr - 6;
+ uint64_t plt_addr = x64-> plt->sh.sh_addr;
+
+ int32_t offset = got_addr - plt_addr - 6;
got_plt[0] = x64->dynamic->sh.sh_addr;
got_plt[1] = 0;
got_addr += 16;
plt_addr += 16;
+ elf_sym_t* sym;
int i;
+ int j = 0;
+ int n = 0;
+
for (i = 0; i < x64->n_plts; i++) {
+
+ while (j < x64->dynsyms->size) {
+ sym = x64->dynsyms->data[j];
+
+ j++;
+
+ if (!sym->got_flag && i + 1 == ++n)
+ break;
+ }
+ assert(j <= x64->dynsyms->size);
+
rela_plt[i].r_offset = got_addr;
rela_plt[i].r_addend = 0;
- rela_plt[i].r_info = ELF64_R_INFO(i + 1, R_X86_64_JUMP_SLOT);
+ rela_plt[i].r_info = ELF64_R_INFO(j, R_X86_64_JUMP_SLOT);
scf_logd("got_addr: %#lx\n", got_addr);
got_plt++;
}
- for (i = 0; i < x64->dyn_relas->size; i++) {
- Elf64_Rela* r = x64->dyn_relas->data[i];
+ if (!x64->plt_relas)
+ return;
+
+ Elf64_Rela* r;
+
+ for (i = 0; i < x64->plt_relas->size; i++) {
+ r = x64->plt_relas->data[i];
+
+ int sym_idx = ELF64_R_SYM(r->r_info);
+
+ assert(sym_idx > 0);
+ assert(sym_idx - 1 < x64->dynsyms->size);
+
+ sym = x64->dynsyms->data[sym_idx - 1];
+
+ uint64_t plt_addr = x64->plt->sh.sh_addr + (sym->plt_got_index + 1) * 16;
+
+ int32_t offset = plt_addr - (cs_base + r->r_offset) + r->r_addend;
+
+ memcpy(cs->data + r->r_offset, &offset, sizeof(offset));
+ }
+}
+
+static void __x64_got_link(elf_native_t* x64, uint64_t rx_base, uint64_t rw_base, elf_section_t* cs)
+{
+ uint64_t cs_base = rx_base + cs->offset;
+
+ x64->rela_dyn->sh.sh_addr = rx_base + x64->rela_dyn->offset;
+ x64->got ->sh.sh_addr = rw_base + x64->got->offset;
+
+ Elf64_Rela* rela_dyn = (Elf64_Rela*)x64->rela_dyn->data;
+ uint64_t* got = (uint64_t* )x64->got->data;
+
+ uint64_t got_addr = x64->got->sh.sh_addr;
+
+ elf_sym_t* sym;
+ int i;
+ int j = 0;
+ int n = 0;
+
+ for (i = 0; i < x64->n_gots; i++) {
+
+ while (j < x64->dynsyms->size) {
+ sym = x64->dynsyms->data[j];
+
+ j++;
+
+ if (sym->got_flag && i + 1 == ++n)
+ break;
+ }
+ assert(j <= x64->dynsyms->size);
+
+ rela_dyn[i].r_offset = got_addr;
+ rela_dyn[i].r_addend = 0;
+ rela_dyn[i].r_info = ELF64_R_INFO(j, R_X86_64_GLOB_DAT);
+
+ scf_logd("got_addr: %#lx\n", got_addr);
+
+ *got = 0;
+
+ got_addr += 8;
+ got++;
+ }
+
+ if (!x64->got_relas)
+ return;
+
+ Elf64_Rela* r;
+
+ for (i = 0; i < x64->got_relas->size; i++) {
+ r = x64->got_relas->data[i];
int sym_idx = ELF64_R_SYM(r->r_info);
+
assert(sym_idx > 0);
+ assert(sym_idx - 1 < x64->dynsyms->size);
- uint64_t plt_addr = x64->plt->sh.sh_addr + sym_idx * 16;
+ sym = x64->dynsyms->data[sym_idx - 1];
- int32_t offset = plt_addr - (cs_base + r->r_offset) + r->r_addend;
+ uint64_t got_addr = x64->got->sh.sh_addr + sym->plt_got_index * 8;
+
+ int32_t offset = got_addr - (cs_base + r->r_offset) + r->r_addend;
memcpy(cs->data + r->r_offset, &offset, sizeof(offset));
}
if (x64->plt)
__x64_plt_link(x64, rx_base, rw_base, cs);
+ if (x64->got)
+ __x64_got_link(x64, rx_base, rw_base, cs);
+
__x64_dynamic_update(x64, rx_base, rw_base);
__x64_dynsym_update (x64);
}
-#include"stdio.h"
+#include<stdio.h>
int main()
{
--- /dev/null
+int g_i = 2;
+
+int f(int a)
+{
+ return g_i + a;
+}
-struct va_list
-{
- uint8_t* iptr;
- uint8_t* fptr;
- uint8_t* optr;
-
- intptr_t ireg;
- intptr_t freg;
- intptr_t others;
-};
+#include<stdarg.h>
int scf_ulong2a(char* buf, int* pn, int size, uint64_t num)
{
--- /dev/null
+#include<stdio.h>
+
+extern int g_i;
+
+int main()
+{
+ printf("result: %d\n", g_i);
+ return 0;
+}
{SCF_CSTR("__builtin_va_start"), SCF_LEX_WORD_KEY_VA_START},
{SCF_CSTR("__builtin_va_arg"), SCF_LEX_WORD_KEY_VA_ARG},
+ {SCF_CSTR("__builtin_va_copy"), SCF_LEX_WORD_KEY_VA_COPY},
{SCF_CSTR("__builtin_va_end"), SCF_LEX_WORD_KEY_VA_END},
};
}
assert(0 == r->dag_nodes->size);
- r = f->rops->find_register_type_id_bytes(0, r->id, f->rops->MAX_BYTES);
+ r = f->rops->find_register_type_id_bytes(is_float, r->id, f->rops->MAX_BYTES);
assert(0 == r->dag_nodes->size);
scf_logd("### local: %#x, local_vars_size: %#x, callee_saved_size: %#x\n",
local, f->local_vars_size, f->callee_saved_size);
- if (f->bp_used_flag || f->vla_flag || f->call_flag) {
+ if (f->bp_used_flag || f->call_flag) {
- if (f->bp_used_flag || f->vla_flag) {
+ if (f->bp_used_flag) {
inst = x64_make_inst_G2E(mov, rsp, rbp);
X64_INST_ADD_CHECK(end, inst, NULL);
end->inst_bytes += inst->len;
f->init_code_bytes = 0;
- if (f->bp_used_flag || f->vla_flag || f->call_flag) {
+ if (f->bp_used_flag || f->call_flag) {
inst = x64_make_inst_G(push, rbp);
X64_INST_ADD_CHECK(f->init_code, inst, NULL);
f->init_code_bytes += inst->len;
- if (f->bp_used_flag || f->vla_flag) {
+ if (f->bp_used_flag) {
inst = x64_make_inst_G2E(mov, rbp, rsp);
X64_INST_ADD_CHECK(f->init_code, inst, NULL);
f->init_code_bytes += inst->len;
if (l == scf_list_sentinel(&f->dag_list_head))
continue;
- int ret = _x64_rcg_make_node(&gn, g, dn, v->rabi);
+ int ret = x64_rcg_make_node(&gn, g, dn, v->rabi);
if (ret < 0)
return ret;
x64_rcg_handler_pt scf_x64_find_rcg_handler (const int op_type);
x64_inst_handler_pt scf_x64_find_inst_handler(const int op_type);
-int x64_rcg_find_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* dn, scf_register_t* reg);
-int _x64_rcg_make_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* dn, scf_register_t* reg);
+int x64_rcg_make (scf_3ac_code_t* c, scf_graph_t* g, scf_dag_node_t* dn, scf_register_t* reg);
+int x64_rcg_find_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* dn, scf_register_t* reg);
+int x64_rcg_make_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* dn, scf_register_t* reg);
int scf_x64_open (scf_native_t* ctx, const char* arch);
int scf_x64_close (scf_native_t* ctx);
int x64_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_t* f);
int x64_init_bb_colors (scf_basic_block_t* bb);
-scf_instruction_t* x64_make_inst_M (scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v, scf_register_t* r_base);
-scf_instruction_t* x64_make_inst_I2M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v_dst, scf_register_t* r_base, uint8_t* imm, int32_t size);
-scf_instruction_t* x64_make_inst_G2M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v_dst, scf_register_t* r_base, scf_register_t* r_src);
-scf_instruction_t* x64_make_inst_M2G(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_register_t* r_dst, scf_register_t* r_base, scf_variable_t* v_src);
+scf_instruction_t* x64_make_inst_M (scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v, scf_register_t* r_base, scf_3ac_code_t* c, scf_function_t* f);
+scf_instruction_t* x64_make_inst_I2M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v_dst, scf_register_t* r_base, uint8_t* imm, int32_t size, scf_3ac_code_t* c, scf_function_t* f);
+scf_instruction_t* x64_make_inst_G2M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v_dst, scf_register_t* r_base, scf_register_t* r_src, scf_3ac_code_t* c, scf_function_t* f);
+scf_instruction_t* x64_make_inst_M2G(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_register_t* r_dst, scf_register_t* r_base, scf_variable_t* v_src, scf_3ac_code_t* c, scf_function_t* f);
int x64_float_OpCode_type(int OpCode_type, int var_type);
scf_rela_t* rela = NULL;
- inst = x64_make_inst_G2M(&rela, mov, dn->var, NULL, rs);
+ inst = x64_make_inst_G2M(&rela, mov, dn->var, NULL, rs, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dn->var, NULL);
}
inst = x64_make_inst_E(call, r_pf);
X64_INST_ADD_CHECK(c, inst, NULL);
} else {
- inst = x64_make_inst_M(&rela, call, dn->var, NULL);
+ inst = x64_make_inst_M(&rela, call, dn->var, NULL, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dn->var, NULL);
}
} else {
scf_rela_t* rela = NULL;
- inst = x64_make_inst_M(&rela, OpCode, var, NULL);
+ inst = x64_make_inst_M(&rela, OpCode, var, NULL, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, var, NULL);
}
} else {
scf_rela_t* rela = NULL;
- inst = x64_make_inst_M(&rela, OpCode, var, NULL);
+ inst = x64_make_inst_M(&rela, OpCode, var, NULL, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, var, NULL);
}
scf_rela_t* rela = NULL;
- inst = x64_make_inst_M2G(&rela, sub, rd, NULL, v);
+ inst = x64_make_inst_M2G(&rela, sub, rd, NULL, v, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
}
X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
- inst = x64_make_inst_M2G(&rela, OpCode, rs, NULL, v1);
+ inst = x64_make_inst_M2G(&rela, OpCode, rs, NULL, v1, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v1, NULL);
return 0;
} else {
scf_rela_t* rela = NULL;
- inst = x64_make_inst_I2M(&rela, OpCode, v, NULL, (uint8_t*)&v->data_size, imm_size);
+ inst = x64_make_inst_I2M(&rela, OpCode, v, NULL, (uint8_t*)&v->data_size, imm_size, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
}
} else {
scf_rela_t* rela = NULL;
- inst = x64_make_inst_M(&rela, OpCode, v, NULL);
+ inst = x64_make_inst_M(&rela, OpCode, v, NULL, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
}
}
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);
+ inst = x64_make_inst_M2G(&rela, lea, rd, NULL, src->dag_node->var, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->dag_node->var, NULL);
return 0;
return _div_mod_assign(ctx, c, 1);
}
-static int _x64_inst_dump_handler(scf_native_t* ctx, scf_3ac_code_t* c)
-{
- if (!c->srcs || c->srcs->size != 3)
- return -EINVAL;
-
- scf_x64_context_t* x64 = ctx->priv;
- scf_function_t* f = x64->f;
- scf_3ac_operand_t* src = c->srcs->data[0];
- scf_3ac_operand_t* logf = c->srcs->data[1];
- scf_3ac_operand_t* msg = c->srcs->data[2];
-
- if (!logf || !logf->dag_node)
- return -EINVAL;
-
- if (!msg || !msg->dag_node)
- return -EINVAL;
-
- scf_instruction_t* inst = NULL;
- scf_register_t* rs = NULL;
- scf_register_t* rd = NULL;
- scf_register_t* rdi = x64_find_register("rdi");
- scf_register_t* rsi = x64_find_register("rsi");
- scf_register_t* rax = x64_find_register("rax");
-
- scf_x64_OpCode_t* lea = x64_find_OpCode(SCF_X64_LEA, 8, 8, SCF_X64_E2G);
- scf_x64_OpCode_t* call = x64_find_OpCode(SCF_X64_CALL,4, 4, SCF_X64_I);
- scf_x64_OpCode_t* xor = x64_find_OpCode(SCF_X64_XOR, 8, 8, SCF_X64_G2E);
- scf_x64_OpCode_t* mov = x64_find_OpCode(SCF_X64_MOV, 8, 8, SCF_X64_G2E);
-
- if (!c->instructions) {
- c->instructions = scf_vector_alloc();
- if (!c->instructions)
- return -ENOMEM;
- }
-
- X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
-
- inst = x64_make_inst_G2E(mov, rsi, rs);
- X64_INST_ADD_CHECK(c, 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, 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, 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, inst, NULL);
-
- rela = calloc(1, sizeof(scf_rela_t));
- if (!rela)
- return -ENOMEM;
- rela->inst_offset = 1;
- 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, inst, NULL);
-
- inst = x64_make_inst_G2P(mov, rax, 0, rax);
- X64_INST_ADD_CHECK(c, inst, NULL);
- return 0;
-}
-
-static int _x64_inst_vla_alloc_handler(scf_native_t* ctx, scf_3ac_code_t* c)
-{
- if (!c->dsts || c->dsts->size != 1)
- return -EINVAL;
-
- if (!c->srcs || c->srcs->size != 3)
- return -EINVAL;
-
- 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* src = c->srcs->data[0];
-
- if (!dst || !dst->dag_node)
- return -EINVAL;
-
- if (!src || !src->dag_node)
- return -EINVAL;
-
- scf_instruction_t* inst = NULL;
- scf_register_t* rs = NULL;
- scf_register_t* rd = NULL;
- scf_register_t* rsp = x64_find_register("rsp");
-
- scf_x64_OpCode_t* add = x64_find_OpCode(SCF_X64_ADD, 4, 8, SCF_X64_I2E);
- scf_x64_OpCode_t* and = x64_find_OpCode(SCF_X64_AND, 4, 8, SCF_X64_I2E);
- scf_x64_OpCode_t* sub = x64_find_OpCode(SCF_X64_SUB, 8, 8, SCF_X64_E2G);
- scf_x64_OpCode_t* mov = x64_find_OpCode(SCF_X64_MOV, 8, 8, SCF_X64_G2E);
-
- if (!c->instructions) {
- c->instructions = scf_vector_alloc();
- if (!c->instructions)
- return -ENOMEM;
- }
-
- X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
-
- uint32_t imm = 0xf;
- inst = x64_make_inst_I2E(add, rs, (uint8_t*)&imm, sizeof(imm));
- X64_INST_ADD_CHECK(c, inst, NULL);
-
- imm = ~0xf;
- inst = x64_make_inst_I2E(and, rs, (uint8_t*)&imm, sizeof(imm));
- X64_INST_ADD_CHECK(c, inst, NULL);
-
- inst = x64_make_inst_E2G(sub, rsp, rs);
- X64_INST_ADD_CHECK(c, inst, NULL);
-
- int ret = x64_save_var(src->dag_node, c, f);
- if (ret < 0)
- return ret;
-
- X64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0);
-
- inst = x64_make_inst_G2E(mov, rd, rsp);
- X64_INST_ADD_CHECK(c, inst, NULL);
- return 0;
-}
-
-static int _x64_inst_vla_free_handler(scf_native_t* ctx, scf_3ac_code_t* c)
-{
- if (!c->dsts || c->dsts->size != 1)
- return -EINVAL;
-
- if (!c->srcs || c->srcs->size != 3)
- return -EINVAL;
-
- scf_x64_context_t* x64 = ctx->priv;
- scf_function_t* f = x64->f;
- scf_3ac_operand_t* src = c->srcs->data[0];
-
- if (!src || !src->dag_node)
- return -EINVAL;
-
- scf_instruction_t* inst = NULL;
- scf_register_t* rs = NULL;
- scf_register_t* rsp = x64_find_register("rsp");
- scf_x64_OpCode_t* add = x64_find_OpCode(SCF_X64_ADD, 8, 8, SCF_X64_E2G);
- scf_x64_OpCode_t* xor = x64_find_OpCode(SCF_X64_XOR, 8, 8, SCF_X64_G2E);
-
- if (!c->instructions) {
- c->instructions = scf_vector_alloc();
- if (!c->instructions)
- return -ENOMEM;
- }
-
- X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
-
- inst = x64_make_inst_E2G(add, rsp, rs);
- X64_INST_ADD_CHECK(c, inst, NULL);
-
- inst = x64_make_inst_G2E(xor, rs, rs);
- X64_INST_ADD_CHECK(c, inst, NULL);
-
- return x64_save_var(src->dag_node, c, f);
-}
-
static int _x64_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c)
{
if (!c->srcs || c->srcs->size < 1)
inst = x64_make_inst_I2G(mov, rd, (uint8_t*)&v->data, rd->bytes);
X64_INST_ADD_CHECK(c, inst, NULL);
} else {
- inst = x64_make_inst_M2G(&rela, mov, rd, NULL, v);
+ inst = x64_make_inst_M2G(&rela, mov, rd, NULL, v, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
}
[SCF_OP_AND_ASSIGN ] = _x64_inst_and_assign_handler,
[SCF_OP_OR_ASSIGN ] = _x64_inst_or_assign_handler,
- [SCF_OP_VLA_ALLOC ] = _x64_inst_vla_alloc_handler,
- [SCF_OP_VLA_FREE ] = _x64_inst_vla_free_handler,
-
[SCF_OP_RETURN ] = _x64_inst_return_handler,
[SCF_OP_GOTO ] = _x64_inst_goto_handler,
- [SCF_OP_3AC_DUMP ] = _x64_inst_dump_handler,
-
[SCF_OP_3AC_JZ ] = _x64_inst_jz_handler,
[SCF_OP_3AC_JNZ ] = _x64_inst_jnz_handler,
[SCF_OP_3AC_JGT ] = _x64_inst_jgt_handler,
X64_INST_ADD_CHECK(c, 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);
+ inst = x64_make_inst_M2G(&rela, OpCode, rs, NULL, src->var, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL);
inst = x64_make_inst_E2G(cmp, rs0, rs1);
X64_INST_ADD_CHECK(c, inst, NULL);
} else {
- inst = x64_make_inst_M2G(&rela, cmp, rs0, NULL, src1->var);
+ inst = x64_make_inst_M2G(&rela, cmp, rs0, NULL, src1->var, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src1->var, NULL);
}
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);
+ inst = x64_make_inst_I2M(&rela, OpCode, dst->var, NULL, (uint8_t*)&src->var->data, src_size, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
return 0;
src->var->tmp_flag = 1;
X64_SELECT_REG_CHECK(&rs, src, c, f, 1);
- inst = x64_make_inst_G2M(&rela, OpCode, dst->var, NULL, rs);
+ inst = x64_make_inst_G2M(&rela, OpCode, dst->var, NULL, rs, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
return -EINVAL;
}
- inst = x64_make_inst_M2G(&rela, OpCode, rd, NULL, src->var);
+ inst = x64_make_inst_M2G(&rela, OpCode, rd, NULL, src->var, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL);
}
} else {
scf_rela_t* rela = NULL;
- inst = x64_make_inst_M2G(&rela, movx, rd, NULL, src->var);
+ inst = x64_make_inst_M2G(&rela, movx, rd, NULL, src->var, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL);
}
} else {
scf_rela_t* rela = NULL;
- inst = x64_make_inst_M2G(&rela, OpCode, rd, NULL, src->var);
+ inst = x64_make_inst_M2G(&rela, OpCode, rd, NULL, src->var, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL);
}
scf_rela_t* rela = NULL;
mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_E2G);
- inst = x64_make_inst_M2G(&rela, mov, rl, NULL, dst->var);
+ inst = x64_make_inst_M2G(&rela, mov, rl, NULL, dst->var, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
}
} else {
scf_rela_t* rela = NULL;
- inst = x64_make_inst_M(&rela, div, src->var, NULL);
+ inst = x64_make_inst_M(&rela, div, src->var, NULL, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL);
}
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);
+ inst = x64_make_inst_G2M(&rela, mov, dst->var, NULL, result, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
}
return 0;
}
-
} else {
scf_rela_t* rela = NULL;
- inst = x64_make_inst_M(&rela, mul, src->var, NULL);
+ inst = x64_make_inst_M(&rela, mul, src->var, NULL, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL);
}
X64_INST_ADD_CHECK(c, inst, NULL);
}
- inst = x64_make_inst_M(&rela, mul, dst->var, NULL);
+ inst = x64_make_inst_M(&rela, mul, dst->var, NULL, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
- } else {
+ } else {
mov2 = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_E2G);
- inst = x64_make_inst_M2G(&rela, mov2, rl, NULL, dst->var);
+ inst = x64_make_inst_M2G(&rela, mov2, rl, NULL, dst->var, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
X64_INST_ADD_CHECK(c, inst, NULL);
}
} else {
- inst = x64_make_inst_G2M(&rela, mov, dst->var, NULL, rl);
+ inst = x64_make_inst_G2M(&rela, mov, dst->var, NULL, rl, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
}
return 0;
}
-
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);
+ inst = x64_make_inst_M2G(&rela, mov, cl, NULL, count->var, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, count->var, NULL);
}
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);
+ inst = x64_make_inst_M(&rela, shift, dst->var, NULL, c, f);
X64_INST_ADD_CHECK(c, 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);
+ inst = x64_make_inst_I2M(&rela, shift, dst->var, NULL, (uint8_t*)&count->var->data, 1, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
}
return inst;
}
+int x64_make_inst_pic(scf_register_t** r_base, scf_variable_t* v, scf_3ac_code_t* c, scf_function_t* f)
+{
+ assert(!*r_base);
+
+ int ret = x64_select_free_reg(r_base, c, f, 0);
+ if (ret < 0) {
+ scf_loge("PIC: select free reg failed\n");
+ return ret;
+ }
+
+ scf_rela_t* rela = NULL;
+ scf_x64_OpCode_t* mov = x64_find_OpCode(SCF_X64_MOV, 8, 8, SCF_X64_E2G);
+ scf_instruction_t* inst = _x64_make_OpCode(mov, 8, *r_base, NULL, NULL);
+ if (!inst)
+ return -ENOMEM;
+
+ ret = _x64_make_disp(&rela, inst, (*r_base)->id, -1, 0);
+ if (ret < 0) {
+ free(inst);
+ return ret;
+ }
+
+ X64_INST_ADD_CHECK(c, inst, rela);
+
+ if (SCF_FUNCTION_PTR == v->type && v->const_literal_flag) {
+ assert(v->func_ptr);
+
+ X64_RELA_ADD_CHECK(f->text_relas, rela, c, v, v->func_ptr);
+ } else
+ X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
+
+ rela->type = R_X86_64_GOTPCREL;
+
+ inst->dst.base = *r_base;
+ inst->src.base = NULL;
+ inst->src.disp = 0;
+ inst->src.mem_flag = 1;
+ return 0;
+}
+
scf_instruction_t* x64_make_inst_L(scf_rela_t** prela, scf_x64_OpCode_t* OpCode)
{
uint8_t reg = 0;
return inst;
}
-scf_instruction_t* x64_make_inst_M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v, scf_register_t* r_base)
+scf_instruction_t* x64_make_inst_M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v, scf_register_t* r_base, scf_3ac_code_t* c, scf_function_t* f)
{
scf_register_t* rbp = x64_find_register("rbp");
} else if (v->global_flag) {
base = -1;
offset = 0;
+
+ if (v->extern_flag && f->pic_flag) {
+ assert(!r_base);
+
+ int ret = x64_make_inst_pic(&r_base, v, c, f);
+ if (ret < 0)
+ return NULL;
+
+ base = r_base->id;
+ }
} else {
scf_loge("temp var should give a register\n");
return NULL;
return inst;
}
-scf_instruction_t* x64_make_inst_I2M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v_dst, scf_register_t* r_base, uint8_t* imm, int32_t size)
+scf_instruction_t* x64_make_inst_I2M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v_dst, scf_register_t* r_base, uint8_t* imm, int32_t size, scf_3ac_code_t* c, scf_function_t* f)
{
scf_register_t* rbp = x64_find_register("rbp");
} else if (v_dst->global_flag) {
base = -1;
offset = 0;
+
+ if (v_dst->extern_flag && f->pic_flag) {
+ assert(!r_base);
+
+ int ret = x64_make_inst_pic(&r_base, v_dst, c, f);
+ if (ret < 0)
+ return NULL;
+
+ base = r_base->id;
+ }
} else {
scf_loge("temp var should give a register\n");
return NULL;
return inst;
}
-scf_instruction_t* x64_make_inst_G2M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v_dst, scf_register_t* r_base, scf_register_t* r_src)
+scf_instruction_t* x64_make_inst_G2M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v_dst, scf_register_t* r_base, scf_register_t* r_src, scf_3ac_code_t* c, scf_function_t* f)
{
if (OpCode->ModRM_OpCode_used) {
scf_loge("ModRM opcode invalid\n");
} else if (v_dst->global_flag) {
base = -1;
offset = 0;
+
+ if (v_dst->extern_flag && f->pic_flag) {
+ assert(!r_base);
+
+ int ret = x64_make_inst_pic(&r_base, v_dst, c, f);
+ if (ret < 0)
+ return NULL;
+
+ base = r_base->id;
+ }
} else {
scf_loge("temp var should give a register\n");
return NULL;
return inst;
}
-scf_instruction_t* x64_make_inst_M2G(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_register_t* r_dst, scf_register_t* r_base, scf_variable_t* v_src)
+scf_instruction_t* x64_make_inst_M2G(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_register_t* r_dst, scf_register_t* r_base, scf_variable_t* v_src, scf_3ac_code_t* c, scf_function_t* f)
{
if (OpCode->ModRM_OpCode_used) {
scf_loge("ModRM opcode invalid\n");
} else if (v_src->global_flag) {
base = -1;
offset = 0;
+
+ if (v_src->extern_flag && f->pic_flag) {
+ assert(!r_base);
+
+ int ret = x64_make_inst_pic(&r_base, v_src, c, f);
+ if (ret < 0)
+ return NULL;
+
+ base = r_base->id;
+ }
} else {
scf_loge("temp var should give a register\n");
return NULL;
else
goto check;
- ret = __x64_peep_dst_was_mem(inst, id);
+ if (id->base)
+ ret = __x64_peep_dst_was_mem(inst, id);
}
if (ret < 0)
return 0;
}
-int _x64_rcg_make_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* dn, scf_register_t* reg)
+int x64_rcg_make_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* dn, scf_register_t* reg)
{
x64_rcg_node_t* rn;
x64_rcg_node_t tmp;
return 0;
}
-static int _x64_rcg_make_edge(scf_graph_node_t* gn0, scf_graph_node_t* gn1)
+static int x64_rcg_make_edge(scf_graph_node_t* gn0, scf_graph_node_t* gn1)
{
if (gn0 == gn1)
return 0;
if (!ds0->active)
continue;
- ret = _x64_rcg_make_node(&gn0, g, dn0, NULL);
+ ret = x64_rcg_make_node(&gn0, g, dn0, NULL);
if (ret < 0)
return ret;
if (!ds1->active)
continue;
- ret = _x64_rcg_make_node(&gn1, g, dn1, NULL);
+ ret = x64_rcg_make_node(&gn1, g, dn1, NULL);
if (ret < 0)
return ret;
assert(gn0 != gn1);
- ret = _x64_rcg_make_edge(gn0, gn1);
+ ret = x64_rcg_make_edge(gn0, gn1);
if (ret < 0)
return ret;
}
if (scf_variable_const(dn0->var))
continue;
- int ret = _x64_rcg_make_node(&gn0, g, dn0, NULL);
+ int ret = x64_rcg_make_node(&gn0, g, dn0, NULL);
if (ret < 0)
return ret;
if (scf_variable_const(dn1->var))
continue;
- ret = _x64_rcg_make_node(&gn1, g, dn1, NULL);
+ ret = x64_rcg_make_node(&gn1, g, dn1, NULL);
if (ret < 0)
return ret;
if (gn1 == gn0)
continue;
- ret = _x64_rcg_make_edge(gn0, gn1);
+ ret = x64_rcg_make_edge(gn0, gn1);
if (ret < 0)
return ret;
}
if (!ds1->active)
continue;
- ret = _x64_rcg_make_node(&gn1, g, dn1, NULL);
+ ret = x64_rcg_make_node(&gn1, g, dn1, NULL);
if (ret < 0)
return ret;
if (gn0 == gn1)
continue;
- ret = _x64_rcg_make_edge(gn0, gn1);
+ ret = x64_rcg_make_edge(gn0, gn1);
if (ret < 0)
return ret;
}
return 0;
}
-static int _x64_rcg_make(scf_3ac_code_t* c, scf_graph_t* g, scf_dag_node_t* dn,
- scf_register_t* reg, scf_x64_OpCode_t* OpCode)
+int x64_rcg_make(scf_3ac_code_t* c, scf_graph_t* g, scf_dag_node_t* dn, scf_register_t* reg)
{
scf_graph_node_t* gn0 = NULL;
scf_graph_node_t* gn1;
int i;
if (dn || reg) {
- ret = _x64_rcg_make_node(&gn0, g, dn, reg);
+ ret = x64_rcg_make_node(&gn0, g, dn, reg);
if (ret < 0) {
scf_loge("\n");
return ret;
return 0;
}
-static int _x64_rcg_make2(scf_3ac_code_t* c, scf_dag_node_t* dn, scf_register_t* reg, scf_x64_OpCode_t* OpCode)
+static int x64_rcg_make2(scf_3ac_code_t* c, scf_dag_node_t* dn, scf_register_t* reg)
{
if (c->rcg)
scf_graph_free(c->rcg);
if (!c->rcg)
return -ENOMEM;
- return _x64_rcg_make(c, c->rcg, dn, reg, OpCode);
+ return x64_rcg_make(c, c->rcg, dn, reg);
}
static int _x64_rcg_call(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
r = NULL;
gn = NULL;
- ret = _x64_rcg_make_node(&gn, g, dn, r);
+ ret = x64_rcg_make_node(&gn, g, dn, r);
if (ret < 0) {
scf_loge("\n");
return ret;
continue;
gn = NULL;
- ret = _x64_rcg_make_node(&gn, g, dn, dn->rabi2);
+ ret = x64_rcg_make_node(&gn, g, dn, dn->rabi2);
if (ret < 0) {
scf_loge("\n");
return ret;
if (!dn_pf->var->const_literal_flag) {
- ret = _x64_rcg_make_node(&gn_pf, g, dn_pf, NULL);
+ ret = x64_rcg_make_node(&gn_pf, g, dn_pf, NULL);
if (ret < 0) {
scf_loge("\n");
return ret;
rabi = x64_find_register_type_id_bytes(0, x64_abi_regs[i], dn_pf->var->size);
- ret = _x64_rcg_make_node(&gn_rabi, g, NULL, rabi);
+ ret = x64_rcg_make_node(&gn_rabi, g, NULL, rabi);
if (ret < 0) {
scf_loge("\n");
return ret;
assert(gn_pf != gn_rabi);
- ret = _x64_rcg_make_edge(gn_pf, gn_rabi);
+ ret = x64_rcg_make_edge(gn_pf, gn_rabi);
if (ret < 0)
return ret;
}
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL);
+ int ret = x64_rcg_make2(c, NULL, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, NULL, NULL, NULL);
+ return x64_rcg_make(c, g, NULL, NULL);
}
static int _x64_rcg_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_assign_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL);
+ int ret = x64_rcg_make2(c, NULL, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, NULL, NULL, NULL);
+ return x64_rcg_make(c, g, NULL, NULL);
}
static int _x64_rcg_bit_not_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_logic_not_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_neg_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_assign_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL);
+ int ret = x64_rcg_make2(c, NULL, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, NULL, NULL, NULL);
+ return x64_rcg_make(c, g, NULL, NULL);
}
static int _x64_rcg_address_of_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_cast_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_mul_div_mod(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
}
if (scf_variable_float(src->dag_node->var))
- return _x64_rcg_make(c, g, dn, NULL, NULL);
+ return x64_rcg_make(c, g, dn, NULL);
int size = x64_variable_size(src->dag_node->var);
int ret = 0;
case SCF_OP_DIV:
case SCF_OP_MUL_ASSIGN:
case SCF_OP_DIV_ASSIGN:
- ret = _x64_rcg_make(c, g, dst->dag_node, rl, NULL);
+ ret = x64_rcg_make(c, g, dst->dag_node, rl);
break;
case SCF_OP_MOD:
case SCF_OP_MOD_ASSIGN:
- ret = _x64_rcg_make(c, g, dst->dag_node, rh, NULL);
+ ret = x64_rcg_make(c, g, dst->dag_node, rh);
break;
default:
if (ret < 0)
return ret;
- ret = _x64_rcg_make(c, g, NULL, rl, NULL);
+ ret = x64_rcg_make(c, g, NULL, rl);
if (ret < 0)
return ret;
- ret = _x64_rcg_make(c, g, NULL, rh, NULL);
+ ret = x64_rcg_make(c, g, NULL, rh);
if (ret < 0)
return ret;
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_sub_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_shift(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
scf_3ac_operand_t* count = c->srcs->data[c->srcs->size - 1];
scf_graph_node_t* gn = NULL;
scf_graph_node_t* gn_cl = NULL;
- scf_register_t* cl = x64_find_register_type_id_bytes(0, SCF_X64_REG_CL, count->dag_node->var->size);
+ scf_register_t* cl = x64_find_register_type_id_bytes(0, SCF_X64_REG_CL, count->dag_node->var->size);
if (!count || !count->dag_node)
return -EINVAL;
}
if (scf_variable_const(count->dag_node->var))
- return _x64_rcg_make(c, g, dn, NULL, NULL);
+ return x64_rcg_make(c, g, dn, NULL);
- int ret = _x64_rcg_make_node(&gn, g, count->dag_node, cl);
+ int ret = x64_rcg_make_node(&gn, g, count->dag_node, cl);
if (ret < 0)
return ret;
- ret = _x64_rcg_make(c, g, dn, NULL, NULL);
+ ret = x64_rcg_make(c, g, dn, NULL);
if (ret < 0)
return ret;
- ret = _x64_rcg_make_node(&gn_cl, g, NULL, cl);
+ ret = x64_rcg_make_node(&gn_cl, g, NULL, cl);
if (ret < 0)
return ret;
if (dn) {
- ret = _x64_rcg_make_node(&gn, g, dn, NULL);
+ ret = x64_rcg_make_node(&gn, g, dn, NULL);
if (ret < 0)
return ret;
- ret = _x64_rcg_make_edge(gn_cl, gn);
+ ret = x64_rcg_make_edge(gn_cl, gn);
if (ret < 0)
return ret;
}
scf_3ac_operand_t* src = c->srcs->data[i];
scf_graph_node_t* gn_src = NULL;
- ret = _x64_rcg_make_node(&gn_src, g, src->dag_node, NULL);
+ ret = x64_rcg_make_node(&gn_src, g, src->dag_node, NULL);
if (ret < 0)
return ret;
- ret = _x64_rcg_make_edge(gn_cl, gn_src);
+ ret = x64_rcg_make_edge(gn_cl, gn_src);
if (ret < 0)
return ret;
}
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_bit_or_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
-}
-
-static int _x64_rcg_dump_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
-{
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL);
- if (ret < 0)
- return ret;
-
- return _x64_rcg_make(c, g, NULL, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_cmp_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL);
+ int ret = x64_rcg_make2(c, NULL, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, NULL, NULL, NULL);
+ return x64_rcg_make(c, g, NULL, NULL);
}
static int _x64_rcg_teq_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL);
+ int ret = x64_rcg_make2(c, NULL, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, NULL, NULL, NULL);
+ return x64_rcg_make(c, g, NULL, NULL);
}
#define X64_RCG_SET(setcc) \
{ \
scf_3ac_operand_t* dst = c->dsts->data[0]; \
\
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL); \
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL); \
if (ret < 0) \
return ret; \
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL); \
+ return x64_rcg_make(c, g, dst->dag_node, NULL); \
}
X64_RCG_SET(setz)
X64_RCG_SET(setnz)
{ \
scf_3ac_operand_t* dst = c->dsts->data[0]; \
\
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL); \
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL); \
if (ret < 0) \
return ret; \
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL); \
+ return x64_rcg_make(c, g, dst->dag_node, NULL); \
}
X64_RCG_CMP(eq)
X64_RCG_CMP(ne)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_add_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_sub_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_mul_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_or_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
- if (ret < 0)
- return ret;
-
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
-}
-
-static int _x64_rcg_vla_alloc_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
-{
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, NULL, NULL, NULL);
-}
-
-static int _x64_rcg_vla_free_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
-{
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL);
- if (ret < 0)
- return ret;
-
- return _x64_rcg_make(c, g, NULL, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_return_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
scf_graph_node_t* gn;
scf_dag_node_t* dn;
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL);
+ int ret = x64_rcg_make2(c, NULL, NULL);
if (ret < 0)
return ret;
- ret = _x64_rcg_make(c, g, NULL, NULL, NULL);
+ ret = x64_rcg_make(c, g, NULL, NULL);
if (ret < 0)
return ret;
} else
r = x64_find_register_type_id_bytes(is_float, x64_abi_ret_regs[i], size);
- ret = _x64_rcg_make_node(&gn, g, dn, r);
+ ret = x64_rcg_make_node(&gn, g, dn, r);
if (ret < 0)
return ret;
}
scf_dag_node_t* dn;
scf_register_t* r;
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL);
+ int ret = x64_rcg_make2(c, NULL, NULL);
if (ret < 0)
return ret;
- ret = _x64_rcg_make(c, g, NULL, NULL, NULL);
+ ret = x64_rcg_make(c, g, NULL, NULL);
if (ret < 0)
return ret;
else
return -EINVAL;
- ret = _x64_rcg_make_node(&gn, g, dn, r);
+ ret = x64_rcg_make_node(&gn, g, dn, r);
if (ret < 0)
return ret;
}
static int _x64_rcg_save_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL);
+ if (!c->srcs || c->srcs->size != 1)
+ return -EINVAL;
+
+ scf_3ac_operand_t* src = c->srcs->data[0];
+ scf_dag_node_t* dn = src->dag_node;
+
+ int ret = x64_rcg_make2(c, dn, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, NULL, NULL, NULL);
+ return x64_rcg_make(c, g, dn, NULL);
}
static int _x64_rcg_load_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
- return 0;
+ if (!c->dsts || c->dsts->size != 1)
+ return -EINVAL;
+
+ scf_3ac_operand_t* dst = c->dsts->data[0];
+ scf_dag_node_t* dn = dst->dag_node;
+
+ return x64_rcg_make2(c, dn, NULL);
}
+
static int _x64_rcg_nop_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
return 0;
#define X64_RCG_BINARY_ASSIGN(name) \
static int _x64_rcg_##name##_assign_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \
{ \
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL); \
+ int ret = x64_rcg_make2(c, NULL, NULL); \
if (ret < 0) \
return ret; \
- return _x64_rcg_make(c, g, NULL, NULL, NULL); \
+ return x64_rcg_make(c, g, NULL, NULL); \
} \
static int _x64_rcg_##name##_assign_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \
{ \
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL); \
+ int ret = x64_rcg_make2(c, NULL, NULL); \
if (ret < 0) \
return ret; \
- return _x64_rcg_make(c, g, NULL, NULL, NULL); \
+ return x64_rcg_make(c, g, NULL, NULL); \
} \
static int _x64_rcg_##name##_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \
{ \
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL); \
+ int ret = x64_rcg_make2(c, NULL, NULL); \
if (ret < 0) \
return ret; \
- return _x64_rcg_make(c, g, NULL, NULL, NULL); \
+ return x64_rcg_make(c, g, NULL, NULL); \
}
X64_RCG_BINARY_ASSIGN(add)
#define X64_RCG_UNARY_ASSIGN(name) \
static int _x64_rcg_##name##_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \
{ \
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL); \
+ int ret = x64_rcg_make2(c, NULL, NULL); \
if (ret < 0) \
return ret; \
- return _x64_rcg_make(c, g, NULL, NULL, NULL); \
+ return x64_rcg_make(c, g, NULL, NULL); \
} \
static int _x64_rcg_##name##_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \
{ \
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL); \
+ int ret = x64_rcg_make2(c, NULL, NULL); \
if (ret < 0) \
return ret; \
- return _x64_rcg_make(c, g, NULL, NULL, NULL); \
+ return x64_rcg_make(c, g, NULL, NULL); \
} \
static int _x64_rcg_##name##_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \
{ \
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL); \
+ int ret = x64_rcg_make2(c, NULL, NULL); \
if (ret < 0) \
return ret; \
- return _x64_rcg_make(c, g, NULL, NULL, NULL); \
+ return x64_rcg_make(c, g, NULL, NULL); \
} \
static int _x64_rcg_##name##_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \
{ \
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL); \
+ int ret = x64_rcg_make2(c, NULL, NULL); \
if (ret < 0) \
return ret; \
- return _x64_rcg_make(c, g, NULL, NULL, NULL); \
+ return x64_rcg_make(c, g, NULL, NULL); \
}
X64_RCG_UNARY_ASSIGN(inc)
X64_RCG_UNARY_ASSIGN(dec)
{ \
scf_3ac_operand_t* dst = c->dsts->data[0]; \
\
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL); \
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL); \
if (ret < 0) \
return ret; \
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL); \
+ return x64_rcg_make(c, g, dst->dag_node, NULL); \
} \
static int _x64_rcg_##name##_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \
{ \
scf_3ac_operand_t* dst = c->dsts->data[0]; \
\
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL); \
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL); \
if (ret < 0) \
return ret; \
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL); \
+ return x64_rcg_make(c, g, dst->dag_node, NULL); \
} \
static int _x64_rcg_##name##_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \
{ \
scf_3ac_operand_t* dst = c->dsts->data[0]; \
\
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL); \
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL); \
if (ret < 0) \
return ret; \
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL); \
+ return x64_rcg_make(c, g, dst->dag_node, NULL); \
} \
static int _x64_rcg_##name##_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \
{ \
scf_3ac_operand_t* dst = c->dsts->data[0]; \
\
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL); \
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL); \
if (ret < 0) \
return ret; \
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL); \
+ return x64_rcg_make(c, g, dst->dag_node, NULL); \
}
X64_RCG_UNARY_POST_ASSIGN(inc_post)
X64_RCG_UNARY_POST_ASSIGN(dec_post)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_address_of_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static int _x64_rcg_push_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
static int _x64_rcg_va_start_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL);
+ int ret = x64_rcg_make2(c, NULL, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, NULL, NULL, NULL);
+ return x64_rcg_make(c, g, NULL, NULL);
}
static int _x64_rcg_va_end_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
- int ret = _x64_rcg_make2(c, NULL, NULL, NULL);
+ int ret = x64_rcg_make2(c, NULL, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, NULL, NULL, NULL);
+ return x64_rcg_make(c, g, NULL, NULL);
}
static int _x64_rcg_va_arg_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
scf_3ac_operand_t* dst = c->dsts->data[0];
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
if (ret < 0)
return ret;
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
}
static x64_rcg_handler_pt x64_rcg_handlers[SCF_N_3AC_OPS] =
[SCF_OP_AND_ASSIGN ] = _x64_rcg_and_assign_handler,
[SCF_OP_OR_ASSIGN ] = _x64_rcg_or_assign_handler,
- [SCF_OP_VLA_ALLOC ] = _x64_rcg_vla_alloc_handler,
- [SCF_OP_VLA_FREE ] = _x64_rcg_vla_free_handler,
-
[SCF_OP_RETURN ] = _x64_rcg_return_handler,
[SCF_OP_3AC_CMP ] = _x64_rcg_cmp_handler,
[SCF_OP_3AC_TEQ ] = _x64_rcg_teq_handler,
- [SCF_OP_3AC_DUMP ] = _x64_rcg_dump_handler,
[SCF_OP_3AC_SETZ ] = _x64_rcg_setz_handler,
[SCF_OP_3AC_SETNZ ] = _x64_rcg_setnz_handler,
mov = x64_find_OpCode(SCF_X64_MOV, r->bytes, r->bytes, SCF_X64_G2E);
}
- inst = x64_make_inst_G2M(&rela, mov, v, NULL, r);
+ inst = x64_make_inst_G2M(&rela, mov, v, NULL, r, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
return r_min;
}
-scf_register_t* x64_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c)
+scf_register_t* x64_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c, int is_float)
{
scf_vector_t* neighbors = NULL;
scf_graph_node_t* gn = NULL;
scf_register_t* free_regs[sizeof(x64_registers) / sizeof(x64_registers[0])];
int nb_free_regs = 0;
- int is_float = scf_variable_float(dn->var);
- int bytes = x64_variable_size(dn->var);
+ int bytes = 8;
int ret;
int i;
int j;
- scf_logd("bytes: %d\n", bytes);
-
assert(c->rcg);
+ if (dn) {
+ is_float = scf_variable_float(dn->var);
+ bytes = x64_variable_size (dn->var);
+ }
+
+ scf_logd("bytes: %d\n", bytes);
+
ret = x64_rcg_find_node(&gn, c->rcg, dn, NULL);
if (ret < 0)
neighbors = c->rcg->nodes;
return NULL;
}
+int x64_select_free_reg(scf_register_t** preg, scf_3ac_code_t* c, scf_function_t* f, int is_float)
+{
+ scf_register_t* r;
+
+ r = x64_select_overflowed_reg(NULL, c, is_float);
+ if (!r) {
+ scf_loge("\n");
+ return -1;
+ }
+
+ int ret = x64_overflow_reg(r, c, f);
+ if (ret < 0) {
+ scf_loge("overflow reg failed\n");
+ return ret;
+ }
+ assert(0 == r->dag_nodes->size);
+
+ r = x64_find_register_type_id_bytes(is_float, r->id, 8);
+
+ assert(0 == r->dag_nodes->size);
+
+ ret = x64_rcg_make(c, c->rcg, NULL, r);
+ if (ret < 0)
+ return ret;
+
+ r->used = 1;
+
+ *preg = r;
+ return 0;
+}
+
int x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f)
{
scf_instruction_t* inst;
lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G);
- inst = x64_make_inst_M2G(&rela, lea, r, NULL, v);
+ inst = x64_make_inst_M2G(&rela, lea, r, NULL, v, NULL, NULL);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
} else if (v->nb_dimentions > 0) {
assert(v->const_literal_flag);
+ assert(!v->extern_flag || !f->pic_flag);
+
lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G);
- inst = x64_make_inst_M2G(&rela, lea, r, NULL, v);
+ inst = x64_make_inst_M2G(&rela, lea, r, NULL, v, NULL, NULL);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
v->tmp_flag = 0;
lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G);
- inst = x64_make_inst_M2G(&rela, lea, r, NULL, v);
+ inst = x64_make_inst_M2G(&rela, lea, r, NULL, v, NULL, NULL);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, v->func_ptr);
} else {
return -EINVAL;
}
- inst = x64_make_inst_M2G(&rela, mov, r, NULL, dn->var);
+ inst = x64_make_inst_M2G(&rela, mov, r, NULL, dn->var, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dn->var, NULL);
}
#endif
} else {
- r = x64_select_overflowed_reg(dn, c);
+ r = x64_select_overflowed_reg(dn, c, is_float);
if (!r) {
scf_loge("\n");
return -1;
int32_t disp = 0;
- if ((vb->nb_pointers > 0 && 0 == vb->nb_dimentions) || vb->vla_flag) {
+ if (vb->nb_pointers > 0 && 0 == vb->nb_dimentions) {
ret = x64_select_reg(&rb, base, c, f, 1);
if (ret < 0) {
scf_register_t* x64_find_abi_register(int index, int bytes);
-scf_register_t* x64_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c);
+scf_register_t* x64_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c, int is_float);
int x64_reg_cached_vars(scf_register_t* r);
int x64_overflow_reg (scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f);
int x64_overflow_reg2(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f);
-int x64_select_reg(scf_register_t** preg, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f, int load_flag);
+int x64_select_free_reg(scf_register_t** preg, scf_3ac_code_t* c, scf_function_t* f, int is_float);
+int x64_select_reg (scf_register_t** preg, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f, int load_flag);
int x64_dereference_reg(x64_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* member, scf_3ac_code_t* c, scf_function_t* f);
CFILES += ../core/scf_optimizer_basic_block.c
CFILES += ../core/scf_optimizer_const_teq.c
CFILES += ../core/scf_optimizer_loop.c
-CFILES += ../core/scf_optimizer_vla.c
CFILES += ../core/scf_optimizer_group.c
CFILES += ../core/scf_optimizer_generate_loads_saves.c
void usage(char* path)
{
- fprintf(stderr, "Usage: %s [-std=..] [-c] [-p/-t] [-d] [-a arch] [-s sysroot] [-Dmacro / -D macro] [-Iinclude / -I include] [-lsofile / -l sofile] [-Lsopath / -L sopath] [-o out] src0 [src1]\n\n", path);
+ fprintf(stderr, "Usage: %s [-std=..] [-fpic / -fPIC] [-c] [-p/-t] [-shared] [-a arch] [-s sysroot] [-Dmacro / -D macro] [-Iinclude / -I include] [-lsofile / -l sofile] [-Lsopath / -L sopath] [-o out] src0 [src1]\n\n", path);
+
fprintf(stderr, "-std: c89 or c99 version\n");
+ fprintf(stderr, "-fpic: PIC, position independent code\n");
+ fprintf(stderr, "-shared: output dynamic library .so\n\n");
+
fprintf(stderr, "-c: only compile, not link\n");
fprintf(stderr, "-p: only parse, not compile\n");
fprintf(stderr, "-t: only 3ac code, not compile\n\n");
fprintf(stderr, "-a: select cpu arch (x64, arm64, naja, or eda), default is x64\n");
- fprintf(stderr, "-s: sysroot dir, default is '../lib'\n");
- fprintf(stderr, "-d: output dynamic library .so\n\n");
+ fprintf(stderr, "-s: sysroot dir, default is '../sysroot'\n\n");
fprintf(stderr, "-D: define a macro\n");
fprintf(stderr, "-I: include paths for .h file\n");
goto error;
}
- int obj_size = objs->size;
- int so_size = sofiles->size;
+ int n_objs = objs->size;
+ int n_sofiles = sofiles->size;
char* sysroot = "../sysroot";
char* arch = "x64";
int _3ac = 0;
int _parse = 0;
int dyn = 0;
+ int pic = 0;
int c_version = SCF_C99;
int i;
goto error;
}
+ int n_srcs = srcs->size;
+
for (i = 1; i < argc; i++) {
if ('-' == argv[i][0]) {
continue;
}
+ if ('f' == argv[i][1]) {
+ if (!strcmp(argv[i] + 1, "fpic") || !strcmp(argv[i] + 1, "fPIC"))
+ pic = 1;
+ continue;
+ }
+
if ('p' == argv[i][1]) {
link = 0;
_3ac = 0;
continue;
}
- if ('d' == argv[i][1]) {
- dyn = 1;
- link = 1;
- _3ac = 0;
- _parse = 0;
- continue;
- }
-
if ('a' == argv[i][1]) {
if (++i >= argc || '-' == argv[i][0]) {
|| !strcmp(std, "ansi"))
c_version = SCF_C89;
- scf_logi("%s, c_version: %d\n", argv[i], c_version);
+ continue;
+
+ } else if (!strcmp(argv[i] + 1, "shared")) {
+ dyn = 1;
+ link = 1;
+ _3ac = 0;
+ _parse = 0;
continue;
}
exec = out;
}
- if (srcs->size > 0) {
+ if (srcs->size > n_srcs) {
scf_parse_t* parse = NULL;
ret = scf_parse_open(&parse, inc_paths, c_version);
}
if (!_parse) {
- ret = scf_parse_compile(parse, arch, _3ac);
+ ret = scf_parse_compile(parse, arch, _3ac, pic);
if (ret < 0) {
scf_loge("\n");
goto error;
parse = NULL;
}
- obj_size = objs->size;
- so_size = sofiles->size;
+ n_objs = objs->size;
+ n_sofiles = sofiles->size;
if (link) {
ret = add_so_files(sofiles, lib_paths, lib_files);
else
MAIN_ADD_FILES(__objs, __sofiles, "x64");
- if (srcs->size > 0) {
+ if (srcs->size > n_srcs) {
ret = scf_vector_add(objs, obj);
if (ret < 0)
goto error;
scf_vector_free(srcs);
if (sofiles) {
- for (i = so_size; i < sofiles->size; i++) {
- char* file = sofiles->data[i];
+ for (i = n_sofiles; i < sofiles->size; i++) {
+ char* file = sofiles->data[i];
scf_logd("i: %d, file: %p, %s\n", i, file, file);
}
if (objs) {
- for (i = obj_size; i < objs->size - 1; i++) {
- char* file = objs->data[i];
+ for (i = n_objs; i < objs->size - 1; i++) {
+ char* file = objs->data[i];
free(file);
}
scf_stack_t* s = d->module_datas[dfa_module_container.index];
dfa_container_data_t* cd = scf_stack_top(s);
- if (d->current_va_arg)
+ if (d->current_va_arg || d->current_va_copy)
return SCF_DFA_NEXT_SYNTAX;
if (!cd) {
return SCF_DFA_NEXT_SYNTAX;
}
- if (d->current_va_arg) {
- scf_logw("SCF_DFA_NEXT_SYNTAX\n");
+ if (d->current_va_arg || d->current_va_copy)
return SCF_DFA_NEXT_SYNTAX;
- }
scf_variable_t* var = NULL;
scf_node_t* node_var = NULL;
SCF_DFA_GET_MODULE_NODE(dfa, type, star, star);
SCF_DFA_GET_MODULE_NODE(dfa, va_arg, arg, va_arg);
+ SCF_DFA_GET_MODULE_NODE(dfa, va_arg, copy, va_copy);
SCF_DFA_GET_MODULE_NODE(dfa, va_arg, rp, va_rp);
SCF_DFA_GET_MODULE_NODE(dfa, container, container, container);
scf_dfa_node_add_child(va_rp, comma);
scf_dfa_node_add_child(va_rp, semicolon);
+ // va_copy(dst, src)
+ scf_dfa_node_add_child(expr, va_copy);
+
// sizeof()
scf_dfa_node_add_child(expr, _sizeof);
scf_dfa_node_add_child(sizeof_rp, rp);
}
id->identity = w;
- id->const_flag = d->const_flag;
- d ->const_flag = 0;
+ id->const_flag = d->const_flag;
+ id->extern_flag = d->extern_flag;
+
+ d->const_flag = 0;
+ d->extern_flag = 0;
return SCF_DFA_NEXT_WORD;
}
scf_stack_t* s = d->module_datas[dfa_module_sizeof.index];
dfa_sizeof_data_t* sd = scf_stack_top(s);
- if (d->current_va_arg)
+ if (d->current_va_arg || d->current_va_copy)
return SCF_DFA_NEXT_SYNTAX;
if (!sd) {
return SCF_LEX_WORD_KEY_VA_ARG == w->type;
}
+static inline int scf_dfa_is_va_copy(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_VA_COPY == w->type;
+}
+
static inline int scf_dfa_is_va_end(scf_dfa_t* dfa, void* word)
{
scf_lex_word_t* w = word;
return SCF_DFA_NEXT_WORD;
}
+static int _va_arg_action_copy(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+ scf_lex_word_t* w = words->data[words->size - 1];
+
+ scf_loge("%s:%d:%d, NOT support 'va_copy'\n", w->file->data, w->line, w->pos);
+ return SCF_DFA_ERROR;
+}
+
static int _va_arg_action_arg(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
scf_parse_t* parse = dfa->priv;
return SCF_DFA_ERROR;
}
- if (scf_ast_find_type(&t, parse->ast, "va_list") < 0) {
+ if (scf_ast_find_type(&t, parse->ast, "__builtin_va_list") < 0) {
scf_loge("type 'va_list' not found, line: %d\n", w->line);
return SCF_DFA_ERROR;
}
else if (d->current_va_arg)
scf_node_add_child(d->current_va_arg, node);
+ else if (d->current_va_copy)
+ scf_node_add_child(d->current_va_copy, node);
+
else if (d->current_va_end)
scf_node_add_child(d->current_va_end, node);
else {
}
if (!id->type) {
-
if (_type_find_type(dfa, id) < 0) {
scf_loge("\n");
return SCF_DFA_ERROR;
d->current_va_start = NULL;
d->current_va_arg = NULL;
+ d->current_va_copy = NULL;
d->current_va_end = NULL;
return SCF_DFA_NEXT_WORD;
d->current_va_start = NULL;
d->current_va_arg = NULL;
+ d->current_va_copy = NULL;
d->current_va_end = NULL;
return SCF_DFA_SWITCH_TO;
SCF_DFA_MODULE_NODE(dfa, va_arg, start, scf_dfa_is_va_start, _va_arg_action_start);
SCF_DFA_MODULE_NODE(dfa, va_arg, arg, scf_dfa_is_va_arg, _va_arg_action_arg);
+ SCF_DFA_MODULE_NODE(dfa, va_arg, copy, scf_dfa_is_va_copy, _va_arg_action_copy);
SCF_DFA_MODULE_NODE(dfa, va_arg, end, scf_dfa_is_va_end, _va_arg_action_end);
SCF_DFA_MODULE_NODE(dfa, va_arg, ap, scf_dfa_is_identity, _va_arg_action_ap);
SCF_DFA_GET_MODULE_NODE(dfa, va_arg, start, start);
SCF_DFA_GET_MODULE_NODE(dfa, va_arg, arg, arg);
+ SCF_DFA_GET_MODULE_NODE(dfa, va_arg, copy, copy);
SCF_DFA_GET_MODULE_NODE(dfa, va_arg, end, end);
SCF_DFA_GET_MODULE_NODE(dfa, va_arg, ap, ap);
SCF_DFA_GET_MODULE_NODE(dfa, type, star, star);
SCF_DFA_GET_MODULE_NODE(dfa, identity, identity, identity);
+ // va_start(ap, fmt)
scf_dfa_node_add_child(start, lp);
scf_dfa_node_add_child(lp, ap);
scf_dfa_node_add_child(ap, comma);
scf_dfa_node_add_child(fmt, rp);
scf_dfa_node_add_child(rp, semicolon);
+ // va_copy(ap2, ap)
+ scf_dfa_node_add_child(copy, lp);
+ scf_dfa_node_add_child(comma, ap);
+
+ // va_end(ap)
scf_dfa_node_add_child(end, lp);
scf_dfa_node_add_child(ap, rp);
+ // va_arg(ap, type)
scf_dfa_node_add_child(arg, lp);
scf_dfa_node_add_child(ap, type);
for (i = 0; i < id0->type_def->nb_dimentions; i++) {
dim = &id0->type_def->dimentions[i];
- scf_variable_add_array_dimention(v, dim->num, NULL);
+ scf_variable_add_array_dimention(v, dim->num);
}
v->const_literal_flag = id0->type_def->nb_dimentions > 0;
return 0;
}
-static int _var_add_vla(scf_ast_t* ast, scf_variable_t* vla)
-{
- scf_function_t* f = NULL;
- scf_expr_t* e = NULL;
- scf_expr_t* e2 = NULL;
- scf_node_t* mul = NULL;
-
- if (scf_ast_find_function(&f, ast, "printf") < 0 || !f) {
- scf_loge("printf() NOT found, which used to print error message when the variable length of array '%s' <= 0, file: %s, line: %d\n",
- vla->w->text->data, vla->w->file->data, vla->w->line);
- return SCF_DFA_ERROR;
- }
-
- int size = vla->data_size;
- int i;
-
- for (i = 0; i < vla->nb_dimentions; i++) {
-
- if (vla->dimentions[i].num > 0) {
- size *= vla->dimentions[i].num;
- continue;
- }
-
- if (0 == vla->dimentions[i].num) {
- scf_loge("\n");
-
- scf_expr_free(e);
- return SCF_DFA_ERROR;
- }
-
- if (!vla->dimentions[i].vla) {
- scf_loge("\n");
-
- scf_expr_free(e);
- return SCF_DFA_ERROR;
- }
-
- if (!e) {
- e = scf_expr_clone(vla->dimentions[i].vla);
- if (!e)
- return -ENOMEM;
- continue;
- }
-
- e2 = scf_expr_clone(vla->dimentions[i].vla);
- if (!e2) {
- scf_expr_free(e);
- return -ENOMEM;
- }
-
- mul = scf_node_alloc(vla->w, SCF_OP_MUL, NULL);
- if (!mul) {
- scf_expr_free(e2);
- scf_expr_free(e);
- return -ENOMEM;
- }
-
- int ret = scf_expr_add_node(e, mul);
- if (ret < 0) {
- scf_expr_free(mul);
- scf_expr_free(e2);
- scf_expr_free(e);
- return ret;
- }
-
- ret = scf_expr_add_node(e, e2);
- if (ret < 0) {
- scf_expr_free(e2);
- scf_expr_free(e);
- return ret;
- }
- }
-
- assert(e);
-
- scf_variable_t* v;
- scf_type_t* t;
- scf_node_t* node;
-
- if (size > 1) {
- mul = scf_node_alloc(vla->w, SCF_OP_MUL, NULL);
- if (!mul) {
- scf_expr_free(e);
- return -ENOMEM;
- }
-
- int ret = scf_expr_add_node(e, mul);
- if (ret < 0) {
- scf_expr_free(mul);
- scf_expr_free(e);
- return ret;
- }
-
- t = scf_block_find_type_type(ast->current_block, SCF_VAR_INT);
- v = SCF_VAR_ALLOC_BY_TYPE(vla->w, t, 1, 0, NULL);
- if (!v) {
- scf_expr_free(e);
- return SCF_DFA_ERROR;
- }
- v->data.i64 = size;
- v->global_flag = 1;
- v->const_literal_flag = 1;
-
- node = scf_node_alloc(NULL, v->type, v);
- scf_variable_free(v);
- v = NULL;
- if (!node) {
- scf_expr_free(e);
- return SCF_DFA_ERROR;
- }
-
- ret = scf_expr_add_node(e, node);
- if (ret < 0) {
- scf_node_free(node);
- scf_expr_free(e);
- return ret;
- }
- }
-
- scf_node_t* assign;
- scf_node_t* len;
- scf_node_t* alloc;
-
- // len = e
- assign = scf_node_alloc(vla->w, SCF_OP_ASSIGN, NULL);
- if (!assign) {
- scf_expr_free(e);
- return SCF_DFA_ERROR;
- }
-
- scf_node_add_child(assign, e->nodes[0]);
- e->nodes[0] = assign;
- assign->parent = e;
-
- scf_node_add_child((scf_node_t*)ast->current_block, e);
- e = NULL;
-
- t = scf_block_find_type_type(ast->current_block, SCF_VAR_INT);
- v = SCF_VAR_ALLOC_BY_TYPE(vla->w, t, 0, 0, NULL);
- if (!v)
- return SCF_DFA_ERROR;
- v->tmp_flag = 1;
-
- len = scf_node_alloc(NULL, v->type, v);
- if (!len) {
- scf_variable_free(v);
- return SCF_DFA_ERROR;
- }
-
- scf_node_add_child(assign, len);
- SCF_XCHG(assign->nodes[0], assign->nodes[1]);
-
- // vla_alloc(vla, len, printf, msg)
- len = scf_node_alloc(NULL, v->type, v);
- scf_variable_free(v);
- v = NULL;
- if (!len)
- return SCF_DFA_ERROR;
-
- alloc = scf_node_alloc(vla->w, SCF_OP_VLA_ALLOC, NULL);
- if (!alloc) {
- scf_node_free(len);
- return -ENOMEM;
- }
-
- // vla node
- node = scf_node_alloc(NULL, vla->type, vla);
- if (!node) {
- scf_node_free(len);
- scf_node_free(alloc);
- return SCF_DFA_ERROR;
- }
-
- scf_node_add_child(alloc, node);
- scf_node_add_child(alloc, len);
- node = NULL;
- len = NULL;
-
- // printf() node
- t = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR);
- v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 1, 1, f);
- if (!v) {
- scf_node_free(alloc);
- return SCF_DFA_ERROR;
- }
- v->const_literal_flag = 1;
-
- node = scf_node_alloc(NULL, v->type, v);
- scf_variable_free(v);
- v = NULL;
- if (!node) {
- scf_node_free(alloc);
- return SCF_DFA_ERROR;
- }
-
- scf_node_add_child(alloc, node);
- node = NULL;
-
- // msg
- char msg[1024];
- snprintf(msg, sizeof(msg) - 1, "\033[31merror:\033[0m variable length '%%d' of array '%s' not more than 0, file: %s, line: %d\n",
- vla->w->text->data, vla->w->file->data, vla->w->line);
-
- t = scf_block_find_type_type(ast->current_block, SCF_VAR_CHAR);
- v = SCF_VAR_ALLOC_BY_TYPE(vla->w, t, 1, 1, NULL);
- if (!v) {
- scf_node_free(alloc);
- return SCF_DFA_ERROR;
- }
- v->const_literal_flag = 1;
- v->global_flag = 1;
-
- v->data.s = scf_string_cstr(msg);
- if (!v->data.s) {
- scf_node_free(alloc);
- scf_variable_free(v);
- return -ENOMEM;
- }
-
- node = scf_node_alloc(NULL, v->type, v);
- scf_variable_free(v);
- v = NULL;
- if (!node) {
- scf_node_free(alloc);
- return SCF_DFA_ERROR;
- }
- scf_node_add_child(alloc, node);
- node = NULL;
-
- scf_node_add_child((scf_node_t*)ast->current_block, alloc);
- return 0;
-}
-
static int _var_add_typedef(scf_ast_t* ast, dfa_data_t* d)
{
scf_variable_t* v;
assert(0 == scf_vector_del(ast->current_block->scope->vars, d->current_var));
- d->current_var->vla_flag = 0;
d->current_var = NULL;
}
return SCF_DFA_SWITCH_TO;
}
-
- if (d->current_var->vla_flag) {
-
- if (_var_add_vla(parse->ast, d->current_var) < 0)
- return SCF_DFA_ERROR;
- }
}
if (d->expr_local_flag > 0 && _var_init_expr(dfa, d, words, 0) < 0)
return SCF_DFA_OK;
}
-
- if (d->current_var->vla_flag) {
-
- if (_var_add_vla(parse->ast, d->current_var) < 0)
- return SCF_DFA_ERROR;
- }
}
if (d->expr_local_flag > 0) {
return SCF_DFA_ERROR;
}
- if (d->current_var->vla_flag) {
-
- if (_var_add_vla(parse->ast, d->current_var) < 0)
- return SCF_DFA_ERROR;
- }
-
if (d->current_var->nb_dimentions > 0) {
scf_logi("var array '%s' init, nb_dimentions: %d\n", d->current_var->w->text->data, d->current_var->nb_dimentions);
return SCF_DFA_NEXT_WORD;
d->expr = NULL;
}
- scf_variable_add_array_dimention(d->current_var, -1, NULL);
+ scf_variable_add_array_dimention(d->current_var, -1);
d->current_var->const_literal_flag = 1;
SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "var_rs"), SCF_DFA_HOOK_POST);
if (!scf_variable_const(r) && SCF_OP_ASSIGN != d->expr->nodes[0]->type) {
- if (d->current_var->typedef_flag) {
- scf_loge("variable length array '%s' can't be type defined, file: %s, line: %d\n",
- d->current_var->w->text->data, w->file->data, w->line);
- goto error;
- }
-
- if (!d->current_var->local_flag) {
- scf_loge("variable length array '%s' must in local scope, file: %s, line: %d\n",
- d->current_var->w->text->data, w->file->data, w->line);
- goto error;
- }
-
- scf_logw("define variable length array, file: %s, line: %d\n", w->file->data, w->line);
+ scf_loge("%s:%d:%d, NOT support VLA (variable length array)\n", w->file->data, w->line, w->pos);
+ goto error;
- d->current_var->dimentions[d->current_var->dim_index].vla = d->expr;
- d->current_var->vla_flag = 1;
- d->expr = NULL;
} else {
d->current_var->dimentions[d->current_var->dim_index].num = r->data.i;
return 0;
}
-static int _scf_op_const_vla_alloc(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
-{
- assert(4 == nb_nodes);
-
- return 0;
-}
-
static int _scf_op_const_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
assert(4 == nb_nodes);
[SCF_OP_SWITCH ] = _scf_op_const_switch,
[SCF_OP_CASE ] = _scf_op_const_case,
[SCF_OP_DEFAULT ] = _scf_op_const_default,
-
- [SCF_OP_VLA_ALLOC ] = _scf_op_const_vla_alloc,
};
scf_operator_handler_pt scf_find_const_operator_handler(const int type)
int i;
for (i = 0; i < v1->nb_dimentions; i++)
- scf_variable_add_array_dimention(r, v1->dimentions[i].num, NULL);
+ scf_variable_add_array_dimention(r, v1->dimentions[i].num);
*d->pret = r;
return 0;
int nb_pointers = 0;
if (v0->nb_dimentions > 0) {
- if (v0->dimentions[0].num < 0 && !v0->dimentions[0].vla) {
+ if (v0->dimentions[0].num < 0) {
scf_loge("\n");
return -1;
}
return -1;
}
- if (v1->data.i >= v0->dimentions[0].num && !v0->dimentions[0].vla) {
+ if (v1->data.i >= v0->dimentions[0].num) {
if (!v0->member_flag) {
- scf_loge("array index '%s' >= size %d, real: %d, file: %s, line: %d\n",
- v1->w->text->data, v0->dimentions[0].num, v1->data.i, v1->w->file->data, v1->w->line);
+ scf_loge("%s:%d:%d, array index '%s' >= size %d, real: %d\n",
+ v1->w->file->data, v1->w->line, v1->w->pos,
+ v1->w->text->data, v0->dimentions[0].num, v1->data.i);
return -1;
}
- scf_logw("array index '%s' >= size %d, real: %d, confirm it for a zero-array end of a struct? file: %s, line: %d\n",
- v1->w->text->data, v0->dimentions[0].num, v1->data.i, v1->w->file->data, v1->w->line);
+ scf_logw("%s:%d:%d, array index '%s' >= size %d, real: %d, confirm it for a zero-array end of a struct?\n",
+ v1->w->file->data, v1->w->line, v1->w->pos,
+ v1->w->text->data, v0->dimentions[0].num, v1->data.i);
}
}
} else if (0 == v0->nb_dimentions && v0->nb_pointers > 0) {
r->member_flag = v0->member_flag;
int i;
- for (i = 1; i < v0->nb_dimentions; i++) {
- scf_expr_t* vla = NULL;
-
- if (v0->dimentions[i].vla) {
- vla = scf_expr_clone(v0->dimentions[i].vla);
- if (!vla) {
- scf_variable_free(r);
- return -ENOMEM;
- }
- }
-
- scf_variable_add_array_dimention(r, v0->dimentions[i].num, vla);
- }
+ for (i = 1; i < v0->nb_dimentions; i++)
+ scf_variable_add_array_dimention(r, v0->dimentions[i].num);
*d->pret = r;
return 0;
return 0;
}
-static int _scf_op_semantic_vla_alloc(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
-{
- assert(4 == nb_nodes);
-
- scf_logw("\n");
- return 0;
-}
-
static int _scf_op_semantic_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
assert(4 == nb_nodes);
[SCF_OP_SWITCH ] = _scf_op_semantic_switch,
[SCF_OP_CASE ] = _scf_op_semantic_case,
[SCF_OP_DEFAULT ] = _scf_op_semantic_default,
-
- [SCF_OP_VLA_ALLOC ] = _scf_op_semantic_vla_alloc,
};
scf_operator_handler_pt scf_find_semantic_operator_handler(const int type)
int size;
uint8_t* v_data;
- if (v->global_flag) {
+ if (v->global_flag)
name = v->w->text->data;
- } else
+ else
name = v->signature->data;
scf_logd("v_%d_%d/%s, nb_dimentions: %d\n", v->w->line, v->w->pos, v->w->text->data, v->nb_dimentions);
for (j = 0; j < f->data_relas->size; j++) {
r = f->data_relas->data[j];
- char* name;
- if (r->var->global_flag)
+ uint16_t shndx = SCF_SHNDX_DATA;
+ char* name;
+
+ if (r->var->global_flag) {
name = r->var->w->text->data;
- else
+
+ if (r->var->extern_flag)
+ shndx = 0;
+ } else
name = r->var->signature->data;
- ret = scf_symtab_add_rela(relas, parse->symtab, r, name, 2);
+ ret = scf_symtab_add_rela(relas, parse->symtab, r, name, shndx);
if (ret < 0) {
scf_loge("\n");
goto error;
return 0;
}
-int scf_parse_native_functions(scf_parse_t* parse, scf_vector_t* functions, const char* arch)
+int scf_parse_native_functions(scf_parse_t* parse, scf_vector_t* functions, const char* arch, int pic_flag)
{
scf_function_t* f;
scf_native_t* native;
if (f->native_flag)
continue;
+
f->native_flag = 1;
+ f->pic_flag = pic_flag;
ret = scf_native_select_inst(native, f);
if (ret < 0) {
return 0;
}
-int scf_parse_compile(scf_parse_t* parse, const char* arch, int _3ac)
+int scf_parse_compile(scf_parse_t* parse, const char* arch, int _3ac, int pic_flag)
{
scf_block_t* b = parse->ast->root_block;
if (!b)
if (_3ac)
goto error;
- ret = scf_parse_native_functions(parse, functions, arch);
+ ret = scf_parse_native_functions(parse, functions, arch, pic_flag);
error:
scf_vector_free(functions);
return ret;
scf_node_t* current_va_start;
scf_node_t* current_va_arg;
+ scf_node_t* current_va_copy;
scf_node_t* current_va_end;
uint32_t typedef_flag:1;
int scf_parse_close(scf_parse_t* parse);
int scf_parse_file (scf_parse_t* parse, const char* path, scf_vector_t** macros, scf_lex_word_t* include);
-int scf_parse_compile(scf_parse_t* parse, const char* arch, int _3ac);
+int scf_parse_compile(scf_parse_t* parse, const char* arch, int _3ac, int pic_flag);
int scf_parse_to_obj (scf_parse_t* parse, const char* out, const char* arch);
int _find_global_var(scf_node_t* node, void* arg, scf_vector_t* vec);
--- /dev/null
+#ifndef _STDARG_H
+#define _STDARG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_va_list
+
+#include <bits/alltypes.h>
+
+#define va_start(v,l) __builtin_va_start(v,l)
+#define va_end(v) __builtin_va_end(v)
+#define va_arg(v,l) __builtin_va_arg(v,l)
+#define va_copy(d,s) __builtin_va_copy(d,s)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
.text
-.global _start, main
-
+.global _start
_start:
- mov %rsp, %rsi
- add $8, %rsi # argv
- mov %rsi, %rdx
-1:
- mov (%rdx), %rdi
- add $8, %rdx # envp
- test %rdi, %rdi
- jnz 1b
-
- mov (%rsp), %rdi # argc
+ endbr64
+ xor %ebp,%ebp
+ mov %rdx,%r9
+ pop %rsi
+ mov %rsp,%rdx
+ and $-16,%rsp
+ push %rax
+ push %rsp
+ xor %r8d,%r8d
+ xor %ecx,%ecx
- call main
- mov %rax, %rdi
- mov $60, %rax
- syscall
-.fill 5, 1, 0
+ lea main(%rip), %rdi
+ call __libc_start_main
+ hlt
+.fill 3, 1, 0