This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

ld unable to do stdcall fixup from DLL?


I have a test case that suggests ld can't do stdcall fixup when the
symbol is provided by a DLL. I'm trying to figure out why it doesn't
work from the ld code, and it seems that pe_fixup_stdcalls doesn't
know anything about _imp__ prefixes, and the _imp__ fixup parts don't
know anything about stdcall @n suffixes. Is this a known
bug/limitation?

Maybe an ideal solution would be to introduce a hash table of "base"
names, with all known prefixes and suffixes stripped off, and lookup
the "base" names of the unresolved symbols in this table. This would
handle all possible permutations of prefix and suffix mismatches, and
avoid cases where the whole symbol table is scanned repeatedly (like
can happen in pe_fixup_stdcalls). Or is there a better way to fix
this? It looks a bit too scary for me, because there are multiple
places that handle the _imp__ prefix.

----8<---- test case as a shell script -----8<----

cat >stdcall_export.c <<EOF
__attribute__((dllexport,stdcall)) int foo () { return 5; }
EOF

cat >stdcall_import.c <<EOF
__attribute__((dllimport,stdcall)) int foo ();
int main () { return foo(); }
EOF

gcc -o stdcall_import.o -c stdcall_import.c
gcc -o stdcall_export.o -c stdcall_export.c

# Use kill-at to cause a stdcall name mismatch
gcc -o stdcall_export.dll stdcall_export.o -shared -Wl,--kill-at
ld stdcall_import.o stdcall_export.dll

----8<---- end test case shell script -----8<----

You can cut-and-paste the above script into a shell, or write it to a
script file first.

Sample output (_imp__foo@0 is the only relevant error):

ld: warning: cannot find entry symbol _mainCRTStartup; defaulting to 00401000
stdcall_import.o(.text+0x15):stdcall_import.c: undefined reference to `_alloca'
stdcall_import.o(.text+0x1a):stdcall_import.c: undefined reference to `__main'
stdcall_import.o(.text+0x1f):stdcall_import.c: undefined reference to `_imp__foo@0'

BTW, I do have a workaround, but it is messy - fool the compiler into
thinking that the symbols have the wrong calling convention, so that
the symbols match up exactly at link-time (no stdcall fixup
required). Use function pointer casts to call the functions with the
correct calling convention. This is very messy (and easy to get
wrong).

-- 
Raoul Gough.
(setq dabbrev-case-fold-search nil)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]