cznic / virtual

github.com/cznic/virtual has moved to modernc.org/virtual
https://godoc.org/modernc.org/virtual
BSD 3-Clause "New" or "Revised" License
20 stars 3 forks source link

Windows support: strategy question (linux emulation or "native") #1

Closed steffengy closed 7 years ago

steffengy commented 7 years ago

Not sure if this is the right repository to place this issue, since it also affects ccir, but i feel it might belong a bit more here.

Is a windows implementation planned?

I see two very different ways of implementing it:

Which of those (or maybe an other even better idea?) would you consider the favorable solution?

Other todos:

cznic commented 7 years ago

@steffengy

Is a windows implementation planned?

Yes, but I hope someone knowing Windows will take care of it.

  • emulating the required linux APIs ("mapping" to the windows equivalents at runtime or at a later stage of the project during compilation)

I think emulating one OS in another, while possible, is too ambitious. virtual uses direct syscalls wherever possible, because I have no intents to rewrite parts of libc or the Linux kernel from scratch ;-)

  • implementing it natively (as the linux implementation, proxying WINAPI calls, this seems to require quite much work?)

IIUC, this is probably the better way.


Couple of notes.

There's a set of platform/architecture neutral VM opcodes, their respective implementations and there's a platform/achitecture specific set. The later set can be tailored using build tags or using the foo_os_arch.go naming scheme. The later option is already in use where amd64 and 386 architectures differ on Linux, so I guess it's easiest to stick with that.

Assuming sqlite is the motivation, I suggest to start the approach like this, because ccir consults virtual when compiling C to recognize functions implemented by the VM itself, aka "builtins":

Easy, isn't it? ;-)

steffengy commented 7 years ago

Thanks for the valuable input!

Assuming sqlite is the motivation

Assumed correctly ;)

Install ccir, go to its libc directory, enter go generate. See what happens and provide feedback so I can make any necessary changes.

go generate:

..\..\virtual\stdio.go:17:2: no buildable Go source files in gopath\src\github.com\cznic\ccir\libc\errno
..\..\virtual\pthread.go:12:2: no buildable Go source files in gopath\src\github.com\cznic\ccir\libc\pthread
..\..\virtual\stdio.go:18:2: no buildable Go source files in gopath\src\github.com\cznic\ccir\libc\stdio
..\..\virtual\unistd.go:14:2: no buildable Go source files in gopath\src\github.com\cznic\ccir\libc\unistd

Which is so far expected. Should virtual really depend on pthreads for windows? (That seems quite linux-specific [isn't used by sqlite on windows], even though there are pthread-shims for windows)

cznic commented 7 years ago

That's a rather unfortunate dependency chain we've got here. generator.go in ccir/libc must import ccir, which imports virtual which imports things under ccir/libc which exactly generator.go should generate ;-)

The proper solution is not clear to me immediately, IIRC, the virtual.IsBuiltin function is the only thing ccir, modulo its tests, needs from virtual.

Let's do the "improper" way: Copy the ccir/libc/errno/errno_linux_yyy.go file to ccir/libc/errno/errno_windows_yyy.go, where yyy is your GOARCH. That will make the constants in that package probably wrong, but I believe it should not matter for now as generator.go generates it's stuff using gcc's headers.

Of course, you need to repeat the step above for any and all other directories missing Windows specific files. Commit to some temp branch before running go generate again because those files will get overwritten once generator.go builds and attempts to do its job. After that you should have the correct values there. Or no values[0] where the source thing does not exist on Windows (like pthread.h). This situation will indicate where a file in virtual will later[1] need to be specialized (like virtual/pthread.go -> virtual/pthread_linux.go, for example).

[0]: Such instances would be probable removed completely later on - once they get no more imported on Windows. [1]: Maybe this will be necessary before ccir/libc/generator can build, I'm not sure, but it seems you're soon going to know ;-)

steffengy commented 7 years ago

@cznic

I created the necessary _windows_amd64 files, now go generate results in:

