From 741841d863be133d4fba91933fdd83dec7a83112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gl=C3=B6ckner?= Date: Fri, 14 May 2010 13:07:59 +0200 Subject: [PATCH] ARM: allow jumps > 32MB on -run This is needed to reach tinycc's PLT from the compiled program. --- tcc.h | 2 +- tccelf.c | 16 ++++++++++++++++ tccrun.c | 4 ++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/tcc.h b/tcc.h index 313214c..29953a6 100644 --- a/tcc.h +++ b/tcc.h @@ -547,7 +547,7 @@ struct TCCState { #endif #ifndef TCC_TARGET_PE -#ifdef TCC_TARGET_X86_64 +#if defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM /* write PLT and GOT here */ char *runtime_plt_and_got; unsigned int runtime_plt_and_got_offset; diff --git a/tccelf.c b/tccelf.c index 4ea8dc8..037615a 100644 --- a/tccelf.c +++ b/tccelf.c @@ -504,6 +504,17 @@ static uplong add_got_table(TCCState *s1, uplong val) *p = val; return (uplong)p; } +#elif defined TCC_TARGET_ARM +#define JMP_TABLE_ENTRY_SIZE 8 +static int add_jmp_table(TCCState *s1, int val) +{ + uint32_t *p = (uint32_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset); + s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE; + /* ldr pc, [pc, #-4] */ + p[0] = 0xE51FF004; + p[1] = val; + return (int)p; +} #endif #endif @@ -611,6 +622,11 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) x -= 0x1000000; x *= 4; x += val - addr; +#ifndef TCC_TARGET_PE + if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000) + if (s1->output_type == TCC_OUTPUT_MEMORY) + x += add_jmp_table(s1, val) - val; /* add veneer */ +#endif if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000) error("can't relocate value at %x",addr); x >>= 2; diff --git a/tccrun.c b/tccrun.c index f04412c..264b8a7 100644 --- a/tccrun.c +++ b/tccrun.c @@ -150,7 +150,7 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr) if (s1->nb_errors) return -1; -#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE +#if (defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM) && !defined TCC_TARGET_PE s1->runtime_plt_and_got_offset = 0; s1->runtime_plt_and_got = (char *)(mem + offset); /* double the size of the buffer for got and plt entries @@ -184,7 +184,7 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr) set_pages_executable(ptr, length); } -#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE +#if (defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM) && !defined TCC_TARGET_PE set_pages_executable(s1->runtime_plt_and_got, s1->runtime_plt_and_got_offset); #endif