public inbox for gcc-prs@sourceware.org help / color / mirror / Atom feed
From: fvdl@wasabisystems.com To: gcc-gnats@gcc.gnu.org Subject: target/6912: x86_64 switch code generation problem with -fPIC Date: Sun, 02 Jun 2002 17:46:00 -0000 [thread overview] Message-ID: <200206030012.g530CsJ19010@k2.vaasje.org> (raw) >Number: 6912 >Category: target >Synopsis: x86_64 switch code generation problem with -fPIC >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: wrong-code >Submitter-Id: net >Arrival-Date: Sun Jun 02 17:46:01 PDT 2002 >Closed-Date: >Last-Modified: >Originator: Frank van der Linden >Release: 3.2 20020602 (experimental) >Organization: >Environment: System: NetBSD k2 1.5ZC NetBSD 1.5ZC (K2) #0: Wed May 1 02:01:29 CEST 2002 fvdl@k2:/work/trees/empee/sys/arch/i386/compile/K2 i386 host: i386-unknown-netbsdelf1.5ZC build: i386-unknown-netbsdelf1.5ZC target: x86_64--netbsd configured with: /work/trees/toolchain/gcc/configure --target=x86_64--netbsd --disable-shared --with-gnu-ld --with-gas --enable-languages=c c++ --prefix=/work/fvdl/toolchain >Description: gcc 3.1 and up generates bad code for switch jump tables when using the -fPIC flag. The problem is that the generated jump table contains 32-bit signed values for the relative offset to jump to. This is fine, for small mode. However, when they are loaded into a register for the computation of the jump destination, they are not sign-extended. This means that for negative offsets, the computed address will be wrong and way out of range (i.e. -10 will be added as 0x00000000fffffff6). This bug may have gone unnoticed for a while, because mostly, the jump table resides in memory *before* the code it points to (.rodata comes before .text, or the jumptable resides in .text before the code), so the offsets will be positive. But, there are cases in which this is not the case (like in the NetBSD dynamic linker). And a compiler should not make assumptions about the order of sections anyway. small example program: /* * Simple testcode to tickle a codegen bug with -fPIC and switch * statements on x86_64. * * The code inside the cases is irrelevant, it's just there as * filler to avoid stuff being optimised away. */ extern int a, b, c, d, e; int foo(void) { switch (a) { case 1: a = b * c; a--; break; case 2: a = d * e; c = d / b; break; case 3: a = c / d; b = d * d; c--; break; case 4: a = d * d; b = c * c; break; case 5: c++; d++; c = b * b; break; } return 0; } ====== gcc 3.1 and up generates (with -O -fPIC) ====== .file "c.c" .text .align 2 .globl foo .type foo,@function foo: .LFB1: pushq %rbx .LCFI0: movq a@GOTPCREL(%rip), %rax cmpl $5, (%rax) ja .L2 mov (%rax), %eax leaq .L8(%rip), %rdx mov (%rdx,%rax,4), %eax <==== no sign-extension addq %rdx, %rax <==== jmp *%rax .section .rodata .align 4 .align 4 .L8: .long .L2-.L8 .long .L3-.L8 .long .L4-.L8 .long .L5-.L8 .long .L6-.L8 .long .L7-.L8 .text .L3: [... rest of code deleted] ====== An older gcc (gcc version 3.1 20010430 (experimental)) generates (with -O -fPIC) correct code: ====== .file "c.c" .text .align 4 .globl foo .type foo,@function foo: .LFB1: pushq %rbx .LCFI0: movq a@GOTPCREL(%RIP), %rax movl (%rax), %eax decl %eax cmpl $4, %eax ja .L2 mov %eax, %eax leaq .L8(%rip), %rdx movslq (%rdx,%rax,4),%rax <=== correct sign extension leaq (%rax,%rdx), %rax jmp *%rax .section .rodata .align 16 .align 4 .L8: .long .L3-.+4+(.-.L8) .long .L4-.+4+(.-.L8) .long .L5-.+4+(.-.L8) .long .L6-.+4+(.-.L8) .long .L7-.+4+(.-.L8) .text .align 4 .L3: [... rest of output deleted] >How-To-Repeat: Compile with a largish switch with -fPIC, and link the resulting program in such a way that the jumptable comes after the code it points to. >Fix: Unknown to me, should be simple. >Release-Note: >Audit-Trail: >Unformatted:
next reply other threads:[~2002-06-03 0:46 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top 2002-06-02 17:46 fvdl [this message] 2002-06-05 8:56 Frank van der Linden 2002-07-12 11:06 Frank van der Linden 2002-10-01 5:35 hubicka
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=200206030012.g530CsJ19010@k2.vaasje.org \ --to=fvdl@wasabisystems.com \ --cc=gcc-gnats@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).