..\..\virtual\cpu.go:1747: c.lstat64 undefined (type *cpu has no field or method lstat64)
..\..\virtual\cpu.go:1749: c.stat64 undefined (type *cpu has no field or method stat64)
..\..\virtual\cpu.go:1755: c.open64 undefined (type *cpu has no field or method open64)
..\..\virtual\cpu.go:1757: c.fcntl undefined (type *cpu has no field or method fcntl)
..\..\virtual\cpu.go:1759: c.fstat64 undefined (type *cpu has no field or method fstat64)
..\..\virtual\sys_mman.go:28: undefined: syscall.SYS_MMAP
..\..\virtual\sys_mman.go:28: not enough arguments in call to syscall.Syscall6
        have (<T>, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr)
        want (uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr)
..\..\virtual\sys_mman.go:39: undefined: syscall.SYS_MUNMAP
..\..\virtual\sys_mman.go:39: not enough arguments in call to syscall.Syscall
        have (<T>, uintptr, uintptr, number)
        want (uintptr, uintptr, uintptr, uintptr, uintptr)
..\..\virtual\sys_time.go:24: undefined: syscall.SYS_GETTIMEOFDAY
..\..\virtual\sys_time.go:24: too many errors

I have a feeling that quite much more in virtual currently depends on linux.

cznic commented 7 years ago

I have a feeling that quite much more in virtual currently depends on linux.

You're right and it's my fault. IMD, free time is most precious and I thought about porting, but that's about it, sorry.

But please don't give up! We can make it, I'm sure ;-)

I'll create ccir and virtual branches for the Windows port, send you a collaborator's invite and will try to fix the trouble in the parts I am able to do so. The above quoted errors seem to be well in that category. IOW, I'll prepare any stubs needed for you to fill in the implementation any time later.

After you accept the invitations, if you decide to do so, please push to the respective branches the non-building versions you have now and I'll try to do what I can. Please be patient, I cannot really test my part, I don't have any Windows box at hand now, not even a virtualized one, so it will probably take more than one round to get it building at least.

cznic commented 7 years ago

@steffengy Branches are ready, invitations sent.

steffengy commented 7 years ago

@cznic Thanks for getting me started, I committed my local CCIR changes (which consist of only copying the _linux_amd64.go files to _windows_amd64 as discussed above), for virtual there aren't any changes yet.

cznic commented 7 years ago

Thanks! I'm on it.

cznic commented 7 years ago

@steffengy

jnml@4670:~/src/github.com/cznic/ccir/libc$ GOOS=windows go build generator.go
jnml@4670:~/src/github.com/cznic/ccir/libc$ file generator.exe 
generator.exe: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows
jnml@4670:~/src/github.com/cznic/ccir/libc$ 

Seems okay here, but I cannot of course execute it. Please try it on Windows.

steffengy commented 7 years ago

@cznic go build generator.go works. go generate returns:

22:48:34.707583 generator.go:951: exit status 1
exit status 1
libc.go:1: running "go": exit status 1

After applying https://github.com/cznic/cc/pull/60 locally:

23:11:45.068749 generator.go:826: m:\mingw\x86_64-w64-mingw32\include\crtdefs.h:35:44: unexpected identifier size_t, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]
m:\mingw\x86_64-w64-mingw32\include\vadefs.h:35:2: error: "VARARGS not implemented for this compiler"
exit status 1
libc.go:2: running "go": exit status 1

(This is using Nuwen 14.1 (GCC 6.3, Mingw) but also happens with TDM-GCC 5.3)

~If I understand correctly VARARGS aren't supported by cznic/cc yet?~ Seems like cznic/cc isn't able to parse crtdefs.h:35 which is: __MINGW_EXTENSION typedef unsigned __int64 size_t; Not sure if the VARARGS error is related to that or some other problem:

#ifndef _VA_LIST_DEFINED    /* if stdargs.h didn't define it */
#define _VA_LIST_DEFINED
#if defined(__GNUC__)
  typedef __gnuc_va_list va_list;
#elif defined(_MSC_VER)
  typedef char *  va_list;
#elif !defined(__WIDL__)
#error VARARGS not implemented for this compiler
#endif
#endif /* _VA_LIST_DEFINED */

Might also be something going wrong with defines/preprocessing

cznic commented 7 years ago

