From 11c489fe748391908d869a4609e22c32fb37d0b5 Mon Sep 17 00:00:00 2001 From: Aleksey Demakov Date: Sun, 26 Nov 2006 20:42:01 +0000 Subject: [PATCH] add POSITION_INDEPENDENT context option --- ChangeLog | 9 +++++++ include/jit/jit-context.h | 1 + jit/jit-context.c | 6 +++++ jit/jit-function.c | 5 ++++ jit/jit-internal.h | 3 +++ jit/jit-rules-x86.ins | 56 ++++++++++++++++++++++++++++----------- 6 files changed, 64 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index e92ee7c..33c63f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-11-27 Aleksey Demakov + + * include/jit/jit-context.h: add JIT_OPTION_POSITION_INDEPENDENT + option. + * jit/jit-internal.h (struct _jit_builder): add position_independent + field. + * jit/jit-function.c (_jit_function_ensure_builder): initialize + position_independent field. + 2006-11-26 Kirill Kononenko * jit/jit-rules-x86.ins: if JIT_USE_SIGNALS is defined do not emit diff --git a/include/jit/jit-context.h b/include/jit/jit-context.h index 33ff8ed..03159b6 100644 --- a/include/jit/jit-context.h +++ b/include/jit/jit-context.h @@ -49,6 +49,7 @@ void jit_context_free_meta(jit_context_t context, int type) JIT_NOTHROW; #define JIT_OPTION_CACHE_PAGE_SIZE 10001 #define JIT_OPTION_PRE_COMPILE 10002 #define JIT_OPTION_DONT_FOLD 10003 +#define JIT_OPTION_POSITION_INDEPENDENT 10004 #ifdef __cplusplus }; diff --git a/jit/jit-context.c b/jit/jit-context.c index 4856d11..d80ed06 100644 --- a/jit/jit-context.c +++ b/jit/jit-context.c @@ -213,6 +213,12 @@ int jit_context_set_meta * A numeric option that disables constant folding when it is set to a * non-zero value. This is useful for debugging, as it forces @code{libjit} to * always execute constant expressions at run time, instead of at compile time. + * + * @vindex JIT_OPTION_POSITION_INDEPENDENT + * @item JIT_OPTION_POSITION_INDEPENDENT + * A numeric option that forces generation of position-independent code (PIC) + * if it is set to a non-zero value. This may be mainly useful for pre-compiled + * contexts. * @end table * * Metadata type values of 10000 or greater are reserved for internal use. diff --git a/jit/jit-function.c b/jit/jit-function.c index fd2896a..4f618fd 100644 --- a/jit/jit-function.c +++ b/jit/jit-function.c @@ -180,6 +180,11 @@ int _jit_function_ensure_builder(jit_function_t func) return 0; } + /* Cache the value of the JIT_OPTION_POSITION_INDEPENDENT option */ + func->builder->position_independent + = jit_context_get_meta_numeric( + func->context, JIT_OPTION_POSITION_INDEPENDENT); + /* Initialize the function builder */ jit_memory_pool_init(&(func->builder->value_pool), struct _jit_value); jit_memory_pool_init(&(func->builder->insn_pool), struct _jit_insn); diff --git a/jit/jit-internal.h b/jit/jit-internal.h index 4ad7183..34f6f5e 100644 --- a/jit/jit-internal.h +++ b/jit/jit-internal.h @@ -322,6 +322,9 @@ struct _jit_builder /* Flag that indicates that the current function contains a tail call */ int has_tail_call : 1; + /* Generate position-independent code */ + int position_independent : 1; + /* List of all instructions in this function */ jit_insn_t *insns; int num_insns; diff --git a/jit/jit-rules-x86.ins b/jit/jit-rules-x86.ins index 3a3bf47..54257be 100644 --- a/jit/jit-rules-x86.ins +++ b/jit/jit-rules-x86.ins @@ -1700,15 +1700,23 @@ JIT_OP_CALL_FILTER_RETURN: manual JIT_OP_ADDRESS_OF_LABEL: [=reg] -> { block = jit_block_from_label(func, (jit_label_t)(insn->value1)); - if(block->address) + if(func->builder->position_independent) { - x86_mov_reg_imm(inst, $1, block->address); + /* TODO */ + TODO(); } else { - /* Output a placeholder and record on the block's fixup list */ - x86_mov_reg_imm(inst, $1, (int)(block->fixup_absolute_list)); - block->fixup_absolute_list = (void *)(inst - 4); + if(block->address) + { + x86_mov_reg_imm(inst, $1, block->address); + } + else + { + /* Output a placeholder and record on the block's fixup list */ + x86_mov_reg_imm(inst, $1, (int)(block->fixup_absolute_list)); + block->fixup_absolute_list = (void *)(inst - 4); + } } } @@ -2395,15 +2403,23 @@ JIT_OP_JUMP_TABLE: ternary patch_fall_through = inst; x86_branch32(inst, X86_CC_GE, 0, 1); - patch_jump_table = inst; - x86_jump_memindex(inst, X86_NOBASEREG, 0, $1, 2); - while(((jit_nint) inst & (sizeof(void*) - 1)) != 0) + if(func->builder->position_independent) { - x86_nop(inst); + /* TODO */ + TODO(); } + else + { + patch_jump_table = inst; + x86_jump_memindex(inst, X86_NOBASEREG, 0, $1, 2); + while(((jit_nint) inst & (sizeof(void*) - 1)) != 0) + { + x86_nop(inst); + } - // displacement goes after opcode. ModR/M, and SIB bytes - *((void **)(patch_jump_table + 3)) = inst; + // displacement goes after opcode. ModR/M, and SIB bytes + *((void **)(patch_jump_table + 3)) = inst; + } for(index = 0; index < num_labels; index++) { @@ -2413,15 +2429,23 @@ JIT_OP_JUMP_TABLE: ternary return; } - if(block->address) + if(func->builder->position_independent) { - x86_imm_emit32(inst, block->address); + /* TODO */ + TODO(); } else { - /* Output a placeholder and record on the block's fixup list */ - x86_imm_emit32(inst, (int)(block->fixup_absolute_list)); - block->fixup_absolute_list = (void *)(inst - 4); + if(block->address) + { + x86_imm_emit32(inst, block->address); + } + else + { + /* Output a placeholder and record on the block's fixup list */ + x86_imm_emit32(inst, (int)(block->fixup_absolute_list)); + block->fixup_absolute_list = (void *)(inst - 4); + } } } -- 2.47.3