From d475faf4ba88713dbfea3ea578eb6145512591aa Mon Sep 17 00:00:00 2001 From: gbeauche <> Date: Sat, 28 Jan 2006 22:03:31 +0000 Subject: [PATCH] Copy constants to 32-bit addressable data pool. This fixes -pie builds on x86_64: program resides above 32-bit barrier and JIT generated code wants (knowingly) to access globals directly. --- .../src/kpx_cpu/src/cpu/jit/basic-dyngen.cpp | 2 +- .../src/kpx_cpu/src/cpu/jit/basic-dyngen.hpp | 2 +- SheepShaver/src/kpx_cpu/src/cpu/jit/dyngen.c | 38 ++++++++------- .../src/kpx_cpu/src/cpu/jit/jit-cache.cpp | 47 ++++++++++++++++++- .../src/kpx_cpu/src/cpu/jit/jit-cache.hpp | 11 +++++ .../src/kpx_cpu/src/cpu/ppc/ppc-dyngen.cpp | 2 +- .../src/kpx_cpu/src/cpu/ppc/ppc-dyngen.hpp | 2 +- 7 files changed, 81 insertions(+), 23 deletions(-) diff --git a/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.cpp b/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.cpp index 0560d462..0ac0883b 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.cpp @@ -25,7 +25,7 @@ int __op_param1, __op_param2, __op_param3; int __op_jmp0, __op_jmp1; #define DYNGEN_IMPL 1 -#define DEFINE_GEN(NAME,ARGS) void basic_dyngen::NAME ARGS +#define DEFINE_GEN(NAME,RET,ARGS) RET basic_dyngen::NAME ARGS #include "basic-dyngen-ops.hpp" basic_dyngen::basic_dyngen(dyngen_cpu_base cpu, int cache_size) diff --git a/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.hpp b/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.hpp index c858a3e3..29684f33 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.hpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.hpp @@ -69,7 +69,7 @@ class basic_dyngen // Generic code generators # define DEFINE_CST(NAME,VALUE) static const unsigned long NAME = VALUE; -# define DEFINE_GEN(NAME,ARGS) void NAME ARGS; +# define DEFINE_GEN(NAME,RET,ARGS) RET NAME ARGS; # include "basic-dyngen-ops.hpp" public: diff --git a/SheepShaver/src/kpx_cpu/src/cpu/jit/dyngen.c b/SheepShaver/src/kpx_cpu/src/cpu/jit/dyngen.c index f1097fd0..652653ce 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/jit/dyngen.c +++ b/SheepShaver/src/kpx_cpu/src/cpu/jit/dyngen.c @@ -546,7 +546,7 @@ static char *gen_dot_prefix(const char *sym_name) { static char name[256]; assert(sym_name[0] == '.'); - snprintf(name, sizeof(name), "dg_dot_%s", sym_name + 1); + snprintf(name, sizeof(name), "dot_%s", sym_name + 1); return name; } @@ -861,23 +861,25 @@ int load_object(const char *filename, FILE *outfile) name = get_sym_name(sym); /* emit local symbols */ if (strstart(name, ".LC", NULL)) { - if (sym->st_shndx == (rodata_cst16_sec - shdr)) { - fprintf(outfile, "#ifdef DYNGEN_IMPL\n"); - print_data(outfile, gen_dot_prefix(name), rodata_cst16 + sym->st_value, 16); - fprintf(outfile, "#endif\n"); - } - else if (sym->st_shndx == (rodata_cst8_sec - shdr)) { - fprintf(outfile, "#ifdef DYNGEN_IMPL\n"); - print_data(outfile, gen_dot_prefix(name), rodata_cst8 + sym->st_value, 8); - fprintf(outfile, "#endif\n"); - } - else if (sym->st_shndx == (rodata_cst4_sec - shdr)) { - fprintf(outfile, "#ifdef DYNGEN_IMPL\n"); - print_data(outfile, gen_dot_prefix(name), rodata_cst4 + sym->st_value, 4); - fprintf(outfile, "#endif\n"); - } + const char *dot_name = gen_dot_prefix(name); + fprintf(outfile, "DEFINE_GEN(gen_const_%s,uint8 *,(void))\n", dot_name); + fprintf(outfile, "#ifdef DYNGEN_IMPL\n"); + fprintf(outfile, "{\n"); + int dot_size = 0; + if (sym->st_shndx == (rodata_cst16_sec - shdr)) + print_data(outfile, dot_name, rodata_cst16 + sym->st_value, (dot_size = 16)); + else if (sym->st_shndx == (rodata_cst8_sec - shdr)) + print_data(outfile, dot_name, rodata_cst8 + sym->st_value, (dot_size = 8)); + else if (sym->st_shndx == (rodata_cst4_sec - shdr)) + print_data(outfile, dot_name, rodata_cst4 + sym->st_value, (dot_size = 4)); else error("invalid section for local data %s (%x)\n", name, sym->st_shndx); + fprintf(outfile, " static uint8 *data_p = NULL;\n"); + fprintf(outfile, " if (data_p == NULL)\n"); + fprintf(outfile, " data_p = copy_data(%s, %d);\n", dot_name, dot_size); + fprintf(outfile, " return data_p;\n"); + fprintf(outfile, "}\n"); + fprintf(outfile, "#endif\n"); } } } @@ -1899,7 +1901,7 @@ void gen_code(const char *name, const char *demangled_name, if (prefix && strstr(func_name, prefix) == func_name) func_name += strlen(prefix); - fprintf(outfile, "DEFINE_GEN(gen_%s,(", func_name); + fprintf(outfile, "DEFINE_GEN(gen_%s,void,(", func_name); if (nb_args == 0) { fprintf(outfile, "void"); } else { @@ -2181,7 +2183,7 @@ void gen_code(const char *name, const char *demangled_name, if (strstart(sym_name, "__op_param", &p)) snprintf(name, sizeof(name), "param%s", p); else if (strstart(sym_name, ".LC", NULL)) - snprintf(name, sizeof(name), "(long)(%s)", gen_dot_prefix(sym_name)); + snprintf(name, sizeof(name), "(long)(gen_const_%s())", gen_dot_prefix(sym_name)); else snprintf(name, sizeof(name), "(long)(&%s)", sym_name); type = ELF32_R_TYPE(rel->r_info); diff --git a/SheepShaver/src/kpx_cpu/src/cpu/jit/jit-cache.cpp b/SheepShaver/src/kpx_cpu/src/cpu/jit/jit-cache.cpp index 476d7bee..031d7546 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/jit/jit-cache.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/jit/jit-cache.cpp @@ -47,7 +47,7 @@ static uint8 *g_translation_cache_end_p; #endif basic_jit_cache::basic_jit_cache(int init_cache_size) - : tcode_start(NULL), code_start(NULL), code_p(NULL), code_end(NULL) + : tcode_start(NULL), code_start(NULL), code_p(NULL), code_end(NULL), data(NULL) { init_translation_cache(init_cache_size); } @@ -55,6 +55,15 @@ basic_jit_cache::basic_jit_cache(int init_cache_size) basic_jit_cache::~basic_jit_cache() { kill_translation_cache(); + + // Release data pool + data_chunk_t *p = data; + while (p) { + data_chunk_t *d = p; + p = p->next; + D(bug("basic_jit_cache: Release data pool %p (%d KB)\n", d, d->size / 1024)); + vm_release(d, d->size); + } } bool @@ -121,3 +130,39 @@ basic_jit_cache::kill_translation_cache() vm_release(tcode_start, cache_size); } } + +uint8 * +basic_jit_cache::copy_data(const uint8 *block, uint32 size) +{ + const int ALIGN = 16; + uint8 *ptr; + + if (data && (data->offs + size) < data->size) + ptr = (uint8 *)data + data->offs; + else { + // No free space left, allocate a new chunk + uint32 to_alloc = sizeof(*data) + size + ALIGN; + uint32 page_size = vm_get_page_size(); + to_alloc = (to_alloc + page_size - 1) & -page_size; + + D(bug("basic_jit_cache: Allocate data pool (%d KB)\n", to_alloc / 1024)); + ptr = (uint8 *)vm_acquire(to_alloc, VM_MAP_PRIVATE | VM_MAP_32BIT); + if (ptr == VM_MAP_FAILED) { + fprintf(stderr, "FATAL: Could not allocate data pool!\n"); + abort(); + } + + data_chunk_t *dcp = (data_chunk_t *)ptr; + dcp->size = to_alloc; + dcp->offs = (sizeof(*data) + ALIGN - 1) & -ALIGN; + dcp->next = data; + data = dcp; + + ptr += dcp->offs; + } + + memcpy(ptr, block, size); + data->offs += (size + ALIGN - 1) & -ALIGN; + D(bug("basic_jit_cache: DATA %p, %d bytes [data=%p, offs=%u]\n", ptr, size, data, data->offs)); + return ptr; +} diff --git a/SheepShaver/src/kpx_cpu/src/cpu/jit/jit-cache.hpp b/SheepShaver/src/kpx_cpu/src/cpu/jit/jit-cache.hpp index 5219bda5..5ee6db87 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/jit/jit-cache.hpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/jit/jit-cache.hpp @@ -37,6 +37,14 @@ class basic_jit_cache uint8 *code_p; uint8 *code_end; + // Data pool (32-bit addressable) + struct data_chunk_t { + uint32 size; + uint32 offs; + data_chunk_t *next; + }; + data_chunk_t *data; + protected: // Initialize translation cache @@ -72,6 +80,9 @@ public: void emit_ptr(uintptr v) { emit_generic(v); } void copy_block(const uint8 *block, uint32 size); void emit_block(const uint8 *block, uint32 size); + + // Emit data to constant pool + uint8 *copy_data(const uint8 *block, uint32 size); }; inline void diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-dyngen.cpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-dyngen.cpp index 9ff6d048..c451781f 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-dyngen.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-dyngen.cpp @@ -27,7 +27,7 @@ #include #define DYNGEN_IMPL 1 -#define DEFINE_GEN(NAME,ARGS) void powerpc_dyngen::NAME ARGS +#define DEFINE_GEN(NAME,RET,ARGS) RET powerpc_dyngen::NAME ARGS #include "ppc-dyngen-ops.hpp" diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-dyngen.hpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-dyngen.hpp index 14c1df51..305de337 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-dyngen.hpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-dyngen.hpp @@ -34,7 +34,7 @@ class powerpc_dyngen { // Code generators for PowerPC synthetic instructions #ifndef NO_DEFINE_ALIAS -# define DEFINE_GEN(NAME,ARGS) void NAME ARGS; +# define DEFINE_GEN(NAME,RET,ARGS) RET NAME ARGS; # include "ppc-dyngen-ops.hpp" #endif