public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
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...)


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