1, support -fpic to make PIC .o,
authoryu.dongliang <18588496441@163.com>
Sun, 9 Aug 2026 16:50:01 +0000 (00:50 +0800)
committeryu.dongliang <18588496441@163.com>
Sun, 9 Aug 2026 16:50:08 +0000 (00:50 +0800)
2, support .rela.dyn & .got to use global vars of .so,
3, use _start.s of libc instead of ../sysroot/lib/x64/_start.s to init global vars of .so
4, delete VLA from SCF.

62 files changed:
core/scf_3ac.c
core/scf_basic_block.h
core/scf_core_types.h
core/scf_function.h
core/scf_lex_word.h
core/scf_operator.c
core/scf_operator_dag.c
core/scf_operator_handler_3ac.c
core/scf_optimizer.c
core/scf_variable.c
core/scf_variable.h
elf/scf_elf.c
elf/scf_elf.h
elf/scf_elf_arm32.c
elf/scf_elf_arm32_so.c
elf/scf_elf_arm64.c
elf/scf_elf_arm64_so.c
elf/scf_elf_link.c
elf/scf_elf_link.h
elf/scf_elf_naja.c
elf/scf_elf_naja_so.c
elf/scf_elf_native.c
elf/scf_elf_native.h
elf/scf_elf_native32.c
elf/scf_elf_native32.h
elf/scf_elf_x64.c
elf/scf_elf_x64_so.c
examples/hello.c
examples/libmy1.c [new file with mode: 0644]
examples/scf_printf.c
examples/test_libmy1.c [new file with mode: 0644]
lex/scf_lex.c
native/risc/scf_risc_reg.c
native/x64/scf_x64.c
native/x64/scf_x64.h
native/x64/scf_x64_inst.c
native/x64/scf_x64_inst_binary.c
native/x64/scf_x64_inst_cmp.c
native/x64/scf_x64_inst_common.c
native/x64/scf_x64_inst_div.c
native/x64/scf_x64_inst_mul.c
native/x64/scf_x64_inst_shift.c
native/x64/scf_x64_inst_util.c
native/x64/scf_x64_peephole.c
native/x64/scf_x64_rcg.c
native/x64/scf_x64_reg.c
native/x64/scf_x64_reg.h
parse/Makefile
parse/main.c
parse/scf_dfa_container.c
parse/scf_dfa_expr.c
parse/scf_dfa_identity.c
parse/scf_dfa_sizeof.c
parse/scf_dfa_util.h
parse/scf_dfa_va_arg.c
parse/scf_dfa_var.c
parse/scf_operator_handler_const.c
parse/scf_operator_handler_semantic.c
parse/scf_parse.c
parse/scf_parse.h
sysroot/include/stdarg.h [new file with mode: 0644]
sysroot/lib/x64/_start.s

