Skip to content
This repository has been archived by the owner on Feb 8, 2024. It is now read-only.

Build on mingw-w64 #104

Merged
merged 2 commits into from
Oct 27, 2017
Merged

Build on mingw-w64 #104

merged 2 commits into from
Oct 27, 2017

Conversation

ghost
Copy link

@ghost ghost commented Oct 8, 2017

No description provided.

@kinke
Copy link
Member

kinke commented Oct 8, 2017

Thanks - how are the tests looking?

@ghost
Copy link
Author

ghost commented Oct 8, 2017

Druntime is working pretty well but phobos is crashing for some reason.
So now i will try to fix phobos, you can check progress here https://github.com/wirx6/phobos/commits/mingw-fix

@ghost
Copy link
Author

ghost commented Oct 8, 2017

There probably is another problem with initialization/gc
Working:

int main(){
	FILE* s = fopen("test.txt", "rw");
	fprintf(s,"test");
	fclose(s);
	return 0;
}

Segfault:

void main(){
	FILE* s = fopen("test.txt", "rw");
	fprintf(s,"test");
	fclose(s);
}
EXCEPTION_DEBUG_INFO:
           dwFirstChance: 1
           ExceptionCode: C0000005 (EXCEPTION_ACCESS_VIOLATION)
          ExceptionFlags: 00000000
        ExceptionAddress: 000000000046A4E0 app.000000000046A4E0
        NumberParameters: 2
ExceptionInformation[00]: 0000000000000000 Read
ExceptionInformation[01]: 000000000D5E6340 Inaccessible Address
First chance exception on 000000000046A4E0 (C0000005, EXCEPTION_ACCESS_VIOLATION)!

