https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106835

            Bug ID: 106835
           Summary: [i386] Taking an address of _GLOBAL_OFFSET_TABLE_
                    produces a wrong value
           Product: gcc
           Version: 11.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rui314 at gmail dot com
  Target Milestone: ---

On i386, _GLOBAL_OFFSET_TABLE_ should reference the location of .got.plt.
However, the following piece of code prints out a bogus value:

```
$ cat foo.c
#include <stdio.h>

extern char _GLOBAL_OFFSET_TABLE_[];
char *ptr = _GLOBAL_OFFSET_TABLE_;

int main() {
  printf("%lx\n", (unsigned long)ptr);
}

$ i686-linux-gnu-gcc-12 -m32 -c foo.c
$ i686-linux-gnu-gcc-12 -m32 -o foo foo.o
$ ./foo
ffffffd0
```

This is because the relocation for .data is of type R_386_GOTPC. It should be
R_386_32.

```
$ readelf -r foo.o

Relocation section '.rel.text' at offset 0x234 contains 5 entries:
 Offset     Info    Type                Sym. Value  Symbol's Name
00000010  00000802 R_386_PC32             00000000   __x86.get_pc_thunk.ax
00000015  0000060a R_386_GOTPC            00000000   _GLOBAL_OFFSET_TABLE_
0000001b  00000509 R_386_GOTOFF           00000000   ptr
00000025  00000309 R_386_GOTOFF           00000000   .rodata
0000002d  00000904 R_386_PLT32            00000000   printf

Relocation section '.rel.data.rel' at offset 0x25c contains 1 entry:
 Offset     Info    Type                Sym. Value  Symbol's Name
00000000  0000060a R_386_GOTPC            00000000   _GLOBAL_OFFSET_TABLE_
```

I found this bug when writing a test for the mold linker.

Related to: https://github.com/rui314/mold/issues/693

Reply via email to