index 1331e92a4cbf7b4eaa7815be2e27c910cda028b5..5560a1905898e305680a6ca4d798992ed98cb25d 100644 (file)
@@ -60,9 +60,6 @@ static scf_3ac_operator_t _3ac_operators[] = {
        {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"},
 
@@ -95,7 +92,6 @@ static scf_3ac_operator_t _3ac_operators[] = {
        {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"},
 
@@ -683,36 +679,8 @@ int scf_3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag)
                                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);
 
@@ -1338,10 +1306,6 @@ static int _3ac_find_basic_block_start(scf_list_t* h)
                        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;
@@ -1526,11 +1490,6 @@ static int _3ac_split_basic_blocks(scf_list_t* h, scf_function_t* f)
                                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;
@@ -1580,11 +1539,7 @@ static int _3ac_split_basic_blocks(scf_list_t* h, scf_function_t* f)
                        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;
index 218a03c3ecea7905e86dbcc0b3f872043cfcac14..d6f91e6b4bc532c2ac5d3e7ec90a97c71a7562d6 100644 (file)
@@ -91,7 +91,6 @@ struct scf_basic_block_s
        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;
@@ -109,8 +108,6 @@ struct scf_basic_block_s
        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);
index a7e225e79ceac59d4f4b123b7cbc11c70331ae66..988d8b0c5ee95ab8638ff531755deef6ccd3132b 100644 (file)
@@ -102,13 +102,11 @@ enum scf_core_types
        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
@@ -190,7 +188,6 @@ enum scf_core_types
        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,
 
index a6558876cb1e8e6c8a9a65780ee557f22a88a190..d0596a7f8a5c9dbdcd665e86fa3e5686f6e41c23 100644 (file)
@@ -64,7 +64,7 @@ struct scf_function_s {
        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;
index 92a2b5da1db9b43b1308f66ddc0350139504a1da..54eeaea09b337c2c1e9e56a00177aabe0bc7735e 100644 (file)
@@ -64,6 +64,7 @@ enum scf_lex_words
        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,        // ?
index 4219d0c8fcaa26af12432d851c861b2db4750bc3..7b9160f04ae9a36343fd8277d91e2d6737820865 100644 (file)
@@ -84,9 +84,6 @@ static scf_operator_t base_operators[] =
        {"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)
index 0e5f0c8575a82e72bc6bfde27b51f8eb5161e61e..62ebd0e856e96a5fea06bd339cb08973ee8b9b1e 100644 (file)
@@ -390,12 +390,6 @@ static int _scf_dag_op_return(scf_list_t* h, scf_dag_node_t* parent, scf_dag_nod
        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);
@@ -472,7 +466,6 @@ scf_dag_operator_t  dag_operators[] =
        {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},
index b93a3a119ab7532d87473a01153da63ea995d6a7..72909501825d63869f9dea340d911d10c4a3e9e5 100644 (file)
@@ -1178,72 +1178,6 @@ static int _scf_op_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void*
        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;
@@ -2568,8 +2502,6 @@ scf_operator_handler_pt  __operator_handlers[SCF_N_3AC_OPS] =
        [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)
index 1b84c1267a46ec9228362340b69cc59112ddd003..133a513c5c13c7e1f38accb259d821e79ee83da6 100644 (file)
@@ -25,7 +25,6 @@ extern scf_optimizer_t   scf_optimizer_basic_block;
 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;
 
@@ -57,7 +56,6 @@ static scf_optimizer_t*  scf_optimizers[] =
 
        &scf_optimizer_dominators,
        &scf_optimizer_loop,
-       &scf_optimizer_vla,
        &scf_optimizer_group,
 
        &scf_optimizer_generate_loads_saves,
index bcd9cdb1539fc5c8a456865ba4d166d162f5d563..7a1a9e2e90aed69daef961b9a879d0d6b8f54e9c 100644 (file)
@@ -298,7 +298,7 @@ void scf_variable_free(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)
 {
        assert(array);
 
@@ -307,7 +307,6 @@ void scf_variable_add_array_dimention(scf_variable_t* array, int num, scf_expr_t
 
        array->dimentions = p;
        array->dimentions[array->nb_dimentions].num = num;
-       array->dimentions[array->nb_dimentions].vla = vla;
        array->nb_dimentions++;
 }
 
@@ -466,9 +465,6 @@ int scf_variable_size(scf_variable_t* v)
 
        assert(v->nb_dimentions > 0);
 
-       if (v->vla_flag)
-               return sizeof(void*);
-
        int capacity = 1;
        int j;
 
index aa501f543077dda838d426965f478ed49adf1485..077b7b53191d5ac74dbcf28c6d30a78eebc7115e 100644 (file)
@@ -5,8 +5,7 @@
 #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 {
@@ -67,7 +66,6 @@ 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;
@@ -92,13 +90,13 @@ int             scf_member_offset(scf_member_t*   m);
 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);
@@ -121,7 +119,7 @@ static inline int scf_variable_const(scf_variable_t* v)
                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;
 }
index 1d5c0206a57d80238378ff39aa512d480c5db2e0..e41a82e0b4b5235c8b0c40a37033facb066c0ac8 100644 (file)
@@ -114,11 +114,8 @@ int scf_elf_close(scf_elf_context_t* elf)
 
 int scf_elf_add_sym(scf_elf_context_t* elf, const scf_elf_sym_t* sym, const char* sh_name)
 {
-       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;
@@ -142,11 +139,8 @@ int scf_elf_add_syms(scf_elf_context_t* elf, const scf_vector_t* syms, const cha
 
 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;
@@ -154,23 +148,26 @@ 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)
 {
-       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;
@@ -178,11 +175,8 @@ int        scf_elf_add_dyn_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela)
 
 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;
@@ -190,11 +184,8 @@ int        scf_elf_add_dyn_need(scf_elf_context_t* elf, const char* soname)
 
 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;
@@ -202,11 +193,8 @@ int scf_elf_read_section(scf_elf_context_t* elf, scf_elf_section_t** psection, c
 
 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;
@@ -214,11 +202,8 @@ int scf_elf_read_syms(scf_elf_context_t* elf, scf_vector_t* syms, const char* sh
 
 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;
index 0a40786ec912cdd1e4456e176e373936a02d797a..0c290c91753c0b01ddba241792b526b1691f352b 100644 (file)
@@ -27,6 +27,7 @@ typedef struct {
        uint8_t         st_info;
 
        uint8_t     dyn_flag:1;
+       uint8_t     got_flag:1;
 } scf_elf_sym_t;
 
 typedef struct {
@@ -79,7 +80,8 @@ struct scf_elf_ops_s
        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);
@@ -108,8 +110,10 @@ int scf_elf_add_syms(scf_elf_context_t* elf, const scf_vector_t*  syms, const ch
 
 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);
 
index 6e66b0f0fc2dfbe66c93f5a46d4c8933ee9aef77..f4223ed1d34ec22ea6d2bd2110039fec7ea11efc 100644 (file)
@@ -452,7 +452,8 @@ scf_elf_ops_t       elf_ops_arm32 =
        .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,
index fc1dee00d54714d2c74b5b051fb769206ae47b47..7c323ec8818484981e583a7320766f9f30d56cb5 100644 (file)
@@ -737,8 +737,8 @@ int __arm32_elf_post_dyn(elf_native_t* arm32, uint64_t rx_base, uint64_t rw_base
                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);
index 3cfe50e5c27f93f2b1e43090f884295e0a3617b9..647b8b64ef87119db87daa8d14b9e6a2b54fe69b 100644 (file)
@@ -464,7 +464,8 @@ scf_elf_ops_t       elf_ops_arm64 =
        .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,
index 783c4e9abfba6a9e238a1e516ea1001122e7af17..54287f0ce207c3da67d6112f8b763014b0c96244 100644 (file)
@@ -722,8 +722,8 @@ int __arm64_elf_post_dyn(elf_native_t* arm64, uint64_t rx_base, uint64_t rw_base
                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);
index ba629819a3549ef16f87e9d426dcc228f8f75f68..d60d32e76ea2af886502d580a223821a1856d016 100644 (file)
@@ -27,85 +27,79 @@ int __scf_elf_file_open(scf_elf_file_t** pfile)
        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);
@@ -132,8 +126,9 @@ rodata_error:
 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)
@@ -172,14 +167,6 @@ int scf_so_file_open(scf_elf_file_t** pso, const char* path, const char* mode, c
 
        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");
@@ -235,6 +222,11 @@ int scf_elf_file_close(scf_elf_file_t* ef, void (*rela_free)(void*), void (*sym_
        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;
 }
@@ -834,17 +826,15 @@ static int _find_so_sym(scf_elf_file_t** pso, scf_vector_t* dlls, scf_elf_sym_t*
                        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;
@@ -906,6 +896,8 @@ static int link_relas(scf_elf_file_t* exec, char* afiles[], int nb_afiles, char*
 
                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;
 
@@ -923,11 +915,31 @@ static int link_relas(scf_elf_file_t* exec, char* afiles[], int nb_afiles, char*
                        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;
@@ -948,8 +960,9 @@ static int link_relas(scf_elf_file_t* exec, char* afiles[], int nb_afiles, char*
                                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");
@@ -957,17 +970,23 @@ static int link_relas(scf_elf_file_t* exec, char* afiles[], int nb_afiles, char*
                        }
                }
 
-               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++) {
@@ -1059,7 +1078,7 @@ int scf_elf_link(scf_vector_t* objs, scf_vector_t* afiles, scf_vector_t* sofiles
                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;
@@ -1083,10 +1102,19 @@ int scf_elf_link(scf_vector_t* objs, scf_vector_t* afiles, scf_vector_t* sofiles
                }
        }
 
+       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;
                }
index acd6fca8752721cf43efaa83ad2c30b357a971e5..b89500c4597c13fa54be3d2617b0122aff82b7b8 100644 (file)
@@ -38,6 +38,7 @@ typedef struct {
 
        scf_vector_t*      dyn_syms;
        scf_vector_t*      rela_plt;
+       scf_vector_t*      rela_dyn;
        scf_vector_t*      dyn_needs;
 
 } scf_elf_file_t;
index 513910a8f9efdc08a167d6be42277666b6edc09b..ea77acce7e4b0347da894cc97a8597a43d3779aa 100644 (file)
@@ -464,7 +464,8 @@ scf_elf_ops_t       elf_ops_naja =
        .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,
index 0193d5e9613d4e05925f8e9717505e508baf7d6c..fd725d706b7553c204f1d2b49dc41fcfd023b119 100644 (file)
@@ -722,8 +722,8 @@ int __naja_elf_post_dyn(elf_native_t* naja, uint64_t rx_base, uint64_t rw_base,
                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);
index a4187daecf35448b1967e2896fde6f82510f37e4..a196ffc5aa8025e6d5787bfd7967789249aa39a6 100644 (file)
@@ -78,6 +78,7 @@ int elf_add_sym(scf_elf_context_t* elf, const scf_elf_sym_t* sym, const char* sh
        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) {
@@ -613,24 +614,13 @@ int elf_add_dyn_need(scf_elf_context_t* elf, const char* soname)
        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;
        }
@@ -638,10 +628,41 @@ int elf_add_dyn_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela)
        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;
@@ -1055,4 +1076,3 @@ void elf_process_syms(elf_native_t* e, uint32_t cs_index)
                }
        }
 }
-
index e1273b7792ca4184d02541a37b6cb099892875dc..4de226c450f49fe2df55f0ec8305fd79963869f6 100644 (file)
@@ -34,8 +34,11 @@ typedef struct {
        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 {
@@ -56,18 +59,22 @@ 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;
 
@@ -85,7 +92,8 @@ int  elf_read_shstrtab(scf_elf_context_t* elf);
 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);
@@ -158,4 +166,3 @@ static inline void section_header(Elf64_Shdr* sh,
 }
 
 #endif
-
index deef2cbe2a997aba77426a724c1ba3851539c587..a703c9c2d0c0971e28beca28d537a1eda8f79c5d 100644 (file)
@@ -619,24 +619,13 @@ int elf32_add_dyn_need(scf_elf_context_t* elf, const char* soname)
        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;
        }
@@ -648,6 +637,38 @@ int elf32_add_dyn_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela)
        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;
@@ -1095,4 +1116,3 @@ void elf32_process_syms(elf_native_t* e, uint32_t cs_index)
                }
        }
 }