If I understand correctly VARARGS aren't supported by cznic/cc yet?

No, varargs should work just fine.

jnml@4670:~/src/github.com/cznic/cc$ git branch 
  issue51
  issue57
  issue59
  issue60
  issue62
  issue67
  issue67-debug
  issue67-wips
  issue91
* master
jnml@4670:~/src/github.com/cznic/cc$ git log -1
commit d5c3a9df03dc0d4053f7d1ba6f4e4622d6d645dc
Author: Jan Mercl <0xjnml@gmail.com>
Date:   Wed Apr 12 01:05:53 2017 +0200

    Fix anonymous struct/union members flattening.
jnml@4670:~/src/github.com/cznic/cc$ grep -ni varargs *
cc.go:419:// See https://gcc.gnu.org/onlinedocs/gccint/Varargs.html
grep: testdata: je adresářem
jnml@4670:~/src/github.com/cznic/cc$ 

The above and what you sent seems to indicate the error message "VARARGS not implemented for this compiler" probably comes from an #error directive. Why? Good question I don't have an answer for ATM.

Can you please take a look at m:\mingw\x86_64-w64-mingw32\include\vadefs.h:35:2 and around to look what the surround (guess) #if or #ifdef condition is? I will meanwhile try to google the file as well. Thank you.

steffengy commented 7 years ago

@cznic Already updated the message, seems like you were too fast :)

cznic commented 7 years ago

Looking here I think we probaly need #define _MSC_VER somenumber on Windows platform. This is due to a hack where I remove any GNUC|GCC #define from the set of predefined macros. It's necessary because otherwise GNU libc wants very GCC specific things.

steffengy commented 7 years ago

Looking here I think we probaly need #define _MSC_VER somenumber on Windows platform.

Hopefully that won't pull in anything too MSVC C++ specific, but I also do not see what else would help here.

23:11:45.068749 generator.go:826: m:\mingw\x86_64-w64-mingw32\include\crtdefs.h:35:44: unexpected identifier size_t, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile] Seems like cznic/cc isn't able to parse crtdefs.h:35 which is: __MINGW_EXTENSION typedef unsigned __int64 size_t;

That part is a bug (or not implemented), I guess?

cznic commented 7 years ago

I hoped for GCC on Windows to also use its own (GNU libc) headers, but it doesn't seem to be the case. It took a bit of tweaking to make it all work with the GNU libc headers...

cznic commented 7 years ago

That part is a bug (or not implemented), I guess?

I think this can be resolved by adding

#define __MINGW_EXTENSION

to builtin.h (in ccir/libc).

steffengy commented 7 years ago

I added the following as a test to ccir/libc/builtin.h:

#define _MSC_VER 
#define __MINGW_EXTENSION

This didn't change any of the error messages, which is strange, since atleast the VARARGS error should surely disappear. Do I need to follow some additional steps that these changes are applied?

cznic commented 7 years ago

This didn't change any of the error messages, which is strange, since atleast the VARARGS error should surely disappear.

Very strange, I must be missing something.

Not really related to the above, but maybe __int64 is not defined to be a type and it neeeds to be added to builtin.h on Windows?

cznic commented 7 years ago

#define _MSC_VER is possibly not enough, try giving it a non zero value, like in #define _MSC_VER 1, for example.

steffengy commented 7 years ago

Also tried that, adding some random stuff like abc to builtin.h which should be syntactically invalid on it's own also doesn't result in any change of the errors (which it surely should). So I guess it doesn't actually look at this file?

cznic commented 7 years ago

I'll try to add a cpp hook to ccir/libc/generator.go, it may help in debugging the issue.

cznic commented 7 years ago

Option added, please pull and try go run generator.go -cpp instead of go generate and redirect stderr output to some log file to inspect. You can also attach it here at issue comments for me to have a look, I think it's possible.

steffengy commented 7 years ago

Done:

