Cross-linking woes: what am I doing wrong?

Dave Korn dk@artimi.com
Tue Apr 13 15:05:00 GMT 2004


> -----Original Message-----
> From: binutils-owner On Behalf Of Bernd Jendrissek
> Sent: 13 April 2004 14:55

> I have two files, foo.c and bar.c:

> /usr/cross/bin/i386-mingw32-objdump -d -r bar.o:
> 
> bar.o:     file format pe-i386

  That looks right.

> Disassembly of section .text:
> 
> 0000000000000000 <.text>:
> 
> 	[same stuff again]
> 
> (Why are there multiple copies of .text in bar.o???)

  There shouldn't be, and I could imagine that having them might mess with
ld's head.  It would be interesting to know how they got there.  You should
verify I suppose that they really are there; maybe your objdump is bugged?

> the relocation seems to get screwed up:
> 
> /usr/cross/bin/i386-mingw32-objdump -d -r foo.exe:
> 
> foo.exe:     file format efi-app-ia32

  And the file spontaneously changes from PE format to something else that
I've never heard of.  That shouldn't happen either IIUIC.

>   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?)

  I think you got it right.  Looks that way to me, anyway.

> Disassembly of section .text:

> 0000000000401ac0 <_shiftit>:
>   401ac0:	55                   	push   %ebp

> 0000000000401b40 <_main>:

>   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>

  Yep, that's bad.  Let's check the reloc by hand: the formula is

  relocated_value = (in_place addend) + (target_sym -
addr_of_relocation_value)

so it should have ended up with the value

    fffffffc + (401ac0 - 401b66) = FFFFFF56

however it ended up with four less, almost as if the addend had been applied
twice.  Hmm, that rings a bell.  There was an m68k bfd bug like that once.

  Now, to actually be correct, the value in the offset needs to be the
difference between the byte immediately after the call instruction (which is
where the pc is pointing by the time the instruction has been read, and so
is the value to which the branch offset is added) and the destination, i.e.
the operand should contain

    401b6a - 401ac0 = FFFFFF56

which is the same as the previous calculation.  Ah, now I see where -4 comes
from: that's the difference between the base address of the reloc target
(which is one byte into the instruction) and the address from which the
branch is actually calculated, which is the byte after the instruction
(which has 5 bytes), so we have (insn+1) - (insn+5) = -4.  Good, glad that
makes sense to me now.

> 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?

  Dunno just yet.  Looks like your toolchain is completely gaga to me.  It's
undoubtedly getting things wrong.  You may have multiple points of failure.

>  And more to the (my) point, what do I
> have to do to be able to cross-compile to Windows? 

  It ought to work.  Maybe something else on your machine is interfering,
perhaps something incompatible in your $PATH; maybe you've got an
intermittent hardware problem that's scrambling data in memory - I'm very
curious why the file format changed; maybe it's something else again.  Maybe
reinstalling from scratch will fix it.

> (Everyone else using
> MinGW seems to be doing just fine; what makes me so special???)

  You're just lucky, I guess!

    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....



More information about the Binutils mailing list