Bug 3956 – linker removes underscore from all exported symbols of a module but the first

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P2
Component
tools
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2010-03-13T09:18:00Z
Last change time
2015-06-09T04:37:39Z
Keywords
dll, pull
Assigned to
nobody
Creator
r.sagitario

Comments

Comment #0 by r.sagitario — 2010-03-13T09:18:09Z
this test program: module testexport; export void foo1() {} export void foo2() {} export void foo3() {} void main() {} compiles, but exports in the resulting executable (not a DLL here for simplicity) are wrong. >dumpbin /exports testexport.exe [...] ordinal hint RVA name 1 0 00003014 D10testexport4foo2FZv 2 1 00003018 D10testexport4foo3FZv 3 2 00003010 _D10testexport4foo1FZv [...] The object file seems ok, here's a snippet from obj2asms' output: extrn _D10testexport4foo1FZv ;expdef expflag=x00, export '_D10testexport4foo1FZv', internal '', ordinal=x0 extrn _D10testexport4foo2FZv ;expdef expflag=x00, export '_D10testexport4foo2FZv', internal '', ordinal=x0 extrn _D10testexport4foo3FZv ;expdef expflag=x00, export '_D10testexport4foo3FZv', internal '', ordinal=x0 [...] public _D10testexport12__ModuleInfoZ _D10testexport4foo1FZv COMDAT flags=x0 attr=x0 align=x0 _D10testexport4foo2FZv COMDAT flags=x0 attr=x0 align=x0 _D10testexport4foo3FZv COMDAT flags=x0 attr=x0 align=x0 __Dmain COMDAT flags=x0 attr=x0 align=x0
Comment #1 by r.sagitario — 2011-12-31T01:11:55Z
*** Issue 7186 has been marked as a duplicate of this issue. ***
Comment #2 by code — 2013-09-27T19:05:26Z
This just broke my shiny new loadFunc, loadSym implementation and it took me +1h to get here. Any ideas how to fix this?
Comment #3 by code — 2013-09-27T22:17:47Z
Presumably something in this TWEAK_EXPORT_NAMES function goes wrong or the function isn't called under certain circumstances. It seems simple enough to remove the underscore striping altogether. Is it possible to debug optlink with some debug infos. How to build this thing? https://github.com/DigitalMars/optlink/blob/475bc5c1fa28eaf899ba4ac1dcfe2ab415db16c6/common/coment.asm#L529
Comment #4 by code — 2013-09-28T07:25:41Z
#ifdef fg_pe
Comment #5 by code — 2013-09-28T07:45:37Z
YES_EXPORT PROC ;; ... #ifdef fg_pe if (OUTPUT_PE) // false on first test TWEAK_EXPORT_NAMES(); #endif DEFINE_EXPORT(); // could set ANY_USE32, but it's usually already SELECT_OUTPUT_SEGMENTED_OR_PE(); ;; ... YES_EXPORT ENDP SELECT_OUTPUT_SEGMENTED_OR_PE PROC if (!(OUTPUT_SEGMENTED | OUTPUT_PE)) return; if (ANY_USE32) // this is already set by defining the output segments SELECT_OUTPUT_PE(); // sets OUTPUT_PE else SELECT_OUTPUT_SEGMENTED(); SELECT_OUTPUT_SEGMENTED_OR_PE ENDP I found the bug, thanks to OllyDbg, but I could use some help to interpret and resolve it. From what I understand optlink determines the output format OUTPUT_SEGMENTED or OUTPUT_PE depending on the input files. That is when it first encounters some usage of 32-bit symbols it will set ANY_USE32. Striping the leading underscore in the exported name is only done for OUTPUT_PE. The problem comes from the circular dependency in the OUTPUT_PE test above. For the first export symbol no output format has yet been set, thus the test fails and the symbol is not stripped. One way to resolve this would be to prematurely test for ANY_USE32 if no OUTPUT is selected. if (OUTPUT_PE || !OUTPUT_SEGMENTED && ANY_USE32) Any ideas?
Comment #6 by code — 2013-09-28T13:28:54Z
Comment #7 by bugzilla — 2014-01-03T18:26:06Z
Fixed 8.00.15