diff options
| author | Michael Matz <matz@suse.de> | 2016-09-27 17:04:39 +0200 |
|---|---|---|
| committer | Michael Matz <matz@suse.de> | 2016-12-15 17:47:12 +0100 |
| commit | 975c74c1f51679cfe62d1fd455344f12399fb51c (patch) | |
| tree | 4866b7821b9e1c146190629972a768dc9b77710d | |
| parent | ad8e14b740f87d814a00f9f0d44301f71ffd7ec6 (diff) | |
| download | tinycc-975c74c1f51679cfe62d1fd455344f12399fb51c.tar.gz tinycc-975c74c1f51679cfe62d1fd455344f12399fb51c.tar.bz2 | |
x86-64: Prefer 32S relocations
This target has _32 and _32S relocs (the latter being for signed
32 bit entities). All instruction displacements have to use
the 32S variants. Normal references like
.long s
normally would use the _32 variant. For normal executables this
doesn't matter. For shared libraries neither (which use PC-relative
relocs). But it matters for things like the kernel that are linked
to high addresses (signed ones). There the GNU linker would error
out on overflow for the _32 variant.
To keep life simple we simply switch from _32 to _32S altogether.
Strictly speaking it's still wrong, but in practice using _32 is
more often wrong than using _32S ;)
| -rw-r--r-- | x86_64-gen.c | 2 | ||||
| -rw-r--r-- | x86_64-link.c | 2 |
2 files changed, 2 insertions, 2 deletions
diff --git a/x86_64-gen.c b/x86_64-gen.c index ea06708..6102be7 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -242,7 +242,7 @@ ST_FUNC int oad(int c, int s) ST_FUNC void gen_addr32(int r, Sym *sym, int c) { if (r & VT_SYM) - greloca(cur_text_section, sym, ind, R_X86_64_32, c), c=0; + greloca(cur_text_section, sym, ind, R_X86_64_32S, c), c=0; gen_le32(c); } diff --git a/x86_64-link.c b/x86_64-link.c index 9ff234b..602a8ef 100644 --- a/x86_64-link.c +++ b/x86_64-link.c @@ -3,7 +3,7 @@ #define EM_TCC_TARGET EM_X86_64 /* relocation type for 32 bit data relocation */ -#define R_DATA_32 R_X86_64_32 +#define R_DATA_32 R_X86_64_32S #define R_DATA_PTR R_X86_64_64 #define R_JMP_SLOT R_X86_64_JUMP_SLOT #define R_GLOB_DAT R_X86_64_GLOB_DAT |
