[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Tinycc-devel] arm64 relocations
From: |
Edmund Grimley Evans |
Subject: |
[Tinycc-devel] arm64 relocations |
Date: |
Thu, 26 Feb 2015 22:54:59 +0000 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
The first part of the patch below changes arm64-gen.c to use the same
relocations that other compilers use on arm64, namely
R_AARCH64_ADR_PREL_PG_HI21 and R_AARCH64_ADD_ABS_LO12_NC.
The second part is an attempt to make tccelf.c cope with those
relocations.
Here's something TCC does better with the patch:
cat <<'EOF' > r.c
#include <stdio.h>
int main()
{
printf("stdin : %p\n", &stdin);
printf("stdout: %p\n", &stdout);
return 0;
}
EOF
Before the patch:
$ ./tcc -B. -run r.c
stdin : 0x40a2d5d8
stdout: 0x435438
(It seems to be bypassing the GOT for stdin.)
After the patch:
$ ./tcc -B. -run r.c
stdin : 0x45b390
stdout: 0x45b3b0
However, weak symbols don't seem to work with the patch:
cat <<'EOF' > w.c
extern int __attribute__((weak)) weak_f1(void);
int main()
{
printf("weak_f1 = %p\n", weak_f1);
return 0;
}
EOF
Before the patch:
$ ./tcc -B. -run w.c
weak_f1 = (nil)
After the patch:
$ ./tcc -B. -run w.c
weak_f1 = 0x453670
Can anyone help with this at all?
Edmund
diff --git a/arm64-gen.c b/arm64-gen.c
index 737a7be..2635680 100644
--- a/arm64-gen.c
+++ b/arm64-gen.c
@@ -400,7 +400,7 @@ static void gen_fstore(int sz, int dst, int bas, uint64_t
off)
static void gen_addr(int r, Sym *sym, unsigned long addend)
{
-#if 0
+#if 1
// This is normally the right way to do it, I think,
// but it does not work with "-run" when stdin or stderr is
// used by the program: "R_AARCH64_ADR_PREL_PG_HI21 relocation failed".
diff --git a/tccelf.c b/tccelf.c
index 2b07f60..7501c7f 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -784,6 +784,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
(val >> 48 & 0xffff) << 5;
break;
case R_AARCH64_ADR_PREL_PG_HI21: {
+ if (sym->st_shndx == SHN_UNDEF)
+ val = s1->plt->sh_addr + rel->r_addend;
uint64_t off = (val >> 12) - (addr >> 12);
if ((off + ((uint64_t)1 << 20)) >> 21)
tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
@@ -792,6 +794,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
break;
}
case R_AARCH64_ADD_ABS_LO12_NC:
+ if (sym->st_shndx == SHN_UNDEF)
+ val = s1->plt->sh_addr + rel->r_addend;
*(uint32_t *)ptr = (*(uint32_t *)ptr & 0xffc003ff) |
(val & 0xfff) << 10;
break;
@@ -1399,6 +1403,8 @@ ST_FUNC void build_got_entries(TCCState *s1)
case R_AARCH64_JUMP26:
case R_AARCH64_CALL26:
+ case R_AARCH64_ADR_PREL_PG_HI21:
+ case R_AARCH64_ADD_ABS_LO12_NC:
if (!s1->got)
build_got(s1);
sym_index = ELFW(R_SYM)(rel->r_info);
- [Tinycc-devel] arm64 relocations,
Edmund Grimley Evans <=