-
index ca53874786f76a128facbf5e328fa05566d30a5a..a3a001c9507e0c7dba617d308d4c2f6c08421305 100644 (file)
@@ -36,34 +36,39 @@ typedef struct {
 } 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;
 
@@ -79,7 +84,8 @@ int  elf32_read_shstrtab(scf_elf_context_t* elf);
 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);
@@ -151,4 +157,3 @@ static inline void section_header(Elf32_Shdr* sh,
 }
 
 #endif
-
index 147d1e04bc083af32664f95a796c3a203e7d20f4..132cddfc1fe30b234da304e4eb45f1658530e10d 100644 (file)
@@ -165,12 +165,12 @@ static int _x64_elf_link_sections(elf_native_t* x64, uint32_t cs_index, uint32_t
                                || 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));
 
@@ -228,7 +228,7 @@ static void _x64_elf_process_syms(elf_native_t* x64, uint32_t cs_index)
                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);
@@ -417,7 +417,22 @@ static int _x64_elf_write_exec(scf_elf_context_t* elf, const char* sysroot)
        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;
@@ -437,9 +452,7 @@ static int _x64_elf_write_exec(scf_elf_context_t* elf, const char* sysroot)
        elf_section_t* crela = NULL;
        elf_section_t* drela = NULL;
        elf_sym_t*     sym;
-
        int ret;
-       int i;
 
        _x64_elf_process_sections(x64, &section_offset, &cs, &ros, &ds, &crela, &drela);
 
@@ -498,7 +511,7 @@ static int _x64_elf_write_exec(scf_elf_context_t* elf, const char* sysroot)
        // 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);
@@ -514,11 +527,18 @@ static int _x64_elf_write_exec(scf_elf_context_t* elf, const char* sysroot)
        __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);
@@ -543,16 +563,29 @@ static int _x64_elf_write_dyn(scf_elf_context_t* elf, const char* sysroot)
                        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)
@@ -628,7 +661,7 @@ static int _x64_elf_write_dyn(scf_elf_context_t* elf, const char* sysroot)
        // 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);
@@ -636,10 +669,15 @@ static int _x64_elf_write_dyn(scf_elf_context_t* elf, const char* sysroot)
        __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);
 
@@ -664,7 +702,8 @@ scf_elf_ops_t       elf_ops_x64 =
        .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,
