[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] [PATCH] use RELA relocations properly for R_DATA_PTR

From: Edmund Grimley Evans
Subject: [Tinycc-devel] [PATCH] use RELA relocations properly for R_DATA_PTR
Date: Tue, 17 Feb 2015 09:00:15 +0000

Try this on x86_64:

cat <<END > t1.c
extern int x[];
int *p = &x[4];

cat <<END > t2.c
#include <stdio.h>
int x[10];
extern int *p;
int main()
  printf("%lld\n", (long long)(p - x));
  return 0;

At first sight this appears to work as expected with both GCC and TCC
as compiler or linker:

gcc -Wall -O2 -c t1.c -o t1.gcc.o
gcc -Wall -O2 -c t2.c -o t2.gcc.o

./tcc -B. -c t1.c -o t1.tcc.o
./tcc -B. -c t2.c -o t2.tcc.o

gcc t[12].gcc.o -o t.gg.exe
./tcc -B. libtcc1.a t[12].gcc.o -o t.gt.exe
gcc t[12].tcc.o -o t.tg.exe
./tcc -B. libtcc1.a t[12].tcc.o -o t.tt.exe

All four executables print "4".

However, when you look at the relocations in t1.?cc.o you find
something strange:

readelf -r t1.gcc.o
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000000  000800000001 R_X86_64_64       0000000000000000 x + 10

readelf -r t1.tcc.o
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000000  000300000001 R_X86_64_64       0000000000000000 x + 0

With TCC the addend is zero! Apparently TCC is putting the offset is
in the data section:

readelf -x .data t1.gcc.o
  0x00000000 00000000 00000000                   ........

readelf -x .data t1.tcc.o
  0x00000000 10000000 00000000                   ........

Now this isn't how RELA relocations are normally described as working,
though I'm not sure that it's wrong. I haven't found a document that
says you have to ignore what value is "in the place" with a RELA
relocation, and looking at the source for lld (LLVM's linker) it
appears that that linker ORs the symbol value plus addend with the
value in the place in the case of R_X86_64_64 ...

Anyway, the attached patch makes TCC generate proper RELA relocations
like GCC does, putting zero in the place so it doesn't matter whether
the linker then ignores that value, adds it, or ORs it.

Proposed commit message:

Use RELA relocations properly for R_DATA_PTR on x86_64.

libtcc.c: Add greloca, a generalisation of greloc that takes an addend.
tcc.h: Add greloca and put_elf_reloca.
tccelf.c: Add put_elf_reloca, a generalisation of put_elf_reloc.
tccgen.c: On x86_64, use greloca instead of greloc in init_putv.

Attachment: 2015-02-17-rela-R_DATA_PTR.patch
Description: Text Data

reply via email to

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