[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug ld/6945] New: ld -r severely broken on 64-bit mingw / pe-x86-64
From: |
mikpe at it dot uu dot se |
Subject: |
[Bug ld/6945] New: ld -r severely broken on 64-bit mingw / pe-x86-64 |
Date: |
6 Oct 2008 12:22:08 -0000 |
x86_64-pc-mingw32-ld -r runs without warnings, but gcc jump tables in the
resulting .o file are broken. At runtime a switch() that references a jump table
now branches off to la-la land and the process crashes.
My x86_64-pc-mingw32 cross toolchain is composed of binutils-2.19.50.20081006
and gcc-4.4.0 20080926, with runtime libs from mingw-w64-snapshot-20080917.
The cross toolchain was compiled by a i686-pc-cygwin native toolchain composed
of binutils-2.18.91 and gcc-4.3.2. The host runs Win XP 64 Pro.
To reproduce, compile and link the file below (bug.c):
1. x86_64-pc-mingw32-gcc -O -c bug.c
2. x86_64-pc-mingw32-ld -r -o bug2.o bug.o
3. x86_64-pc-mingw32-gcc -o bug bug.o
4. x86_64-pc-mingw32-gcc -o bug2 bug2.o
Running ./bug works and produces output like:
L90 == 000000000040165A
L95 == 0000000000403000
L95.L90_minus_L95 == -6566, L95 + -6566 == 000000000040165A
However, running ./bug2 instead fails with:
L90 == 000000000040165A
L95 == 0000000000403000
L95.L90_minus_L95 == -6406, L95 + -6406 == 00000000004016FA
ERROR
This error does not occur when compiling for 32-bit mingw, or when compiling for
Linux or Solaris (32- or 64-bit x86).
The source code for bug.c follows below. The inline asm() block constructs a gcc
switch() jump table in "pic" mode: entries aren't code lables but the
differences from the table itself to the code labels. The rest of the code just
verifies the contents of the jump table.
#include <stdio.h>
struct L95 { /* mimics a gcc -fpic jump table */
int L90_minus_L95;
};
extern const struct L95 L95;
struct L95info { /* provides the actual target labels */
void *L90;
};
struct L95info L95info;
void __attribute__((noinline)) foo(void)
{
asm(
"leaq _L95info(%rip), %rax\n\t"
"leaq L90(%rip), %rdx\n\t"
"movq %rdx, 0(%rax)\n\t"
".section .rdata,\"dr\"\n\t"
".align 4\n"
"_L95:\n\t"
".long L90-_L95\n\t"
".text\n\t"
"movl $1, %eax\n"
"L90:\n\t"
"addl %eax, %eax");
}
int main(void)
{
int diff;
void *result;
foo();
printf("L90 == %p\n", L95info.L90);
printf("L95 == %p\n", &L95);
diff = L95.L90_minus_L95;
result = (char*)&L95 + diff;
printf("L95.L90_minus_L95 == %d, L95 + %d == %p\n",
diff, diff, result);
if (result != L95info.L90) {
printf("ERROR\n");
return 1;
}
return 0;
}
--
Summary: ld -r severely broken on 64-bit mingw / pe-x86-64
Product: binutils
Version: 2.19
Status: NEW
Severity: critical
Priority: P2
Component: ld
AssignedTo: unassigned at sources dot redhat dot com
ReportedBy: mikpe at it dot uu dot se
CC: bug-binutils at gnu dot org
GCC host triplet: i686-pc-cygwin
GCC target triplet: x86_64-pc-mingw32
http://sourceware.org/bugzilla/show_bug.cgi?id=6945
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.
- [Bug ld/6945] New: ld -r severely broken on 64-bit mingw / pe-x86-64,
mikpe at it dot uu dot se <=
- [Bug ld/6945] ld -r severely broken on 64-bit mingw / pe-x86-64, nickc at redhat dot com, 2008/10/09
- [Bug ld/6945] ld -r severely broken on 64-bit mingw / pe-x86-64, mikpe at it dot uu dot se, 2008/10/09
- [Bug ld/6945] ld -r severely broken on 64-bit mingw / pe-x86-64, nickc at redhat dot com, 2008/10/22
- [Bug ld/6945] ld -r severely broken on 64-bit mingw / pe-x86-64, nickc at redhat dot com, 2008/10/22
- [Bug ld/6945] ld -r severely broken on 64-bit mingw / pe-x86-64, mikpe at it dot uu dot se, 2008/10/25
- [Bug ld/6945] ld -r severely broken on 64-bit mingw / pe-x86-64, nickc at redhat dot com, 2008/10/25