From: Charles Wilson <cwilson@ece.gatech.edu>
To: DJ Delorie <dj@delorie.com>
Cc: binutils@sources.redhat.com, cygwin@cygwin.com
Subject: Re: [aida_s@mx12.freecom.ne.jp: A serious bug of "ld --enable-auto-import"]
Date: Sun, 26 Aug 2001 08:10:00 -0000 [thread overview]
Message-ID: <3B891172.9000207@ece.gatech.edu> (raw)
In-Reply-To: <200108260613.CAA28557@envy.delorie.com>
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...)
next prev parent reply other threads:[~2001-08-26 8:10 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-08-25 22:11 Charles S. Wilson
2001-08-25 22:30 ` DJ Delorie
2001-08-25 22:47 ` Charles Wilson
2001-08-25 23:14 ` DJ Delorie
2001-08-26 8:10 ` Charles Wilson [this message]
2001-08-26 8:43 ` DJ Delorie
2001-08-26 9:04 ` Charles Wilson
2001-08-26 9:43 ` DJ Delorie
2001-08-26 15:35 ` Charles Wilson
2001-08-26 12:27 ` Kurt Roeckx
-- strict thread matches above, loose matches on Subject: below --
2001-08-25 10:50 Christopher Faylor
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=3B891172.9000207@ece.gatech.edu \
--to=cwilson@ece.gatech.edu \
--cc=binutils@sources.redhat.com \
--cc=cygwin@cygwin.com \
--cc=dj@delorie.com \
/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: link
Be 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).