index 4639d2ce3364273d2a813487558d5a97a8e87457..396d3797de29ee8a07a7e03bfadef13e91a8fe7c 100644 (file)
@@ -170,7 +170,7 @@ static int _x64_elf_add_gnu_hash(elf_native_t* x64, elf_section_t** ps)
 #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
@@ -361,6 +361,87 @@ static int _x64_elf_add_got_plt(elf_native_t* x64, elf_section_t** ps)
        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;
@@ -639,6 +720,7 @@ int __x64_elf_add_dyn(elf_native_t* x64, const char* sysroot)
                ".dynsym",
                ".dynstr",
 //             ".gnu.version_r",
+               ".rela.dyn",
                ".rela.plt",
                ".plt",
 
@@ -647,6 +729,7 @@ int __x64_elf_add_dyn(elf_native_t* x64, const char* sysroot)
 
                ".dynamic",
                ".got.plt",
+               ".got",
                ".data",
        };
 
@@ -660,11 +743,13 @@ int __x64_elf_add_dyn(elf_native_t* x64, const char* sysroot)
 
 //     _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();
 
@@ -715,31 +800,41 @@ int __x64_elf_add_dyn(elf_native_t* x64, const char* sysroot)
 
        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;
@@ -747,6 +842,7 @@ int __x64_elf_add_dyn(elf_native_t* x64, const char* sysroot)
        str->data = NULL;
        str->len  = 0;
        str->capacity = 0;
+
        scf_string_free(str);
        str = NULL;
 
@@ -757,6 +853,8 @@ int __x64_elf_add_dyn(elf_native_t* x64, const char* sysroot)
        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]));
 
@@ -797,6 +895,7 @@ int __x64_so_add_dyn(elf_native_t* x64, const char* sysroot)
                ".gnu.hash",
                ".dynsym",
                ".dynstr",
+               ".rela.dyn",
                ".rela.plt",
                ".plt",
 
@@ -805,6 +904,7 @@ int __x64_so_add_dyn(elf_native_t* x64, const char* sysroot)
 
                ".dynamic",
                ".got.plt",
+               ".got",
                ".data",
        };
 
@@ -813,10 +913,12 @@ int __x64_so_add_dyn(elf_native_t* x64, const char* sysroot)
        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]));
 
@@ -830,7 +932,7 @@ int __x64_so_add_dyn(elf_native_t* x64, const char* sysroot)
        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);
@@ -907,21 +1009,27 @@ int __x64_so_add_dyn(elf_native_t* x64, const char* sysroot)
        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;
@@ -930,6 +1038,7 @@ int __x64_so_add_dyn(elf_native_t* x64, const char* sysroot)
        str->data = NULL;
        str->len  = 0;
        str->capacity = 0;
+
        scf_string_free(str);
        str = NULL;
 
@@ -940,6 +1049,9 @@ int __x64_so_add_dyn(elf_native_t* x64, const char* sysroot)
                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]));
@@ -963,6 +1075,7 @@ static void __x64_dynamic_update(elf_native_t* x64, uint64_t rx_base, uint64_t r
                        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;
@@ -1006,19 +1119,19 @@ static void __x64_plt_link(elf_native_t* x64, uint64_t rx_base, uint64_t rw_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;
@@ -1041,11 +1154,26 @@ static void __x64_plt_link(elf_native_t* x64, uint64_t rx_base, uint64_t rw_base
        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);
 
@@ -1064,15 +1192,88 @@ static void __x64_plt_link(elf_native_t* x64, uint64_t rx_base, uint64_t rw_base
                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));
        }
@@ -1088,6 +1289,9 @@ void __x64_elf_post_dyn(elf_native_t* x64, uint64_t rx_base, uint64_t rw_base, e
        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);
 }
index a4f61fef73fe30dab1eada50de8fb146bad4b610..4cc8c43e047a37febeb6689710bbc37702888c26 100644 (file)
@@ -1,4 +1,4 @@
-#include"stdio.h"
+#include<stdio.h>
 
 int main()
 {
diff --git a/examples/libmy1.c b/examples/libmy1.c
new file mode 100644 (file)
index 0000000..87eb357
--- /dev/null
@@ -0,0 +1,6 @@
+int g_i = 2;
+
+int f(int a)
+{
+       return g_i + a;
+}
index e6df4f965a6a5030403e05a6a23abeb60a4c72a3..e38964b7403cac0d870751ac7b36e9ac22a0db96 100644 (file)
@@ -1,13 +1,4 @@
-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)
 {
diff --git a/examples/test_libmy1.c b/examples/test_libmy1.c
new file mode 100644 (file)
index 0000000..005cb6e
--- /dev/null
@@ -0,0 +1,9 @@
+#include<stdio.h>
+
+extern int g_i;
+
+int main()
+{
+       printf("result: %d\n", g_i);
+       return 0;
+}
index 693aef63bcfe7bb99533289fadc5168802c89ca6..26dcbd317b12a5587615d60249ade89100006f64 100644 (file)
@@ -116,6 +116,7 @@ static scf_key_word_t  key_words[] =
 
        {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},
 };
 
index 2f75ea90a97f027a041d2e5ccfaf59fdd09851b1..0e8f2e1b6299a1e9541e0b6f09627c9eadf37f99 100644 (file)
@@ -286,7 +286,7 @@ int risc_select_free_reg(scf_register_t** preg, scf_3ac_code_t* c, scf_function_
        }
        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);
 
index 94b2b895a90cf71a6695e4f5b185265eec653274..421d334eae88b930022af736fe05db413b19fbc7 100644 (file)
@@ -242,9 +242,9 @@ static int _x64_function_finish(scf_function_t* f)
        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;
@@ -260,13 +260,13 @@ static int _x64_function_finish(scf_function_t* f)
        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;
