Windows 32-bit x86 AOT assembler didn't link correctly.
authorlateralusX <lateralusx.github@gmail.com>
Tue, 19 Apr 2016 15:12:48 +0000 (17:12 +0200)
committerlateralusX <lateralusx.github@gmail.com>
Tue, 19 Apr 2016 15:17:46 +0000 (17:17 +0200)
commit09ba9118ce73c9cc1a54e3b6d78e3ec5f0f6e60d
tree6bbdaa6a639d0a5a2ba003953252a2fdae6bff31
parent24418b8821d73ad6e2b25094c4370ac96a4c68f3
Windows 32-bit x86 AOT assembler didn't link correctly.

When running basic make check in mono/mini there are some hidden errors in the check-seq-points test. Current test compares output between JIT and AOT compile assemblies but doesn't pay attention to the result of the as and ld calls building the AOT:ed modules. It turns out that the linkage of the AOT compiled module on win32 x86 actually fails due to naming of symbols included in .def or .globl assembler expressions. The fix makes sure that local function symbols or global symbol definitions follows the cdecl win32 x86 convention and are prefixed with _. The fix tries to resolve this using two different strategies. Since there are many code paths in the AOT compiler emitting local/global symbols + referencing the emitted symbols, it doesn't look like there is one place to fix this (unless rename the symbol altogether and that could cause regressions elsewhere).

First, local function symbols are emitted using .def expression when used as debug symbols. By prefixing debug symbols with _ will resolve most of the local function symbols. By mangling the debug symbols we can fix both emitted symbols and references to these symbols in two location (get_debug_sym, get_plt_entry_debug_sym).

Second, in order to make sure all other symbols (local/global) ending up in .def or .globl expressions are correctly mangled, the functions to emit local/global symbols in aot-compiler.c have been extended to check mangling on passed in symbols before emitting. If passed in symbol doesn't follow the name mangling rule, the symbols will be mangled and the mangled symbol will be emitted together with a label to the mangled symbol. This is done to make sure we have a correct label for the emitted symbol that can be used by the linker. Since the rest of the code is unaware of the mangled name, it will continue reference the unmangled name and since there is already a label to the unmangled symbol, the mangling will be transparent for the rest of the code.

NOTE, the fix only applies to windows X86 build, other configurations are not affected by this issue.

This PR also includes a fix detected on windows when debugging and fixing above issue. The AOT compiler tries to rename linked module to the final target name, for example from basic.exe.dll.tmp to basic.exe.dll. If the file already exist, the rename will fail on windows causing a silent failure in the AOT compiler and this will "leak" the tmp file + ending up with the old basic.exe.dll. The fix is to check result of the rename function call and if it fails with "file already exist error", unlink target and redo rename operation. The rename can still fail due to other reasons ending up in the same problem, but to make a good fix, the error handling of the method needs to be revisited in order to properly clean up tmp files and allocations in error cases. This will be handled in a different PR.
mono/mini/aot-compiler.c