{
extern extern (C) __gshared
extern (C) __gshared
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was dropping the first extern intended?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, good catch! That's definitely wrong, as the symbols are left initialized with nulls, and the GC doesn't have a single global as GC root.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More context: these symbols are to be provided by the linker. An extra underscore is prepended by LDC automatically.

else version (Windows)
{
pushRange(&_data_start__, &_bss_end__);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See https://github.com/msysgit/msys/blob/master/winsup/cygwin/winsup.h#L262. I think the previous code was correct - taking the address is necessary, and the old names should match as well.

Copy link
Member

@kinke kinke Oct 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh and please don't touch the MSVC part in a functional way, that was working fine when 0.17 was released. ;) [You removed the extern there too - thinking it was just a typo? extern(C) extern would look better.]

@ghost ghost force-pushed the mingw-fix branch from ccfbcdb to 817f54d Compare October 9, 2017 19:28
@ghost
Copy link
Author

ghost commented Oct 9, 2017

Sorry my mistake but for some reason ldc is not adding that underscore.

libdruntime-ldc.a(sections_ldc.obj):(.text[_D2rt12sections_ldc12initSectionsFZv]+0x1ce): undefined reference to `_data_start__'
libdruntime-ldc.a(sections_ldc.obj):(.text[_D2rt12sections_ldc12initSectionsFZv]+0x1d5): undefined reference to `_bss_end__'

Maybe someone more experienced will take care of the sections.

@kinke
Copy link
Member

kinke commented Oct 9, 2017

Validating the symbols exist (and checking their mangled names via objdump I guess) should be easy with a C file:

#include <stdio.h>
int global;
extern char _data_start__, _data_end__;
int main() {
  printf("%p, %p, %p\n", &global, &_data_start__, &_data_end__);
  return 0;
}

@ghost
Copy link
Author

ghost commented Oct 9, 2017

$ clang -c -o test.o test.c && nm test.o && clang -o test.exe test.o
0000000000000000 b .bss
0000000000000000 d .data
0000000000000000 p .pdata
0000000000000000 r .rdata
0000000000000000 t .text
0000000000000000 r .xdata
                 U __main
                 U _data_end__
                 U _data_start__
0000000000000004 C global
0000000000000000 T main
                 U printf
test.o:(.text+0x27): undefined reference to `_data_start__'
test.o:(.text+0x2e): undefined reference to `_data_end__'

@kinke
Copy link
Member

kinke commented Oct 9, 2017

Erm you're using clang? Please provide some more details about your environment, starting with Windows version, toolchain(s), used linker etc.

@ghost
Copy link
Author

ghost commented Oct 9, 2017

I am using 64 bit mingw-w64 delivered by msys2(http://www.msys2.org/). GCC is producing same symbols as clang.

@kinke
Copy link
Member

kinke commented Oct 9, 2017

You answered just one aspect - at least the linker would be good to know as well.

For MSVC, those symbols are derived from the binary's headers at startup: https://github.com/ldc-developers/druntime/blob/ldc-ltsmaster/src/ldc/msvc.c. That file is currently excluded in runtime/CMakeLists.txt for non-MSVC targets (see here). You may want to try adding it (clang may support the MSVC pragmas) and use it in rt.sections* just like MSVC (i.e., not taking their address).

@ghost
Copy link
Author

ghost commented Oct 9, 2017

Clang on mingw is not supporting MSVC's pragmas and also has different preprocessor defines.
This code may work because mingw is using MS crt at all but need to be redesigned.

@JohanEngelen
Copy link
Member

@wirx6 Those symbols are magic linker symbols, so the exact symbolnames that you need depend solely on the linker used. Perhaps because you are targeting mingw you have to use Linux-like linker magic symbolnames. These magic linker symbolnames are quite badly documented... so it's a bit of a pain to figure it out. http://www.airs.com/blog/archives/56
I'm not sure whether such magic names exist for the .data section.

I see that in LDC master, we use a different mechanism to find the start and end of the data section.

void[] dataSection = findImageSection(".data");

Backporting that is an alternative path you can try.

@dnadlinger
Copy link
Member

dnadlinger commented Oct 9, 2017

If you have a look at an old commit from before MSVC support was merged, data range registration was definitely working on mingw-w64. I don't quite remember everything that has changed since on Windows, though.

@ghost ghost force-pushed the mingw-fix branch 2 times, most recently from 7272731 to f09bc42 Compare October 10, 2017 16:31
@ghost
Copy link
Author

ghost commented Oct 10, 2017

@JohanEngelen I backported it and still getting the same error(I will leave it because it solves undefined symbols problem).
Maybe problem is somewhere else.

@kinke
Copy link
Member

kinke commented Oct 16, 2017

I just reluctantly installed MSYS2 and mingw-w64-x86_64-gcc. An additional leading underscore was needed (and not zero-initializing the global), then the symbols are there and seem plausible when linking with ld (v2.29.1) via gcc (v7.2.0).

#include <stdio.h>
int global = 123;
extern char __data_start__, __data_end__;
int main() {
  printf("%p, %p, %p\n", &global, &__data_start__, &__data_end__);
  return 0;
}
nm data.exe
00000000004030b0 D __data_end__
0000000000403000 D __data_start__

On Win64, LDC doesn't prepend the C underscore for C symbols (Win32 only), so you'll need to declare it with 2 leading underscores in druntime.

*add FILE definition
*use ms's stdio functions
*another try to fix sections
*phobos will be fixed later
@ghost ghost force-pushed the mingw-fix branch from f09bc42 to df8f861 Compare October 17, 2017 14:22
@ghost
Copy link
Author

ghost commented Oct 17, 2017

Thats what I got when added -d-debug=PRINTF to D_Flags

initSections called
_d_newclass(ci = 00000000004C1F20, core.thread.Thread)
 p = 0000000002720000
p = 0000000002720000
ci = 00000000004C1F20, ci.init.ptr = 00000000005043C0, len = 304
vptr = 00000000005044F0
vtbl[0] = 00000000004C1F20
vtbl[1] = 00000000004676B0
init[0] = 5044f0
init[1] = 0
init[2] = 0
init[3] = 0
init[4] = 0
initialization done
initTLSRanges called
0000000001101F60.Gcx::addRange(000000000049E000, 000000000051EA20)
Found RtlCaptureStackBackTrace
DbgHelp Version 4.0.5

So segfault happens somewhere there

printf("DbgHelp Version %d.%d.%d\n", dbghelpVersion.MajorVersion, dbghelpVersion.MinorVersion, dbghelpVersion.Revision);
}
HANDLE hProcess = GetCurrentProcess();
DWORD symOptions = dbghelp.SymGetOptions();
symOptions |= SYMOPT_LOAD_LINES;
symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS;
symOptions |= SYMOPT_DEFERRED_LOAD;
symOptions = dbghelp.SymSetOptions( symOptions );
debug(PRINTF) printf("Search paths: %s\n", generateSearchPath().ptr);

@ghost
Copy link
Author

ghost commented Oct 17, 2017

Operator ~= is crashing for some reason
Segfault:

auto a = "Hello";
a ~= " world!";

Working:

auto a = "Hello";
a = format("%s world!",a);

Beside of this anything seems to be fine

initSections called
_d_newclass(ci = 00000000004C4050, core.thread.Thread)
 p = 0000000002710000
p = 0000000002710000
ci = 00000000004C4050, ci.init.ptr = 0000000000506850, len = 304
vptr = 0000000000506980
vtbl[0] = 00000000004C4050
vtbl[1] = 000000000046A640
init[0] = 506980
init[1] = 0
init[2] = 0
init[3] = 0
init[4] = 0
initialization done
initTLSRanges called
0000000000F61750.Gcx::addRange(00000000004A0000, 0000000000520A20)
Found RtlCaptureStackBackTrace
DbgHelp Version 4.0.5
Search paths: (null)
Hello world!
processing GC Marks, 0
finiSections called

@kinke
Copy link
Member

kinke commented Oct 27, 2017

I pushed a cleanup commit and verified the changes against current MinGW-w64 headers; should be fine except for [most likely irrelevant] stdin/out/err initialization (MinGW seems to use the normal MSVC infrastructure on Win64, but making ltsmaster use that for MinGW would be tedious and seems unnecessary).

@kinke
Copy link
Member

kinke commented Oct 27, 2017

@wirx6: Please verify that it's still working like before, my MSYS environment isn't set up for building LDC. Will merge then.

@kinke
Copy link
Member

kinke commented Oct 27, 2017

Got my environment to build now; druntime compiles fine.

@kinke kinke merged commit 064840c into ldc-developers:ldc-ltsmaster Oct 27, 2017
@ghost
Copy link
Author

ghost commented Oct 27, 2017

@kinke I made a PKGBUILD script for testing purposes.
Can be built with command makepkg-mingw -s.
pk.zip
pacman -U *.pkg.tar.xz to install in mingw environment.

kinke pushed a commit that referenced this pull request Oct 27, 2017
* add FILE definition
* use ms's stdio functions
* fix sections
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants