https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81490
--- Comment #27 from H.J. Lu <hjl.tools at gmail dot com> --- (In reply to H. Peter Anvin from comment #26) > @GPREL (altough it probably should be @GPOFF by analogy with @TPOFF?) gives > the linker an option to distinguish the relocations which need to be > adjusted at link/load time and the ones that don't. > The GP offset is fixed at link-time. > We have our own way of doing that for the Linux kernel, but I'm guessing > H.J. wants a more general solution. > It makes __seg_fs and __seg_gs easier to use: [hjl@gnu-6 gprel-1]$ cat x.c int __seg_gs foo; int get_foo (void) { return foo; } void set_foo (int x) { foo = x; } static int __seg_gs bar; int get_bar (void) { return bar; } void set_bar (int x) { bar = x; } [hjl@gnu-6 gprel-1]$ cat foo.c #define _GNU_SOURCE #include <stdio.h> #include <syscall.h> #include <unistd.h> #include <asm/prctl.h> extern int __seg_gs foo; extern int __gp; extern int get_foo (void); extern void set_foo (int); extern int get_bar (void); extern void set_bar (int); int setup_gp (void *p) { return syscall (SYS_arch_prctl, ARCH_SET_GS, p); } int main () { setup_gp (&__gp); printf ("foo: %d\n", foo); printf ("foo: %d\n", get_foo ()); foo = 30; printf ("foo: %d\n", foo); printf ("foo: %d\n", get_foo ()); set_foo (-30); printf ("foo: %d\n", foo); printf ("foo: %d\n", get_foo ()); printf ("bar: %d\n", get_bar ()); set_bar (-30); printf ("bar: %d\n", get_bar ()); return 0; } [hjl@gnu-6 gprel-1]$ make /export/build/gnu/gcc-x32/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc-x32/build-x86_64-linux/gcc/ -mgprel -g -O2 -c -o x.o x.c /export/build/gnu/gcc-x32/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc-x32/build-x86_64-linux/gcc/ -mgprel -g -O2 -c -o foo.o foo.c /export/build/gnu/gcc-x32/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc-x32/build-x86_64-linux/gcc/ -mgprel -o x x.o foo.o ./x foo: 0 foo: 0 foo: 30 foo: 30 foo: -30 foo: -30 bar: 0 bar: -30 [hjl@gnu-6 gprel-1]$