open-watcom / open-watcom-v2

Open Watcom V2.0 - Source code repository, Wiki, Latest Binary build, Archived builds including all installers for download.
Other
958 stars 157 forks source link

OWCC's "-mabi" Option Does Not Affect External Decorations #75

Closed ArmstrongJ closed 10 years ago

ArmstrongJ commented 10 years ago

I've been using owcc on GNU/Linux to attempt to build a library (openssl, to be specific), and the "-mabi=stdcall" does not behave quite as I expected. Normally using wcl386 directly, I would specify "-5s," for example, to allow linking with the Win32 API. However, with owcc, the decorations are not properly modified, causing linking to fail. More specifically, regardless of the value of "-mabi=," the decorations are still following the Watcom calling convention decorations. With wcl386 and the "-[3,4,5,6][r,s]" options, the decorations are modified appropriately.

Rather than submit a patch directly, I was wondering what others might think the proper fix would be to get the decorations working properly during linking using the POSIX wrapper. I wouldn't have a problem with allowing the "-[3,4,5,6][r,s]" options directly (I have a branch where this works fine), but I'm not sure that's ideal.

@jmalak I'm willing to implement whatever people think might be the best solution.

jmalak commented 10 years ago

the owcc option -mabi=stdcall is the same as wcl.. option -ecs these options are designed for specific purpose when you need change default calling convention but if you need link Win32 API you don't need change default calling convention because each WIN32 API function has explicitly defined calling convention in header files, therefore it always use stdcall/cdecl calling convention even if you use -mabi or -ec.. options

ArmstrongJ commented 10 years ago

I think I made an incorrect statement in my original report. I cannot seem to create a, for example, DLL using owcc that is both a) using stdcall on Win32 and b) decorated properly so as to be understood by other Win32 binaries. The "-5s" and similar options do take care of this problem automatically.

However, that said, I do seem to remember the -mabi option being set to "stdcall" causing some very strange behavior when linking with the Win32 API. I don't think it actually worked. That could very well be another bug based on what you say above.

All I'd really like is the "-5s" family of options available from owcc. Those options work perfectly.

I'll fire up the project on which I was attempting to use owcc (it was openssl's libssl) and see exactly what the issue was.

jmalak commented 10 years ago

It looks like you need cdecl calling convention not stdcall. Generaly there are 3 calling convention, WIN32 API (defined in header file) CRTL ( option -3r/s and C/C++ header files definition ) and user code -mabi or -ec... options. All 3 must be setup properly. If you give me more details about linker reported problems I can identify which one is incorrect.

jmalak commented 10 years ago

I have a note. owcc wraper logic contains 2 options -mregparm= 'r' or 's' -mabi= 'cdecl' or 'stdcall' or ...... By default 'watcall' is default calling convention with passing parameters by registers if you use -mregparm=r it doesn't change anything, it is default setup if you use -mregparm=s it changes 'watcall' to be 'cdecl' with passing parameters on stack, therefore it changes also defaut calling convention to 'cdecl', it affect all CRTL calls/data (they have specified 'watcall' in header files) and all calls/data which don't have specified calling convention (mostly user code)

the -mabi option realy change only default calling convention, don't affect any specified calling convention

Generaly if you want create modules linked with non-watcom CRTL then you should use -mregparm='s' which switch 'watcall' calling convention to 'cdecl' globaly, it has affect to calls/data with 'watcall' or without any calling convention

If you want link non-watcom modules which call CRTL with watcom CRTL you can also use -mregparm=s to ensure that CRTL with cdecl calling convention will be used, there is another solution without -mregparm=s but you must explicitly specify CRTL with cdecl calling convention to linker (clib3s.lib)

Usage of -mregparm and -mabi otions can help you with interfacing to non-watcom modules/code. But their usage depend on each case.

ArmstrongJ commented 10 years ago

Sorry for taking so long to reply to your questions, @jmalak. The compilation procedure for openssl is a bit tedious because it tries to use ar to build libraries, and OpenWatcom doesn't really have a clean, compatible wrapper for that utilty (not a criticism, just a fact).

I'm trying to build a static library for libssl and libcrypt as shipped by OpenSSL. The specifics of the project aren't particularly important. However, the build process I'm using is to allow GNU autotools to build the Makefile, requesting a MinGW build, then manually modifying the Makefile to use owcc and a few OpenWatcom-specific options. The ./configure script was realtively unhappy if you ask it to use owcc from the start (again, not OpenWatcom's fault or a criticism of it in any way).

Anyway, as a first try, I used owcc with the following flags:

-mabi=stdcall -mregparm=0 -O3 -bt=nt

This fails pretty quickly with the following error:

o_names.c(94): Error! E1010: Type mismatch
o_names.c(94): Note! I2003: source conversion type is 'int (__watcall *)(char const *__p1,char const *__p2)'
o_names.c(94): Note! I2004: target conversion type is 'int (*)(char const *__p1,char const *__p2)'
Error: Compiler returned a bad status compiling 'o_names.c'

The offending code is paraphrased below:

...
# define OPENSSL_strcmp strcmp
...
typedef struct name_funcs_st
    {
    unsigned long (*hash_func)(const char *name);
    int (*cmp_func)(const char *a,const char *b);
    void (*free_func)(const char *, int, const char *);
    } NAME_FUNCS;
...
    NAME_FUNCS *name_funcs;
...
        name_funcs->cmp_func = OPENSSL_strcmp; /* <- This is line 94 where the error occurs */

So if I remove the "-mabi=stdcall" flag, and compilation will proceed. The "-mregparm=0" (specifying using stack-based calling) allows compilation to proceed. I had assumed that "-mregparm=0" would be similar to using, for example, "-5s" (ignoring the CPU-specifying integer) when using wcl386.

When I build my libraries and get them into a nice watcom-compatible .lib, I can now try to link against my main project. So lets say I do that. My main project is a more generic OpenWatcom project, relying on "-6s" and using wcl386 to build. When I link, I receive a number of undefined functions that should have been provided by my library that was built using owcc. When I examine the listing, I can see that the functions in the library are, in libcrypto.lib for example, defined as:

ACCESS_DESCRIPTION_free_../home/jeff/workspace/openssl-1.0.1h/crypto/x509v3/v3_info.c
ACCESS_DESCRIPTION_it_../home/jeff/workspace/openssl-1.0.1h/crypto/x509v3/v3_info.c
ACCESS_DESCRIPTION_new_../home/jeff/workspace/openssl-1.0.1h/crypto/x509v3/v3_info.c
AES_bi_ige_encrypt_..../home/jeff/workspace/openssl-1.0.1h/crypto/aes/aes_ige.c
AES_cbc_encrypt_......./home/jeff/workspace/openssl-1.0.1h/crypto/aes/aes_cbc.c
AES_cfb128_encrypt_..../home/jeff/workspace/openssl-1.0.1h/crypto/aes/aes_cfb.c
AES_cfb1_encrypt_....../home/jeff/workspace/openssl-1.0.1h/crypto/aes/aes_cfb.c
AES_cfb8_encrypt_....../home/jeff/workspace/openssl-1.0.1h/crypto/aes/aes_cfb.c
AES_ctr128_encrypt_..../home/jeff/workspace/openssl-1.0.1h/crypto/aes/aes_ctr.c
AES_decrypt_........../home/jeff/workspace/openssl-1.0.1h/crypto/aes/aes_core.c
...

So the functions appear to be decorated as watcall even though I had asked for stack-based calling.

My only desire in this bug report is to get the same delightfully simple behavior I get by using "-5s" when compiling with wcl386. I've built a version of owcc that allows "-<4,5,6><r,s>" to pass through to the underlying compiler, and all these issues with decorations and odd linking problems disappear.

jmalak commented 10 years ago

Sorry for incorrect option -mregparm=s, you are right proper is -mregparm=0.

Options mapping owcc -> wcl... -mtune=i3 -mregparm=s owcc optins are equivalent for wcl... options -3s. -mtune=i6 -mregparm=s -> -6s etc. These options switch watcall to cdecl, that all calling without defined calling convention or watcall is realy cdecl.

Don't use option -mabi= any way.

There are a few problems common for non-WATCOM projects. Projects expect default calling convention cdecl and relay on this in code instead of expect general calling convention or define calling convention explicitly by some macro. Most terrible project is openpng, which hard coded calling convention for CRTL C-function into code because they expected only use of MS CRTL. Some projects understand WATCOM calling convention, but implementation is sometimes only partial, that without patching build makefiles, source code, etc. you can not get something useful with Watcom native calling convention.

Back to openssl project and OW. I always used MS VC related things not MinGw. In the past I was testing to build openssl project by OW. But it was not possible without patching. Main problem is that you can not use assembly modules with OW default calling convention, you must compile only pure C version. Next problem is exported name for DLL's. Generaly, problems should be resolved by use cdecl as default calling convention (-3s option). In this case you must strictly use -3s option for compiling any part of openssl. To better understand of your problem I need full map file from linking process. From this file I will be able to get info about modules which were compiled with wrong calling convntion. Please, e-mail me your map file.

jmalak commented 10 years ago

Anyway wlib can be switched to ar mode by defining WLIB$AR environment variable or renaming to ar name (see code in bld/nwlib/c/cmdline.c)

ArmstrongJ commented 10 years ago