# 22 "predefined.h"
typedef char *__builtin_va_list;
# 548 "mingw\\x86_64-w64-mingw32\\include\\_mingw.h"
const char *__mingw_get_crt_info (void);
# 35 "mingw\\x86_64-w64-mingw32\\include\\crtdefs.h"
typedef unsigned __int64 size_t;
00:00:39.304571 generator.go:847: mingw\x86_64-w64-mingw32\include\crtdefs.h:35:44: unexpected identifier size_t, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]
mingw\x86_64-w64-mingw32\include\vadefs.h:35:2: error: "VARARGS not implemented for this compiler"
exit status 1

EDIT: seems like builtin.h is indeed somehow not applied. adding _MSVC_VER to predefined.h makes the VARARGS error disappear.

cznic commented 7 years ago
# 35 "m:\\mingw\\x86_64-w64-mingw32\\include\\crtdefs.h"
typedef unsigned __int64 size_t;
00:00:39.304571 generator.go:847: mingw\x86_64-w64-mingw32\include\crtdefs.h:35:44: unexpected identifier size_t, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]

The line with the crtdefs.h:35:44 error seems to have only 32 characters, why is the error column 44? Do you have any idea?

Anyway, please look into the log, if __int64 is typedefed or #defined any place before usage here. Thanks.

edit: typos

cznic commented 7 years ago

EDIT: seems like builtin.h is indeed somehow not applied.

Have no idea why, it's imported quite directly.

steffengy commented 7 years ago

The crtdefs.h:35:44 seems to have only 32 characters, why the error column is 44?

"__MINGW_EXTENSION typedef unsigned __int64 size_t;".length == 50

Anyway, please look into the log, if __int64 is typedefed or #defined any place before usage here.

With the following in predefined.h

#define _MSC_VER 1
#define __MINGW_EXTENSION 1

the (entire) log is:

# 25 "predefined.h"
typedef char *__builtin_va_list;
# 33 "m:\\mingw\\x86_64-w64-mingw32\\include\\vadefs.h"
typedef char * va_list;
# 548 "m:\\mingw\\x86_64-w64-mingw32\\include\\_mingw.h"
const char *__mingw_get_crt_info (void);
# 35 "m:\\mingw\\x86_64-w64-mingw32\\include\\crtdefs.h"
typedef unsigned __int64 size_t;
00:12:16.470538 generator.go:847: m:\mingw\x86_64-w64-mingw32\include\crtdefs.h:35:44: unexpected identifier size_t, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]
exit status 1

Adding e.g. #define __int64 int [which isn't quite right but fine to track this compiler issue here] to also predefined.h (definitely also not working in builtin.h) seems to do it and gives me another error (the next one):

ctype_windows_amd64.h:10:23: unexpected identifier __ptlocinfo, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]
cznic commented 7 years ago

My comment about <builtin.h> was misleading, sorry, that's used in a later stage.

I think your experiments are correct, we have to, guarded by some #ifdefs, add some #defines to predefine.h.

Sorry, it's few weeks I've been into these places and got meanwhile focused elsewhere...

cznic commented 7 years ago

ctype_windows_amd64.h:10:23: unexpected identifier __ptlocinfo, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]

Such implementation defined things, note the two leading underscores, are why we are slurping the predefined macros from cpp -dM. What does that, if I recall the command correctly, shows?

cznic commented 7 years ago

BTW, have I told you how much I dislike C after doing this project? ;-)

steffengy commented 7 years ago

Haha you probably now know several more edge cases than before :)

cpp -dM doesn't appear to do anything. Maybe __ptlocinfo comes from mingw-w64-headers/crt/ctype.h ?

cznic commented 7 years ago

Haha you probably now know several more edge cases than before :)

Always look on the bright side ;-)

cpp -dM doesn't appear to do anything.

Yeah, on Linux it should be $ cpp -dM /dev/null, please try (guessed) c:\> cpp -dM NUL or something like that... We rely on the system CC predefines a lot.

Maybe __ptlocinfo comes from mingw-w64-headers/crt/ctype.h ?

If only I had any idea what it stands for. Some 'pointer to location info'?

cznic commented 7 years ago

Or 'thread local info' maybe?

steffengy commented 7 years ago

Since it's quite big not directly here (cpp -dM NUL works): https://gist.github.com/steffengy/690934e545549c280efa6731ac4550eb

pthreadlocinfo "points" to threadlocaleinfostruct.