@@ -381,7 +381,7 @@ static int _x64_argv_prepare(scf_graph_t* g, scf_basic_block_t* bb, scf_function
                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;
 
index 47e13c8e477bcb971edd698e310a3c2d500d06b0..42f4ec3a20148011af35ee8b76436078eb407cbe 100644 (file)
@@ -32,8 +32,9 @@ typedef int (*x64_inst_handler_pt)(scf_native_t* ctx, scf_3ac_code_t* c);
 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);
@@ -57,10 +58,10 @@ int x64_load_bb_colors (scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function
 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);
 
index e10d024ce4c4d74394b06a516d419fe6f8a96656..2abb52c3b29914e834732b8bdf27b127ac998223 100644 (file)
@@ -443,7 +443,7 @@ static int _x64_call_update_dsts(scf_3ac_code_t* c, scf_function_t* f, scf_regis
 
                        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);
                }
@@ -565,7 +565,7 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                        inst = x64_make_inst_E(call, r_pf);
                        X64_INST_ADD_CHECK(c, 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);
                }
@@ -649,7 +649,7 @@ static int _x64_inst_unary(scf_native_t* ctx, scf_3ac_code_t* c, int OpCode_type
        } 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);
        }
@@ -696,7 +696,7 @@ static int _x64_inst_unary_assign(scf_native_t* ctx, scf_3ac_code_t* c, int OpCo
        } 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);
        }
@@ -774,7 +774,7 @@ static int _x64_inst_neg_handler(scf_native_t* ctx, scf_3ac_code_t* c)
 
                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);
        }
@@ -829,7 +829,7 @@ static int _x64_inst_inc_float(scf_function_t* f, scf_3ac_code_t* c, int INC)
 
        X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
 
-       inst = x64_make_inst_M2G(&rela, OpCode, rs, NULL, v1);
+       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;
@@ -883,7 +883,7 @@ static int _x64_inst_inc(scf_native_t* ctx, scf_3ac_code_t* c, int INC, int ADD)
                } 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);
                }
@@ -902,7 +902,7 @@ static int _x64_inst_inc(scf_native_t* ctx, scf_3ac_code_t* c, int INC, int ADD)
                } 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);
                }
@@ -1175,7 +1175,7 @@ static int _x64_inst_address_of_handler(scf_native_t* ctx, scf_3ac_code_t* c)
        }
 
        lea  = x64_find_OpCode(SCF_X64_LEA, 8,8, SCF_X64_E2G);
-       inst = x64_make_inst_M2G(&rela, lea, rd, NULL, src->dag_node->var);
+       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;
@@ -1477,171 +1477,6 @@ static int _x64_inst_mod_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c)
        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)
@@ -1758,7 +1593,7 @@ static int _x64_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                        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);
                }
@@ -2442,14 +2277,9 @@ static x64_inst_handler_pt  x64_inst_handlers[] =
        [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,
index ec83545401e112a0bd2644bd736e19c2686c7b77..63a329cb3f3545fbf60aec3f823329f4e7bdc086 100644 (file)
@@ -44,7 +44,7 @@ static int _binary_assign_sib_float(scf_register_t* rb, scf_register_t* ri, int3
        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);
 
index 2230212601127d9f7800142ec53830cc9a6e0bbd..e4de880ef08b23164ba4bb89f3617c90ddcf813d 100644 (file)
@@ -70,7 +70,7 @@ static int _inst_cmp(scf_dag_node_t* src0, scf_dag_node_t* src1, scf_3ac_code_t*
                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);
        }
index 52e7b00a33dd0e89bef65bc44272ccdd14bf4756..117925a635fc896a93ecb84e0471829800b590ba 100644 (file)
@@ -127,7 +127,7 @@ static int _x64_inst_op2_imm(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_
 
                OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_I2E);
                if (OpCode) {
-                       inst = x64_make_inst_I2M(&rela, OpCode, dst->var, NULL, (uint8_t*)&src->var->data, src_size);
+                       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;
@@ -144,7 +144,7 @@ static int _x64_inst_op2_imm(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_
        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);
 
@@ -220,7 +220,7 @@ int x64_inst_op2(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_t* src, scf_
                        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);
        }
@@ -276,7 +276,7 @@ int x64_inst_movx(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, s
        } 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);
        }
@@ -339,7 +339,7 @@ int x64_inst_float_cast(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t
        } 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);
        }
index eebb869be8170ef81f456dbf1a7d3f07285ce682..9c55d3d31d0768316c35bf4e1f6846a4105a3e57 100644 (file)
@@ -64,7 +64,7 @@ int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c
                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);
        }
@@ -88,7 +88,7 @@ int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c
        } 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);
        }
@@ -109,7 +109,7 @@ int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c
                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);
        }
@@ -128,4 +128,3 @@ int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c
 
        return 0;
 }
-
index 7fcc0db6d4c80917a33e857068ecb85c33dbdf68..ca238412b88f04d1f43ae19174eb5dfd2dea1221 100644 (file)
@@ -19,7 +19,7 @@ static int _int_mul_src(scf_x64_OpCode_t* mul, scf_register_t* rh, scf_dag_node_
        } 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);
        }
@@ -119,14 +119,14 @@ int x64_inst_int_mul(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c
                                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);
 
@@ -142,11 +142,10 @@ int x64_inst_int_mul(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c
                        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;
 }
-
index 9444828b4e596adfcc28056ad12fa4f9bcfda5fc..ec438c2633e7672ead3e8eb3a21cad5393135832 100644 (file)
@@ -37,7 +37,7 @@ static int _shift_count(scf_dag_node_t* count, scf_3ac_code_t* c, scf_function_t
                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);
        }
@@ -87,12 +87,12 @@ static int _x64_shift(scf_native_t* ctx, scf_3ac_code_t* c, scf_dag_node_t* dst,
 
                if (0 != count->color) {
                        shift = x64_find_OpCode(OpCode_type, 1, dst->var->size, SCF_X64_G2E);
-                       inst  = x64_make_inst_M(&rela, shift, dst->var, NULL);
+                       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);
                }
