Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when changing default calling convention in wpp386 #1285

Open
fafner2000 opened this issue May 5, 2024 · 4 comments
Open

Error when changing default calling convention in wpp386 #1285

fafner2000 opened this issue May 5, 2024 · 4 comments
Labels
bug C++ C++ compiler

Comments

@fafner2000
Copy link

Error when changing default calling convention in wpp386

Hello,

It seems I am breaking Watcom compiler in every way possible recently :-D

I had undefined symbols when linking against a Windows library (specifically libssh2) where names seemed ok but underscores where on the wrong side (for example: "libssh2_session_hostkey_ is an undefined reference" while the library exports the symbol "_libssh2_session_hostkey"), which I understood to be a calling convention problem. In this case the compiler using its default Watcom calling convention, while the library uses cdecl (or possibly stdcall). Whatever the precise calling convention, I tried changing it and ended up with that error:
$WATCOM/lh/cstdio(186): Error! E671: col(43) function modifier cannot be used on a variable
cstdio.h:186 : _WCRTDATA extern __w_FILE _WCDATA __iob[];

Here is a command example that can cause the problem (with any valid test.c file):
wpp386 -ecc -fo=test.o test.c

This seems to be specific to the C++ compiler, as the same command with the C compiler will compile fine:
wcc386 -ecc -fo=test.o test.c

Using -ecw (Watcom calling convention) will compile fine on both, and any other calling convention I tried (cdecl, stdcall, pascal) will fail with C++ compiler.

I may be doing something wrong though. Some C++ specificity that would require an additional parameter maybe? I thought it might be some name-mangling problem, but the error doesn't seem to suggest that.

@jmalak
Copy link
Member

jmalak commented May 5, 2024

it looks like you have missconfigured OW.
Please on which host OS you compile and for which target OS.
You mentioned that you link against Windows library, but from error message it looks like you have OW configured for Linux.
If you cross compile from Linux to Windows then you must setup properly cross-compile environment.
In your case you should have setup INCLUDE environment variable for Windows (by default it is setup for host OS).
see cross-compile
you should setup it to export INCLUDE=$WATCOM/h:$WATCOM/h/nt
Anyway this is known problem #1246

@jmalak jmalak added bug C++ C++ compiler labels May 5, 2024
@fafner2000
Copy link
Author

fafner2000 commented May 5, 2024

Sorry, it was me being overzealous on removing all options that weren't related to the problem (and yes, the target doesn't seem to be related). Here is the environment I use, and the command with the proper target (excluding the WATCOM path):
export PATH="$PATH:$WATCOM/binl64"
export INCLUDE="$WATCOM/h:$WATCOM/h/nt"
wpp386 -bt=nt -ecc -fo=test.o -fr test.cpp

So obviously, I am compiling under a 64-bits Linux system targeting a 32-bits Windows environment. Additionally, I don't reach the link stage (since the error occurs while including a system library, long before reaching my own code).

Edit: In this particular case, I don't event use the Windows library, just trying to compile some random test file lying around which compiles fine otherwise.

@fafner2000
Copy link
Author

I am looking into the problem, and I discovered that the external variable that causes the error indeed has a function modifier through a #define :

#define _WRTLDCONV __declspec(__watcall)    // _comdef.h:59
#define _WCRTDATA _WRTLDCONV                // _comdef.h:122
_WCRTDATA extern __w_FILE _WCDATA __iob[];  // cstdio.h:186

Indeed, if I create a test file containing only this line (and dummy main function):
__declspec(__watcall) extern int dummy;
It compiles fine with -ecw option, but has the same error with -ecc . Additionally, if I change __watcall to __cdecl, it is the other way around: it will compile fine with -ecc , but has an error with -ecw .

As I understand this, the external variable __iob is declared with Watcom calling convention, which seems strange to me. The bug would be that there should be an error when the default calling convention is used, as well as when another one is used.

@jmalak
Copy link
Member

jmalak commented May 5, 2024

It is not simple as it looks like. Take into account that you need to be able link together modules with different calling convention properly. By example __iob is internal OW CRTL symbol for file I/O that it can have some members which contains pointers with OW internal calling convention therefore such variables have different mangling. Take into account that OW run-time libraries are using OW calling convention which you can not change all run-time libraries symbols has appropriate mangling to be properly recognized. each function or variable has specified calling convention by header files. -ec.. option change calling convention for function or variable without specified calling convention only. For C++ compiler it is more complex because there are two linkage C and C++. -ec... options change only C linkage symbols without specified calling convention.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug C++ C++ compiler
Projects
None yet
Development

No branches or pull requests

2 participants