This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/84184] New: gcc generates wrong relocations with negative offsets in struct arrays (but not integral arrays)


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.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]