index d475604f9a44248de8c373847e2f804e5f1ceca0..9d9d760762943dd64b2d2e61eecb559b862053c7 100644 (file)
@@ -325,6 +325,46 @@ scf_instruction_t* x64_make_inst_I2E(scf_x64_OpCode_t* OpCode, scf_register_t* r
        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;
@@ -365,7 +405,7 @@ scf_instruction_t* x64_make_inst_L(scf_rela_t** prela, scf_x64_OpCode_t* OpCode)
        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");
 
@@ -386,6 +426,16 @@ scf_instruction_t* x64_make_inst_M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode,
                } 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;
@@ -468,7 +518,7 @@ scf_instruction_t* x64_make_inst_I2L(scf_rela_t** prela, scf_x64_OpCode_t* OpCod
        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");
 
@@ -489,6 +539,16 @@ scf_instruction_t* x64_make_inst_I2M(scf_rela_t** prela, scf_x64_OpCode_t* OpCod
                } 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;
@@ -555,7 +615,7 @@ scf_instruction_t* x64_make_inst_G2L(scf_rela_t** prela, scf_x64_OpCode_t* OpCod
        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");
@@ -579,6 +639,16 @@ scf_instruction_t* x64_make_inst_G2M(scf_rela_t** prela, scf_x64_OpCode_t* OpCod
                } 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;
@@ -633,7 +703,7 @@ scf_instruction_t* x64_make_inst_L2G(scf_rela_t** prela, scf_x64_OpCode_t* OpCod
        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");
@@ -656,6 +726,16 @@ scf_instruction_t* x64_make_inst_M2G(scf_rela_t** prela, scf_x64_OpCode_t* OpCod
                } 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;
index e4e41a840126d88295248f2b2254427ba7a2e883..9f09af61c4e6e444761dcad48d5467685aeaccce 100644 (file)
@@ -356,7 +356,8 @@ static int _x64_peephole_cmp(scf_vector_t* save_insts, scf_vector_t* peep_insts,
                        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)
index 58f73447ec9ab906c62a59b496ff5e7f268da9af..baf144bc9c33d9b21f7fb4ac555107e1c4106474 100644 (file)
@@ -27,7 +27,7 @@ int x64_rcg_find_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* dn,
        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;
@@ -69,7 +69,7 @@ int _x64_rcg_make_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* dn
        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;
@@ -114,7 +114,7 @@ static int _x64_rcg_active_vars(scf_graph_t* g, scf_vector_t* active_vars)
                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;
 
@@ -126,13 +126,13 @@ static int _x64_rcg_active_vars(scf_graph_t* g, scf_vector_t* active_vars)
                        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;
                }
@@ -163,7 +163,7 @@ static int _x64_rcg_operands(scf_graph_t* g, scf_vector_t* operands)
                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;
 
@@ -175,14 +175,14 @@ static int _x64_rcg_operands(scf_graph_t* g, scf_vector_t* operands)
                        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;
                }
@@ -208,14 +208,14 @@ static int _x64_rcg_to_active_vars(scf_graph_t* g, scf_graph_node_t* gn0, scf_ve
                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;
        }
@@ -223,8 +223,7 @@ static int _x64_rcg_to_active_vars(scf_graph_t* g, scf_graph_node_t* gn0, scf_ve
        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;
@@ -235,7 +234,7 @@ static int _x64_rcg_make(scf_3ac_code_t* c, scf_graph_t* g, scf_dag_node_t* dn,
        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;
@@ -256,7 +255,7 @@ static int _x64_rcg_make(scf_3ac_code_t* c, scf_graph_t* g, scf_dag_node_t* dn,
        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);
@@ -265,7 +264,7 @@ static int _x64_rcg_make2(scf_3ac_code_t* c, scf_dag_node_t* dn, scf_register_t*
        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)
@@ -328,7 +327,7 @@ 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;
@@ -355,7 +354,7 @@ static int _x64_rcg_call(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
                        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;
@@ -368,7 +367,7 @@ static int _x64_rcg_call(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
 
        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;
@@ -381,7 +380,7 @@ static int _x64_rcg_call(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
 
                        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;
@@ -389,7 +388,7 @@ static int _x64_rcg_call(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
 
                        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;
                }
@@ -418,115 +417,115 @@ static int _x64_rcg_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_gr
 {
        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)
@@ -548,7 +547,7 @@ static int _x64_rcg_mul_div_mod(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_
        }
 
        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;
@@ -567,12 +566,12 @@ static int _x64_rcg_mul_div_mod(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_
                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:
@@ -582,11 +581,11 @@ static int _x64_rcg_mul_div_mod(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_
        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;
 
@@ -628,22 +627,22 @@ static int _x64_rcg_add_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_
 {
        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)
@@ -655,7 +654,7 @@ 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;
@@ -667,26 +666,26 @@ static int _x64_rcg_shift(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
        }
 
        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;
        }
@@ -696,11 +695,11 @@ static int _x64_rcg_shift(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
                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;
        }
@@ -738,49 +737,40 @@ static int _x64_rcg_bit_and_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_gr
 {
        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) \
@@ -788,10 +778,10 @@ static int _x64_rcg_##setcc##_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_
 { \
        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)
@@ -805,10 +795,10 @@ static int _x64_rcg_##op##_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_gra
 { \
        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)
@@ -821,33 +811,33 @@ static int _x64_rcg_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_gra
 {
        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)
@@ -879,40 +869,22 @@ static int _x64_rcg_and_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf
 {
        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)
@@ -924,11 +896,11 @@ static int _x64_rcg_return_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_gra
        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;
 
@@ -954,7 +926,7 @@ static int _x64_rcg_return_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_gra
                } 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;
        }
@@ -971,11 +943,11 @@ static int _x64_rcg_memset_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_gra
        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;
 
@@ -1000,7 +972,7 @@ static int _x64_rcg_memset_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_gra
                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;
        }
@@ -1033,17 +1005,30 @@ X64_RCG_JCC(jbe)
 
 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;
@@ -1056,24 +1041,24 @@ static int _x64_rcg_end_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_
 #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)
@@ -1100,31 +1085,31 @@ X64_RCG_SHIFT_ASSIGN(shr)
 #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)
@@ -1134,37 +1119,37 @@ static int _x64_rcg_##name##_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_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##_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)
@@ -1173,20 +1158,20 @@ static int _x64_rcg_address_of_array_index_handler(scf_native_t* ctx, scf_3ac_co
 {
        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)
@@ -1200,28 +1185,28 @@ static int _x64_rcg_pop_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_gr
 
 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] =
@@ -1282,14 +1267,10 @@ 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,
index d017fabc68f4913b39d5ed423c920c1d15186aa0..5988fd31c1dd41e219536a908b80837837f54a03 100644 (file)
@@ -413,7 +413,7 @@ int x64_save_var2(scf_dag_node_t* dn, scf_register_t* r, scf_3ac_code_t* c, scf_
                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);
 
@@ -570,7 +570,7 @@ static scf_register_t* _x64_reg_cached_min_vars(scf_register_t** regs, int nb_re
        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;
@@ -578,16 +578,20 @@ scf_register_t* x64_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c)
        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;
@@ -694,6 +698,37 @@ scf_register_t* x64_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c)
        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;
@@ -717,16 +752,18 @@ int x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf
 
                lea  = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G);
 
-               inst = x64_make_inst_M2G(&rela, lea, r, NULL, v);
+               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);
 
@@ -739,7 +776,7 @@ int x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf
                        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 {
@@ -825,7 +862,7 @@ int x64_load_reg(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_f
                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);
 
@@ -854,7 +891,7 @@ int x64_select_reg(scf_register_t** preg, scf_dag_node_t* dn, scf_3ac_code_t* c,
                }
 #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;
@@ -991,7 +1028,7 @@ int x64_array_index_reg(x64_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* in
 
        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) {
index 23bf2d1bc213fef8887ca6cf8c6fb79ec1bd97e6..346a98a571e53410cf5101e79de9fee0fa625e5e 100644 (file)
@@ -101,7 +101,7 @@ scf_vector_t*       x64_register_colors();
 
 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);
 
@@ -127,7 +127,8 @@ int                 x64_reg_used  (scf_register_t* r, scf_dag_node_t* dn);
 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);
 
index 1f588d0902d98e431e3ec1a52ea59f72d838bd67..8cba095cd8873973cdd841d9a8170fd749bd3e84 100644 (file)
@@ -123,7 +123,6 @@ CFILES += ../core/scf_optimizer_dominators_reverse.c
 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
 
index 041367f6466fcba72f38655c017db897c0d907aa..e2f46b16db0efcbe5396f1f87c18bda134bbfb35 100644 (file)
@@ -45,15 +45,18 @@ static char* __arm32_sofiles[] =
 
 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");
@@ -309,8 +312,8 @@ int main(int argc, char* argv[])
                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";
@@ -319,6 +322,7 @@ int main(int argc, char* argv[])
        int   _3ac      = 0;
        int   _parse    = 0;
        int   dyn       = 0;
+       int   pic       = 0;
        int   c_version = SCF_C99;
 
        int i;
@@ -329,6 +333,8 @@ int main(int argc, char* argv[])
                        goto error;
        }
 
