Mail Archives: cygwin/2001/08/26/11:11:12
DJ Delorie wrote:
>>Anyway, I'm confused. The .o file already contains the "12" (actually,
>>0c 00 00 00 in on-disk byte order), so gas has already done its work --
>>properly. The problem occurs during the linking step -- ld is ignoring
>>the offset stored within the opcode and is blindly stuffing in the
>>relocation address without adding the offset.
>>
>
> Ok, a couple of things:
>
> In make_import_fixup in ld/emultempl/pe.em, it uses rel->addend
> without also checking for the inline offset. For formats that use an
> inline addend, rel->addend may be zero.
????
> Addends are very tricky in PE. There's lots of comments about adding,
> subtracting, adding, subtracting, etc, in various places in the code.
>
> I don't think an import library *can* specify an offset to be added at
> runtime.
Well, that's not exactly what we're trying to do here. We want hello.o
(which will be linked against the import library) to specify a runtime
offset. The import library doesn't specify it. But that's beside the
point; It looks like NOBODY can specify a runtime offset, because:
> From my understanding of the dll import/export system,
> windows simply places the address of the thing being imported in the
> location indicated.
seems to be correct.
Urk. Here's what hello.o looks like when hello.c uses
__declspec(dllimport) (and hwstr.c uses __declspec(dllexport)). Recall
that this configuration works as expected.
hello.o: file format pe-i386
Disassembly of section .text:
00000000 <_main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 18 sub $0x18,%esp
6: e8 00 00 00 00 call b <_main+0xb>
b: a1 00 00 00 00 mov 0x0,%eax
10: c6 40 0c 21 movb $0x21,0xc(%eax)
14: a1 00 00 00 00 mov 0x0,%eax
19: 89 45 fc mov %eax,0xfffffffc(%ebp)
1c: 8b 45 fc mov 0xfffffffc(%ebp),%eax
<snip>
And the relocs:
hello.o: file format pe-i386
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000007 DISP32 ___main
0000000c dir32 __imp__hwstr1
00000015 dir32 __imp__hwstr2
00000029 dir32 __imp__hwstr1
0000002f DISP32 _puts
0000003a dir32 __imp__hwstr2
00000040 DISP32 _puts
<snip>
Now, sure, you EXPECT the compiler to generate different asm code when
you use __declspec() modifiers. BUT the difference here is instructive:
hwstr1[12]='!'; generates THIS (with declspec'ed hwstr1)
b: a1 00 00 00 00 mov 0x0,%eax
10: c6 40 0c 21 movb $0x21,0xc(%eax)
instead of (without declspec'ed hwstr1)
b: c6 05 0c 00 00 00 21 movb $0x21,0xc
In the declspec case, a runtime offset is avoided (because the windows
loader "can't do that" ???).
This looks very bad for auto-import. One way to fix this is to change
the compiler to always generate the two-line assembler version instead
of the one-line version -- for all extern vars (because in the
auto-import world, you can't tell the difference between statically
linked externs and DLL-linked externs). But that would add a lot of
extra code even in cases when it's not needed, and could slow execution.
I really hope there's another way to fix this, since my idea is unlikely
to be accepted by gcc.
--Chuck
P.S. going back the the non-declspec-decorated versions, if we just link
hello.o and hwstr.o together (no dll's involved) it "just works".
hello.o has the one-line assembler:
b: c6 05 0c 00 00 00 21 movb $0x21,0xc
and the linker includes uses the address of _hwstr1 from hwstr.o, adds
"12" to it, and stuffs it into 0x00d---0x010.
from hello.exe:
40104f: c6 05 10 20 40 00 21 movb $0x21,0x402010
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000400 00401000 00401000 00000400 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000200 00402000 00402000 00000800 2**2
CONTENTS, ALLOC, LOAD, DATA
[288](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000004 _hwstr1
So, _hwstr1 is located at 0x00402000 + 0x00000004 = 0x00402004.
_hwstr1[12] is 0x00402010, which is exactly what is stuffed into the
machine opcode above.
(Yeah, I know this is obvious & is what you'd expect to see; but at this
point I'm manually verifying even the obvious stuff...)
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Bug reporting: http://cygwin.com/bugs.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
- Raw text -