cznic commented 7 years ago

Since it's quite big not directly here (cpp -dM NUL works): https://gist.github.com/steffengy/690934e545549c280efa6731ac4550eb

Thanks. The output of cpp -dM seems okay. That's all I know.

We're now in the Windows/C land and there's not much left what I can help you with. Not that I don't want to, I just don't know enough about Windows (and the GCC implementation on that platform).

Please try to investigate further. Don't hesitate to ask for any help I can provide you with. (That means mostly the Go side, unfortunately.) We can always ask other/more experts if necessary. Last, but not least, it's getting a bit late at night here and I should probably get some sleep.

My wish for this weekend is to try and start coding ccgo. FYI: The ccir/libc .h and .go stuff will be used by it as well, meaning this work of your's is not going to be wasted.

Also, please add yourself to the CONTRIBUTORS and/or AUTHORS files in both ccir and virtual so we do not forget to do that later before merging the issue1 branches to master.

steffengy commented 7 years ago

Yeah I'll try to look into that stuff once I got proper defines for __int64 and will update here once there are some exciting news.

The windows land itself is often quite annoying, MSVC even more but MINGW is IMHO not better buf (except for interoperability) worse.

steffengy commented 7 years ago

Also signing out for today. Regarding unexpected identifier __ptlocinfo for extern pthreadlocinfo __ptlocinfo;

seems like that it's actually because of pthreadlocalinfo not being recognized.

From my point this seems like a bug, where typedefs are not semantically recognized for such cases?

cznic commented 7 years ago

From my point this seems like a bug, where typedefs are not semantically recognized for such cases?

Of course it can be a bug. If you can create a simple reproduction case, which some other C compiler accepts, please fill a cc issue, thank you.

steffengy commented 7 years ago

@cznic LIBC builds now for mingw64 :)

Happy for feedback, especially regarding the workaround + adding of types here: https://github.com/cznic/ccir/commit/c77c34348497f3d1b39778e50a099d6b66eaf18e#diff-c0cbe5fc2255f37eda2c46a58fd84141R930

One issue seems to be:

string_windows_amd64.h:23:100: unexpected ',', expected declarator or optional init declarator list or one of ['(', '*', ';', identifier]

references cznic/cc#94

This seems to be caused because it's a struct-redefinition of pthreadlocinfo using multiple declarators. (It is included in most .h files, maybe moving to builtin.h and removing it from builder.go works, but I don't see how that could work) Any idea how to fix that?

cznic commented 7 years ago

Assuming "LIBC builds" means that running go generate in ccir/libc works without errors, I'm not sure from where or at which step the error in the header file is reported. Is that when go test is invoked in ccir? Please clarify.

Also, please keep pushing your intermediate local changes of the issue1 branches so I can early test for potential breakages of the Linux version. Don't worry about size of the commits or proper commit messages if you think the later merge to master branch will be squashed.

In any case, it seems your porting effort is making great progress already!

I will get to look cznic/cc#94 in a couple of hours, I hope.

steffengy commented 7 years ago

Assuming "LIBC builds" means that running go generate in ccir/libc works without errors, I'm not sure from where or at which step the error in the header file is reported. Is that when go test is invoked in ccir? Please clarify.

Sorry, yeah that happens when I run go test when for example a GCC-torture test relies on string.h and stdlib.h, which both contain a definition of pthreadlocinfo, which fails because of cznic/cc#94.

I'm currently also trying to find out what's going on there, but still having a hard time finding the relevant place in the parser.

cznic commented 7 years ago

Wow! Do some tests already pass? You're light years ahead compared to what I thought is possible only yesterday ;-)

steffengy commented 7 years ago
--- FAIL: TestTCC (0.65s)
        all_test.go:359: ..\cc\testdata\tcc-0.9.26\tests\tests2\22_floating_point.c: FAIL
                cc.Parse: gopath\src\github.com\cznic\ccir\libc\math_windows_amd64.h:23:100: unexpected ',', expected declarator or optional init declarator list or one of ['(', '*', ';', identifier]
        all_test.go:368: 47/55 ok
        all_test.go:370: failures: 8