@jmalak thanks for the assistance. When I went back to check, my last message where I received the incorrect (in my opinion, at least) decorations on the functions were using the owcc flags "-mregparm=0" like I thought. Out of interest, I added the flag "-mtune=i6" as well, which you state should map to simply saying "-6s" with wcl386. However, when I build with these options, I still do get the incorrect decorations on my library's function (trailing underscore):

ACCESS_DESCRIPTION_free_../home/jeff/workspace/openssl-1.0.1h/crypto/x509v3/v3_info.c
ACCESS_DESCRIPTION_it_../home/jeff/workspace/openssl-1.0.1h/crypto/x509v3/v3_info.c
ACCESS_DESCRIPTION_new_../home/jeff/workspace/openssl-1.0.1h/crypto/x509v3/v3_info.c
AES_bi_ige_encrypt_..../home/jeff/workspace/openssl-1.0.1h/crypto/aes/aes_ige.c
AES_cbc_encrypt_......./home/jeff/workspace/openssl-1.0.1h/crypto/aes/aes_cbc.c
...

So out of interest, I tried using my owcc patched to pass "-6s" through to the compiler. The resultant file listing is now:

ACCESS_DESCRIPTION_free../home/jeff/workspace/openssl-1.0.1h/crypto/x509v3/v3_info.c
ACCESS_DESCRIPTION_it../home/jeff/workspace/openssl-1.0.1h/crypto/x509v3/v3_info.c
ACCESS_DESCRIPTION_new../home/jeff/workspace/openssl-1.0.1h/crypto/x509v3/v3_info.c
AES_bi_ige_encrypt...../home/jeff/workspace/openssl-1.0.1h/crypto/aes/aes_ige.c
AES_cbc_encrypt......../home/jeff/workspace/openssl-1.0.1h/crypto/aes/aes_cbc.c
...

There are no trailing underscores, as expected, in the case where "-6s" (passed through owcc) is used.

The above points out that the "-6s" flag and its other processor spec bretheren perform some additional work beyond just activating what you've stated is the equivalent ("-mtune=i6 -mregparm=s"). Some other work is done by wcl386's flag that can't be achieved currently with available owcc flags.

I don't have any problem building OpenSSL beyond one or two minor changes to C code and disabling assembly routines. However, I am only building the necessary static libraries (libcrypto.lib and libssl.lib) for linking to a DLL later in an outside project (the Python standard library, actually). I'm not building any of OpenSSL's included applications or test routines. I only mentioned OpenSSL as a reference to the complicated nature of the code base rather than any particular problem with compiling it.

jmalak commented 10 years ago

Sorry, I did the same mistake as before, proper options are -mtune=i3 -mregparm=0

If you have any similar problems then try option -v for owcc. for comparision you can use wcl386 without -zq option. It should display real compiler line (translated by owcc or wcl..) that we will be able determine what is wrong. Do you have any log with owcc command line?

I didn't have problem with compiling openssl library, but I have problems with proper linking DLL to application, but I was creating DLL with native OW registry calling convention (__watcall). With cdecl it should be simple.

ArmstrongJ commented 10 years ago

@jmalak I think I have a handle on the problem. I'm not sure why in my previous email I reported that "-mregparm=0 -mtune=i6" didn't work, but it seems to work fine. Using the "-v" switch, I clearly see the "-6s" switch passed to wcl386 from owcc. So it does work. Please excuse my incorrect previous report.

There still is an issue, though. If one does use "-mregparm=0" by itself with owcc, it has no effect. Using the "-v" switch with "-mregparm=0", the wcc386 command shows no change. Consider the following:

owcc flags observed wcc386 translation
-mtune=i6 -mregparm=0 -6s
-mtune=i6 -6r
-mregparm=0 nothing

The "-mregparm" switch must be accompanied by an "-mtune" switch, but the reverse is not true. I'd consider this situation a bug. An "-mregparm=0" switch alone should probably trigger a "-3s" flag.

Again, sorry for the earlier misleading report. I'm not sure why I didn't see the proper result on my initial try with "-mtune=i6 -mregparm=0".

jmalak commented 10 years ago

I think so it is bug. Yes, in this case default target CPU 3 should be used. I will fix it.

jmalak commented 10 years ago

It is fixed now by https://github.com/open-watcom/open-watcom-v2/commit/40647823ff59f260a12d96abf56f2e3a879ec025

ArmstrongJ commented 10 years ago

@jmalak I'm waiting on a build on my end, but the code looks fine. I'll give it a shot today or tomorrow. Thanks for your help and attention.

ArmstrongJ commented 10 years ago

@jmalak everything looks fine after 40647823ff59f260a12d96abf56f2e3a879ec025. Feel free to close this bug, and thanks for your help!

jmalak commented 10 years ago

I little rework owcc to support -march option 492ecd12fcb35a349b0e3f60593561a15c7b0d98 that now you can build for any target from any host (16/32/64-bit)