+       int n_srcs = srcs->size;
+
        for (i = 1; i < argc; i++) {
 
                if ('-' == argv[i][0]) {
@@ -338,6 +344,12 @@ int main(int argc, char* argv[])
                                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;
@@ -352,14 +364,6 @@ int main(int argc, char* argv[])
                                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]) {
@@ -387,7 +391,13 @@ int main(int argc, char* argv[])
                                                        || !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;
                                }
 
@@ -528,7 +538,7 @@ int main(int argc, char* argv[])
                        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);
@@ -572,7 +582,7 @@ int main(int argc, char* argv[])
                }
 
                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;
@@ -589,8 +599,8 @@ int main(int argc, char* argv[])
                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);
@@ -619,7 +629,7 @@ int main(int argc, char* argv[])
                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;
@@ -653,8 +663,8 @@ 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);
 
@@ -665,8 +675,8 @@ error:
        }
 
        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);
                }
index 03d1bbbd5bba19e2f915eeb610dc54a4a5fb852d..a9c4c1ee0d8cebebdd2522e8e9cd2fa0e88c7678 100644 (file)
@@ -166,7 +166,7 @@ static int _container_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        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) {
index 47b07727a893c56635b476925116a75c2be4acb7..49a2187bb278a0ac4b799768c1fae5df6768348f 100644 (file)
@@ -413,10 +413,8 @@ static int _expr_action_rp_cast(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                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;
@@ -904,6 +902,7 @@ static int _dfa_init_syntax_expr(scf_dfa_t* dfa)
        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);
@@ -941,6 +940,9 @@ static int _dfa_init_syntax_expr(scf_dfa_t* dfa)
        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);
index 01d08bf2341852d9c60d51b93da4bcff32efdecc..48d9ae9da0aeef175b455d3ad11d0faa03328bc4 100644 (file)
@@ -22,8 +22,11 @@ static int _identity_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void*
        }
 
        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;
 }