--- FAIL: TestGCCExec (10.51s)
        all_test.go:359: ..\cc\testdata\gcc-6.3.0\gcc\testsuite\gcc.c-torture\execute\20000910-2.c: FAIL
                cc.Parse: gopath\src\github.com\cznic\ccir\libc\string_windows_amd64.h:23:100: unexpected ',', expected declarator or optional init declarator list or one of ['(', '*', ';', identifier]
        all_test.go:368: 1222/1250 ok
        all_test.go:370: failures: 28
--- FAIL: TestC4 (0.02s)
        all_test.go:792: gopath\src\github.com\cznic\ccir\libc\stdlib_windows_amd64.h:23:100: unexpected ',', expected declarator or optional init declarator list or one of ['(', '*', ';', identifier]
--- FAIL: TestSqlite (0.06s)
        all_test.go:792: gopath\src\github.com\cznic\ccir\libc\stdlib_windows_amd64.h:23:100: unexpected ',', expected declarator or optional init declarator list or one of ['(', '*', ';', identifier]
FAIL
exit status 1
FAIL    github.com/cznic/ccir   11.312s

I guess that means some already pass ;-)

steffengy commented 7 years ago
    ir.LinkMain: ..\cc\testdata\tcc-0.9.26\tests\tests2\40_stdio.c:5:14: undefined fopen
                # ccir.New
                # [0]: *ir.FunctionDefinition {gopath\src\github.com\cznic\ccir\libc\builtin.h:38:15 __builtin_strlen func(*int8)uint64 ExternalLinkage } [__s]
                0x00000         panic                           ; gopath\src\github.com\cznic\ccir\libc\builtin.h:38:15
                # [1]: *ir.FunctionDefinition {gopath\src\github.com\cznic\ccir\libc\builtin.h:39:17 __builtin_bswap64 func(uint64)uint64 ExternalLinkage } [x]
                0x00000         panic                           ; gopath\src\github.com\cznic\ccir\libc\builtin.h:39:17

What does output like that actually mean? Seems like builtin.h comes into play now, but since stdio.h for windows contains those definitions I guess this is "one stage further" now?

EDIT: likely fopen should point to __builtin_fopen (which is in builtin.h)

cznic commented 7 years ago

Blind shot: https://github.com/cznic/virtual/commit/951399f7ea15f610de34277e3f938fd04d5aa676 Please try, thank you.

   # ccir.New
                # [0]: *ir.FunctionDefinition {gopath\src\github.com\cznic\ccir\libc\builtin.h:38:15 __builtin_strlen func(*int8)uint64 ExternalLinkage } [__s]
                0x00000         panic                           ; gopath\src\github.com\cznic\ccir\libc\builtin.h:38:15
                # [1]: *ir.FunctionDefinition {gopath\src\github.com\cznic\ccir\libc\builtin.h:39:17 __builtin_bswap64 func(uint64)uint64 ExternalLinkage } [x]
                0x00000         panic                           ; gopath\src\github.com\cznic\ccir\libc\builtin.h:39:17

This lists/dumps the objects ir.LinkMain was passed to aid in debugging linker failure.

steffengy commented 7 years ago

@cznic It may've been blind but spot on :) Now I atleast know that for the future errors of this kind, I'll have to take a look at virtual.

cznic commented 7 years ago

EDIT: likely fopen should point to __builtin_fopen (which is in builtin.h)

That could be the proper solution. It depends on how GCC on Windows solves the 32/64 bit file sizes schizma of many libc functions. This solves it for Linux.

edit: fixed link

cznic commented 7 years ago

Now I atleast know that for the future errors of this kind, I'll have to take a look at virtual.

Yeah, you're now entering the real land-of-fun, aka the virtual builtins B-)

cznic commented 7 years ago

FYI: Builtins are implemented as "abnormal" functions having a single panic instruction. That's a pattern recognized in virtual.Load and replaced by a call to the corresponding Go builtin. Like fopen64 you've just met.

steffengy commented 7 years ago

GCC & TCC test suites now pass on windows. Now the real fun begins.

cznic commented 7 years ago

GCC & TCC test suites now pass on windows. Now the real fun begins.

Wonderful. Just fantastic!