tinycc-devel
[Top][All Lists]
Advanced

[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);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]