index aec0be79125e19fe624562e1db5a9d3d51dad8ef..bdfb92ea60770073be6d03ab7d875495ee019ec0 100644 (file)
@@ -82,7 +82,7 @@ static int _sizeof_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        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) {
index b38ea2e0330485440eacf4846e2363304b1a47ca..5e569699ad806bad1515d13772de6a877f0bbaf5 100644 (file)
@@ -228,6 +228,13 @@ static inline int scf_dfa_is_va_arg(scf_dfa_t* dfa, void* word)
        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;
index 918690cb96637129b2667adcc66a1991dea0aa69..06e718a54ce47f9594ef1d538c20fa20b90fdf23 100644 (file)
@@ -31,6 +31,14 @@ static int _va_arg_action_start(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        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;
@@ -114,7 +122,7 @@ static int _va_arg_action_ap(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                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;
        }
@@ -135,6 +143,9 @@ static int _va_arg_action_ap(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        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 {
@@ -242,7 +253,6 @@ static int _va_arg_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                }
 
                if (!id->type) {
-
                        if (_type_find_type(dfa, id) < 0) {
                                scf_loge("\n");
                                return SCF_DFA_ERROR;
@@ -264,6 +274,7 @@ static int _va_arg_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
                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;
@@ -271,6 +282,7 @@ static int _va_arg_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        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;
@@ -288,6 +300,7 @@ static int _dfa_init_module_va_arg(scf_dfa_t* dfa)
 
        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);
@@ -313,6 +326,7 @@ static int _dfa_init_syntax_va_arg(scf_dfa_t* dfa)
 
        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);
@@ -326,6 +340,7 @@ static int _dfa_init_syntax_va_arg(scf_dfa_t* dfa)
        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);
@@ -333,9 +348,15 @@ static int _dfa_init_syntax_va_arg(scf_dfa_t* dfa)
        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);
 
index 8a8a94818c06f04a10560702279dafc177c6a616..8e8c0834f409b606bec4b4309fd86e9fc2bf0b30 100644 (file)
@@ -164,7 +164,7 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d)
                        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;
@@ -248,239 +248,6 @@ static int _var_init_expr(scf_dfa_t* dfa, dfa_data_t* d, scf_vector_t* words, in
        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;
@@ -517,7 +284,6 @@ static int _var_add_typedef(scf_ast_t* ast, dfa_data_t* d)
 
                assert(0 == scf_vector_del(ast->current_block->scope->vars, d->current_var));
 
-               d->current_var->vla_flag = 0;
                d->current_var = NULL;
        }
 
@@ -548,12 +314,6 @@ static int _var_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
                        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)
@@ -598,12 +358,6 @@ static int _var_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data
 
                        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) {
@@ -653,12 +407,6 @@ static int _var_action_assign(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                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;
@@ -751,7 +499,7 @@ static int _var_action_ls(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                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);
@@ -785,23 +533,9 @@ static int _var_action_rs(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        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;
 
index 41ff57beacbcd486e780cb2fd3f92b622a5783ef..cfa654c6043c65757d8d749fd16630809a6bea85 100644 (file)
@@ -367,13 +367,6 @@ static int _scf_op_const_default(scf_ast_t* ast, scf_node_t** nodes, int nb_node
        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);
@@ -1017,8 +1010,6 @@ scf_operator_handler_pt  const_operator_handlers[SCF_N_OPS] =
        [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)
index dcb7c5a45e71db7cac2219fec4a913966da89200..9918ff6d0caf49a3465223e6fc11b1c2f449b1c0 100644 (file)
@@ -886,7 +886,7 @@ static int _scf_op_semantic_pointer(scf_ast_t* ast, scf_node_t** nodes, int nb_n
 
        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;
@@ -933,7 +933,7 @@ static int _scf_op_semantic_array_index(scf_ast_t* ast, scf_node_t** nodes, int
        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;
                }
@@ -947,16 +947,18 @@ static int _scf_op_semantic_array_index(scf_ast_t* ast, scf_node_t** nodes, int
                                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) {
@@ -980,19 +982,8 @@ static int _scf_op_semantic_array_index(scf_ast_t* ast, scf_node_t** nodes, int
        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;
@@ -1446,14 +1437,6 @@ static int _scf_op_semantic_default(scf_ast_t* ast, scf_node_t** nodes, int nb_n
        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);
@@ -3212,8 +3195,6 @@ scf_operator_handler_pt  semantic_operator_handlers[SCF_N_OPS] =
        [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)
index 38a3836d6a89103fefa2e69eba6ec0eddd2bbaa0..20e6636b463425cb8939ad590ad120f62dd66c74 100644 (file)
@@ -1356,9 +1356,9 @@ static int _fill_data(scf_parse_t* parse, scf_variable_t* v, scf_string_t* data,
        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);
@@ -1875,13 +1875,18 @@ static int _scf_parse_add_text_relas(scf_parse_t* parse, scf_elf_context_t* elf,
                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;
@@ -2013,7 +2018,7 @@ int scf_eda_write_cpk(scf_parse_t* parse, const char* out, scf_vector_t* functio
        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;
@@ -2033,7 +2038,9 @@ int scf_parse_native_functions(scf_parse_t* parse, scf_vector_t* functions, cons
 
                if (f->native_flag)
                        continue;
+
                f->native_flag = 1;
+               f->pic_flag    = pic_flag;
 
                ret = scf_native_select_inst(native, f);
                if (ret < 0) {
@@ -2267,7 +2274,7 @@ int scf_parse_fill_code(scf_parse_t* parse, scf_vector_t* functions, scf_vector_
        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)
@@ -2290,7 +2297,7 @@ int scf_parse_compile(scf_parse_t* parse, const char* arch, int _3ac)
        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;
index 2dbbcc5ab5209a7d1e34052cf091f1bf6cb8a73b..cff60ce5d3e484f9eed66ba1542c6b369fb0a9f9 100644 (file)
@@ -100,6 +100,7 @@ struct dfa_data_s {
 
        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;
@@ -126,7 +127,7 @@ int scf_parse_open (scf_parse_t** pparse, const scf_vector_t* inc_paths, int c_v
 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);
diff --git a/sysroot/include/stdarg.h b/sysroot/include/stdarg.h
new file mode 100644 (file)
index 0000000..3256f80
--- /dev/null
@@ -0,0 +1,21 @@
+#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
index 2df9e0344a28a9afbde7d4bc9f566a6a706df137..dbd839b186a0fa0d4e53fd79c629488f7d05c64f 100644 (file)
@@ -1,20 +1,18 @@
 .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