aboutsummaryrefslogtreecommitdiff
path: root/tccelf.c
diff options
context:
space:
mode:
authorgrischka <grischka>2013-02-04 16:08:06 +0100
committergrischka <grischka>2013-02-04 16:24:59 +0100
commit82bcbd027f100d7601c6139e93e1f69a9cc46244 (patch)
tree39d361cc3ae5df94710082778852bf427d101d10 /tccelf.c
parent3186455599043938d765b4cc9b92af5fde7241cd (diff)
downloadtinycc-82bcbd027f100d7601c6139e93e1f69a9cc46244.tar.gz
tinycc-82bcbd027f100d7601c6139e93e1f69a9cc46244.tar.bz2
portability: fix void* <-> target address conversion confusion
- #define addr_t as ElfW(Addr) - replace uplong by addr_t - #define TCC_HAS_RUNTIME_PLTGOT and use it
Diffstat (limited to 'tccelf.c')
-rw-r--r--tccelf.c77
1 files changed, 40 insertions, 37 deletions
diff --git a/tccelf.c b/tccelf.c
index 5fea23a..ced61fc 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -84,7 +84,7 @@ static void rebuild_hash(Section *s, unsigned int nb_buckets)
}
/* return the symbol number */
-ST_FUNC int put_elf_sym(Section *s, uplong value, unsigned long size,
+ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
int info, int other, int shndx, const char *name)
{
int name_offset, sym_index;
@@ -157,7 +157,7 @@ ST_FUNC int find_elf_sym(Section *s, const char *name)
}
/* return elf symbol value, signal error if 'err' is nonzero */
-static void *get_elf_sym_addr(TCCState *s, const char *name, int err)
+ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
{
int sym_index;
ElfW(Sym) *sym;
@@ -167,26 +167,28 @@ static void *get_elf_sym_addr(TCCState *s, const char *name, int err)
if (!sym_index || sym->st_shndx == SHN_UNDEF) {
if (err)
tcc_error("%s not defined", name);
- return NULL;
+ return 0;
}
- return (void*)(uplong)sym->st_value;
+ return sym->st_value;
}
+#ifdef TCC_IS_NATIVE
/* return elf symbol value */
LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
{
- return get_elf_sym_addr(s, name, 0);
+ return (void*)get_elf_sym_addr(s, name, 0);
}
/* return elf symbol value or error */
-ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name)
+ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
{
- return get_elf_sym_addr(s, name, 1);
+ return (void*)get_elf_sym_addr(s, name, 1);
}
+#endif
/* add an elf symbol : check if it is already defined and patch
it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
-ST_FUNC int add_elf_sym(Section *s, uplong value, unsigned long size,
+ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,
int info, int other, int sh_num, const char *name)
{
ElfW(Sym) *esym;
@@ -431,12 +433,12 @@ ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
if (sh_num == SHN_UNDEF) {
name = strtab_section->data + sym->st_name;
if (do_resolve) {
-#if !defined TCC_TARGET_PE || !defined _WIN32
+#if defined TCC_IS_NATIVE && !defined _WIN32
void *addr;
name = symtab_section->link->data + sym->st_name;
addr = resolve_sym(s1, name);
if (addr) {
- sym->st_value = (uplong)addr;
+ sym->st_value = (addr_t)addr;
goto found;
}
#endif
@@ -469,10 +471,10 @@ ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
}
}
-#ifndef TCC_TARGET_PE
+#ifdef TCC_HAS_RUNTIME_PLTGOT
#ifdef TCC_TARGET_X86_64
#define JMP_TABLE_ENTRY_SIZE 14
-static uplong add_jmp_table(TCCState *s1, uplong val)
+static addr_t add_jmp_table(TCCState *s1, addr_t val)
{
char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset;
s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
@@ -480,30 +482,30 @@ static uplong add_jmp_table(TCCState *s1, uplong val)
p[0] = 0xff;
p[1] = 0x25;
*(int *)(p + 2) = 0;
- *(uplong *)(p + 6) = val;
- return (uplong)p;
+ *(addr_t *)(p + 6) = val;
+ return (addr_t)p;
}
-static uplong add_got_table(TCCState *s1, uplong val)
+static addr_t add_got_table(TCCState *s1, addr_t val)
{
- uplong *p = (uplong *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset);
- s1->runtime_plt_and_got_offset += sizeof(uplong);
+ addr_t *p = (addr_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset);
+ s1->runtime_plt_and_got_offset += sizeof(addr_t);
*p = val;
- return (uplong)p;
+ return (addr_t)p;
}
#elif defined TCC_TARGET_ARM
#define JMP_TABLE_ENTRY_SIZE 8
-static uplong add_jmp_table(TCCState *s1, int val)
+static addr_t 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 (uplong)p;
+ return (addr_t)p;
}
#endif
-#endif
+#endif /* def TCC_HAS_RUNTIME_PLTGOT */
/* relocate a given section (CPU dependent) */
ST_FUNC void relocate_section(TCCState *s1, Section *s)
@@ -513,7 +515,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
ElfW(Sym) *sym;
int type, sym_index;
unsigned char *ptr;
- uplong val, addr;
+ addr_t val, addr;
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
int esym_index;
#endif
@@ -612,13 +614,14 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
is_call = (type == R_ARM_CALL);
x += val - addr;
h = x & 2;
-#ifndef TCC_TARGET_PE
- if ((x & 3) || x >= 0x2000000 || x < -0x2000000)
- if (!(x & 3) || !blx_avail || !is_call)
- if (s1->output_type == TCC_OUTPUT_MEMORY) {
+#ifdef TCC_HAS_RUNTIME_PLTGOT
+ if (s1->output_type == TCC_OUTPUT_MEMORY) {
+ if ((x & 3) || x >= 0x2000000 || x < -0x2000000)
+ if (!(x & 3) || !blx_avail || !is_call) {
x += add_jmp_table(s1, val) - val; /* add veneer */
is_thumb = 0; /* Veneer uses ARM instructions */
}
+ }
#endif
if ((x & 3) || x >= 0x2000000 || x < -0x2000000)
if (!(x & 3) || !blx_avail || !is_call)
@@ -770,8 +773,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
*(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
break;
default:
- fprintf(stderr,"FIXME: handle reloc type %x at %x [%.8x] to %x\n",
- type, (unsigned)addr, (unsigned)(uplong)ptr, (unsigned)val);
+ fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
+ type, (unsigned)addr, ptr, (unsigned)val);
break;
#elif defined(TCC_TARGET_C67)
case R_C60_32:
@@ -796,8 +799,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
case R_C60HI16:
break;
default:
- fprintf(stderr,"FIXME: handle reloc type %x at %x [%.8x] to %x\n",
- type, (unsigned)addr, (unsigned)(uplong)ptr, (unsigned)val);
+ fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
+ type, (unsigned)addr, ptr, (unsigned)val);
break;
#elif defined(TCC_TARGET_X86_64)
case R_X86_64_64:
@@ -837,7 +840,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
long long diff;
diff = (long long)val - addr;
if (diff <= -2147483647 || diff > 2147483647) {
-#ifndef TCC_TARGET_PE
+#ifdef TCC_HAS_RUNTIME_PLTGOT
/* XXX: naive support for over 32bit jump */
if (s1->output_type == TCC_OUTPUT_MEMORY) {
val = (add_jmp_table(s1, val - rel->r_addend) +
@@ -858,7 +861,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
*(int *)ptr = val - rel->r_addend;
break;
case R_X86_64_GOTPCREL:
-#ifndef TCC_TARGET_PE
+#ifdef TCC_HAS_RUNTIME_PLTGOT
if (s1->output_type == TCC_OUTPUT_MEMORY) {
val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
*(int *)ptr += val - addr;
@@ -1275,7 +1278,7 @@ ST_FUNC Section *new_symtab(TCCState *s1,
}
/* put dynamic tag */
-static void put_dt(Section *dynamic, int dt, uplong val)
+static void put_dt(Section *dynamic, int dt, addr_t val)
{
ElfW(Dyn) *dyn;
dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
@@ -1545,7 +1548,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
int *section_order;
int shnum, i, phnum, file_offset, offset, size, j, sh_order_index, k;
long long tmp;
- uplong addr;
+ addr_t addr;
Section *strsec, *s;
ElfW(Shdr) shdr, *sh;
ElfW(Phdr) *phdr, *ph;
@@ -1553,9 +1556,9 @@ static int elf_output_file(TCCState *s1, const char *filename)
unsigned long saved_dynamic_data_offset;
ElfW(Sym) *sym;
int type, file_type;
- uplong rel_addr, rel_size;
+ addr_t rel_addr, rel_size;
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
- uplong bss_addr, bss_size;
+ addr_t bss_addr, bss_size;
#endif
file_type = s1->output_type;
@@ -2191,7 +2194,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
/* get entry point address */
if (file_type == TCC_OUTPUT_EXE)
- ehdr.e_entry = (uplong)tcc_get_symbol_err(s1, "_start");
+ ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
else
ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
}