This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/84184] New: gcc generates wrong relocations with negative offsets in struct arrays (but not integral arrays)
- From: "slyfox at inbox dot ru" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 02 Feb 2018 17:38:49 +0000
- Subject: [Bug c/84184] New: gcc generates wrong relocations with negative offsets in struct arrays (but not integral arrays)
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84184
Bug ID: 84184
Summary: gcc generates wrong relocations with negative offsets
in struct arrays (but not integral arrays)
Product: gcc
Version: 7.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: slyfox at inbox dot ru
Target Milestone: ---
Created attachment 43327
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43327&action=edit
reloc-bug.c
It's a trimmed-down version of linux kernel miscompilation on ia64:
https://bugs.gentoo.org/518130
Minimal reproducer:
// cat reloc-bug.c
#include <stdio.h>
typedef unsigned long long u64;
struct s { u64 a; };
struct s glo_s[] = {
{ 100, },
// glo_s_middle_hidden:
// ; Injected as LDFLAGS="-Wl,--defsym=glo_s_middle=glo_s+8
-Wl,--defsym=glo_s_middle_hidden=glo_s+8"
{ 700, },
{ 800, },
};
extern char glo_s_middle_hidden[] __attribute__((visibility("hidden")));
static u64 __attribute__((noinline)) val_s_hidden(void) {
const struct s * m = (const struct s *)glo_s_middle_hidden;
return m[-1].a;
}
int main() {
printf ("val/hidden = %lld\n", val_s_hidden());
}
+ ia64-unknown-linux-gnu-gcc-7.2.0 -c -O2 reloc-bug.c -o reloc-bug.o
+ ia64-unknown-linux-gnu-gcc-7.2.0 -O2 reloc-bug.o -o reloc-bug
-Wl,--defsym=glo_s_middle=glo_s+8 -Wl,--defsym=glo_s_middle_hidden=glo_s+8
+ ./reloc-bug
./mk.sh: line 12: 12418 Segmentation fault ./reloc-bug
Note a few things:
Note 1:
it's not trivial to write the code in standard C. I had to synthesise symbol
with --defsym. I tried a few targets where this sample crashes instead of
returning 100:
# fails
CC=sparc64-unknown-linux-gnu-gcc
CC=ia64-unknown-linux-gnu-gcc
CC=alpha-unknown-linux-gnu-gcc
# works
CC=sparc-unknown-linux-gnu-gcc
CC=x86_64-pc-linux-gnu-gcc
CC=aarch64-unknown-linux-gnu-gcc
CC=armv5tel-softfloat-linux-gnueabi-gcc
CC=hppa-unknown-linux-gnu-gcc
CC=hppa2.0-unknown-linux-gnu-gcc
CC=m68k-unknown-linux-gnu-gcc
CC=mips-unknown-linux-gnu-gcc
CC=nios2-unknown-linux-gnu-gcc
CC=powerpc-unknown-linux-gnu-gcc
CC=powerpc64-unknown-linux-gnu-gcc
CC=powerpc64le-unknown-linux-gnu-gcc
CC=s390x-unknown-linux-gnu-gcc
CC=sh4-unknown-linux-gnu-gcc
Note 2:
If we change
struct s { u64 a; };
struct s glo_s[] = {
to
u64 glo_s[] = {
gcc will generate correct code.