This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Cross-linking woes: what am I doing wrong?
- From: Bernd Jendrissek <berndj at prism dot co dot za>
- To: binutils at sources dot redhat dot com
- Date: Tue, 13 Apr 2004 15:55:06 +0200
- Subject: Cross-linking woes: what am I doing wrong?
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hello, me again
I used to think my problem was with the mingw GCC, it being patched and
all. But now I think I'll start blaming ld for my woes. Let's see...
I have two files, foo.c and bar.c:
foo.c:
void shiftit(unsigned char *buf, int n)
{
int i;
for (i = 0; i < n; i++) {
buf[i] >>= 1;
}
}
bar.c:
void shiftit(unsigned char *buf, int n);
char name[] = "foobar";
int main()
{
shiftit(name, 5);
}
/usr/cross/bin/i386-mingw32-objdump -d -r bar.o:
bar.o: file format pe-i386
Disassembly of section .text:
0000000000000000 <_main>:
0: 55 push %ebp
1: 31 c0 xor %eax,%eax
3: 89 e5 mov %esp,%ebp
5: 83 ec 08 sub $0x8,%esp
8: 83 e4 f0 and $0xfffffff0,%esp
b: e8 fc ff ff ff call c <_main+0xc>
c: DISP32 __alloca
10: e8 fc ff ff ff call 11 <_main+0x11>
11: DISP32 ___main
15: c7 04 24 00 00 00 00 movl $0x0,(%esp,1)
18: dir32 .data
1c: b8 05 00 00 00 mov $0x5,%eax
21: 89 44 24 04 mov %eax,0x4(%esp,1)
25: e8 fc ff ff ff call 26 <_main+0x26>
26: DISP32 _shiftit
2a: 89 ec mov %ebp,%esp
2c: 5d pop %ebp
2d: c3 ret
...
Disassembly of section .text:
0000000000000000 <.text>:
[same stuff again]
(Why are there multiple copies of .text in bar.o???)
So in bar.o, we can all see the DISP32 reloc to shiftit; presumably the
diff from the reloc offset (26) to its value (shiftit) has to get added
to the data already there (-4), to yield the PC relative offset to
shiftit from the *next* instruction. Am I right so far? (I know I'm
right about how i386 jumps and calls work; I mean am I right about how
the relocation is supposed to work?)
But now, when I link foo.o and bar.o into an executable:
/usr/cross/bin/i386-mingw32-ld -Bdynamic -o foo.exe /usr/cross/lib/gcc-lib/i386-mingw32/3.3.3/../../../../i386-mingw32/lib/crt2.o /usr/cross/lib/gcc-lib/i386-mingw32/3.3.3/crtbegin.o -L/usr/cross/lib/gcc-lib/i386-mingw32/3.3.3 -L/usr/cross/lib/gcc-lib/i386-mingw32/3.3.3/../../../../i386-mingw32/lib foo.o bar.o -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt /usr/cross/lib/gcc-lib/i386-mingw32/3.3.3/crtend.o
the relocation seems to get screwed up:
/usr/cross/bin/i386-mingw32-objdump -d -r foo.exe:
foo.exe: file format efi-app-ia32
Disassembly of section .text:
...
0000000000401ac0 <_shiftit>:
401ac0: 55 push %ebp
...
0000000000401b40 <_main>:
401b40: 55 push %ebp
401b41: 31 c0 xor %eax,%eax
401b43: 89 e5 mov %esp,%ebp
401b45: 83 ec 08 sub $0x8,%esp
401b48: 83 e4 f0 and $0xfffffff0,%esp
401b4b: e8 cc 04 00 00 call 40201c <LBE7+0xb>
401b50: e8 b7 01 00 00 call 401d0c <LBE3+0x1>
401b55: c7 04 24 00 30 40 00 movl $0x403000,(%esp,1)
401b5c: b8 05 00 00 00 mov $0x5,%eax
401b61: 89 44 24 04 mov %eax,0x4(%esp,1)
401b65: e8 52 ff ff ff call 401abc <___do_sjlj_init+0x3c>
BANG! The call misses its intended target by 4 bytes, as if the
pre-reloc instruction
25: e8 fc ff ff ff call 26 <_main+0x26>
in bar.o should have been
25: e8 00 00 00 00 call 26 <_main+0x26>
This off-by-four breakage is everywhere, of course; including the
mingw-runtime, so my executables never even get a chance to start up.
(They crash in CrtDllMainStartup or whatever it's called.)
What the hell is going on here? And more to the (my) point, what do I
have to do to be able to cross-compile to Windows? (Everyone else using
MinGW seems to be doing just fine; what makes me so special???)
- --
http://voyager.abite.co.za/~berndj/ (up again for now - yay!)
"There are few or no amazing magicians in the world. Precious few
people are skilled enough to walk in on the blazing ruins of an
arbitrary sinking project, patch the holes and make it into a graceful
ocean liner. People that have this skill ought to be designing
projects correctly from the ground up, not dousing the flames of
someone else's train wreck."
- Lewin Edwards (comp.arch.embedded)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (GNU/Linux)
Comment: For info see http://www.gnupg.org
iD8DBQFAe/Ew/FmLrNfLpjMRAhnIAKCCxngA7irDZA5brKhBgAZGBbo6NgCfaAju
WAMRJ/0/DkpFI526EOj2fNA=
=akg8
-----END PGP SIGNATURE-----