> On 10 Dec 2018, at 15:11, Magnus Ihse Bursie <magnus.ihse.bur...@oracle.com> 
> wrote:
> 
> 
> 
> On 2018-12-10 16:02, Alexey Ivanov wrote:
>> 
>> 
>> On 10/12/2018 10:41, Magnus Ihse Bursie wrote:
>>> 
>>> 
>>> On 2018-12-07 22:18, Simon Tooke wrote:
>>>> Looking at the code, it seems (to me) the "correct" thing to do is to is
>>>> to create a Windows-specific version of dbgsysBuildFunName() in
>>>> linker_md.c, and have it decorate the function name as appropriate for
>>>> 32-bit windows.  Note that in transport.c, you'd need to pass in the
>>>> parameter stack size (the bit after the @), but it could at least behave
>>>> properly on 32 vs 64 bit Windows.
>>>> 
>>>> Notice this approach is already used for the library name, via
>>>> dbgsysBuildLibName()
>>>> 
>>>> If the function is never intended to be called by Java via JNI, then it
>>>> should never have been declared JNICALL in the first place - but that
>>>> ship has sailed.
>>>> 
>>>> I don't think changing the decorated exported name to undecorated is a
>>>> good idea, as it obfuscates the calling convention used.
>>>> 
>>> Good analysis, Simon. I agree. 
>>> 
>>> I have now looked more into the situation. In fact, it looks a lot like 
>>> JDWP has been broken on Windows 32-bit for a long time, but we have patched 
>>> around the issue in the JDK by using /export. This is the spec we're 
>>> dealing with: 
>>> https://docs.oracle.com/javase/10/docs/specs/jdwp/jdwp-transport.html. I 
>>> quote:
>>> 
>>>> The transport library must export an onload function with the following 
>>>> prototype:
>>>> 
>>>> JNIEXPORT jint JNICALL
>>>> jdwpTransport_OnLoad(JavaVM *jvm,
>>>>                      jdwpTransportCallback *callback,
>>>>                      jint version,
>>>>                      jdwpTransportEnv** env);
>>>> 
>>>> This function will be called by the JDWP (or other agent) when the library 
>>>> is loaded.
>>>> 
>>>> 
>>> 
>>> Nothing here says anything that the function should be exported using 
>>> anything other than the normal _stdcall (implied by JNICALL) name mangling 
>>> rules. However, JDWP has not been working according to the spec and looking 
>>> for the correct symbol, and while we could have noticed that in the JDK, we 
>>> didn't, because someone (long ago) added /export:jdwpTransport_OnLoad as a 
>>> workaround to the affected libraries, instead of fixing JDWP.
>> 
>> This means that we cannot change the calling convention: it must stay as it 
>> is now.
>> 
>> I think JDWP has always been working according to the spec. Using __stdcall 
>> is the recommended calling convention for Win32 and for DLLs in particular. 
>> Usually function names are exported undecorated in DLL. (If my memory serves 
>> me well, older Microsoft tools exported extern "C" __stdcall functions 
>> undecorated.)
> So then the question becomes: what does the spec mean? That the __stdcall 
> convention should be used, or that the function name should be explicitly 
> exported under a non __stdcall-convention name? Neither behavior seems 
> clearly written out, so this is left to an implicit interpretation of what 
> that "usually" means..?

A couple of MSFT quotes on name decoration from 
https://docs.microsoft.com/en-gb/cpp/build/reference/decorated-names?view=vs-2017
 says;

> Normally, you don't have to know the decorated name to write code that 
> compiles and links successfully. Decorated names are an implementation detail 
> internal to the compiler and linker.

> Name decoration is also important when linking to code written in other 
> programming languages or using other compilers. Different compilers use 
> different name decoration conventions. When your executable links to code 
> written in another language, special care must be taken to match the exported 
> and imported names and calling conventions.

And we should also keep in mind that MSFT itself doesn’t use name mangling in 
the core windows API.

I still see this |jdwpTransport_OnLoad| not much different than 
|JNI_CreateJavaVM| in the context of it’s availability and accessibility from 
outer world.

>> 
>> I believe this — exporting the undecorated function names — allows for 
>> interoperability between 32 bit and 64 bit in cases where you load a DLL and 
>> dynamically look up a function in it.
>> 
>> There were too many /export options to export Win32 functions undecorated 
>> for this one to be an accident rather than the intention.
> How do you mean? 
>> 
>>> Now, given that we've shipped code that didn't adhere to the specs for so 
>>> long, we can probably not break that behavior. Instead, I propose we amend 
>>> dbgsysBuildFunName() so that on Windows 32-bit, it looks for both the 
>>> "jdwpTransport_OnLoad", and the symbol as mangled by _stdcall rules. I also 
>>> propose that if both symbols are present, the _stdcall named one should 
>>> take precedence, since that's according to the spec (and the other is just 
>>> a fallback to maintain backwards compatibility).
>> 
>> Since removing JNICALL is not an option, there are only two options:
>> 
>> 1. Add /export option to the Makefile or pragma-comment to the source file;
>> 2. Lookup the decorated name _jdwpTransport_OnLoad@16 for Win32 with 
>> fallback to undecorated one.
> Yes.
> 
> I think the correct solution here is 2.

Does keeping name mangling in-place gives anyone any value? It would probably 
only add the overhead of making the callers compute the stack size of the 
parameters. And I couldn’t find any sign or history of changes but name 
mangling, theoretically, it could change over versions of compilers.

The pragma-comment approach could also be overly simplified as shown 
https://stackoverflow.com/a/41910450, which will leave us with a single line 
addition to the function body as;

#pragma EXPORT

which is from my point of view a simpler (and maintainable) approach than 
adding a decorated name lookup logic.

Regards,

Ali

>> 
>> 
>> I just wonder how it's possible to implement a generic dbgsysBuildFunName 
>> for an arbitrary function without knowing the size of function parameters. 
>> Could it be the reason why most DLLs export __stdcall functions undecorated?
> (I assume you mean dbgsysFindLibraryEntry; there is a dbgsysBuildFunName as 
> well but it appears to be dead code.)
> 
> The dbgsysFindLibraryEntry does not need to work with an arbitrary function. 
> It's implemented in jdk.jdwp.agent, for the sole reason of locating the 
> jdwpTransport_OnLoad function.
> 
> In general, I assume this to hold true. If you don't know the signature of 
> the function you want to call, you're screwed anyway, regardless of calling 
> convention.
> 
> /Magnus
> 
>> 
>> Regards,
>> Alexey
>> 
>>> 
>>> /Magnus
>>>> -Simon Tooke
>>>> 
>>>> 
>>>> On 12/7/2018 2:09 PM, Alexey Ivanov wrote:
>>>> 
>>>>> Hi Andrew,
>>>>> 
>>>>> Sorry for my belated reply.
>>>>> Yes, it's also an option… however, this solution seems to be
>>>>> overcomplicated to export one function or two. The calling convention
>>>>> of exported functions for JVM cannot be changed, they can be called
>>>>> from third-party software.
>>>>> 
>>>>> If the function is used internally-only, its calling convention can be
>>>>> changed as long as all components are updated.
>>>>> 
>>>>> Thank you for the pointer to another approach used to handle name
>>>>> decorations of __stdcall functions. It looks we have to work out a
>>>>> common approach to this problem.
>>>>> 
>>>>> Regards,
>>>>> Alexey
>>>>> 
>>>>> On 27/11/2018 18:49, Andrew Luo wrote:
>>>>> 
>>>>>> By the way, in hotspot we are generating a .def file dynamically
>>>>>> while keeping the JNICALL calling convention (for symbols such as
>>>>>> JNI_CreateJavaVM) I believe (just by looking through the code in
>>>>>> 
>>>>>> http://hg.openjdk.java.net/jdk/jdk/file/44fe5fab538a/make/hotspot/lib/JvmMapfile.gmk
>>>>>> ,
>>>>>> unless this code is inactive - someone who knows this area better
>>>>>> than me might want to comment...).  Shouldn't the same approach be
>>>>>> taken here as well?
>>>>>> 
>>>>>> Thanks
>>>>>> Andrew
>>>>>> 
>>>>>> -----Original Message-----
>>>>>> From: core-libs-dev 
>>>>>> <core-libs-dev-boun...@openjdk.java.net>
>>>>>>  On
>>>>>> Behalf Of Ali Ince
>>>>>> Sent: Monday, November 19, 2018 2:08 PM
>>>>>> To: Alexey Ivanov 
>>>>>> <alexey.iva...@oracle.com>
>>>>>> ; build-dev
>>>>>> 
>>>>>> <build-...@openjdk.java.net>; core-libs <core-libs-...@openjdk.java.net>
>>>>>> 
>>>>>> Subject: Re: [PATCH] Windows 32-bit DLL name decoration
>>>>>> 
>>>>>> Hi Alexey,
>>>>>> 
>>>>>> I don’t have an account on JBS as I’m not an author yet, my OCA has
>>>>>> just been processed. Would it be possible for someone with an author
>>>>>> status to create an issue?
>>>>>> 
>>>>>> Regards,
>>>>>> 
>>>>>> Ali
>>>>>> 
>>>>>> 
>>>>>>> On 19 Nov 2018, at 12:12, Alexey Ivanov <alexey.iva...@oracle.com>
>>>>>>> 
>>>>>>> wrote:
>>>>>>> 
>>>>>>> Hi Ali,
>>>>>>> 
>>>>>>> The fix looks good to me provided it resolves your problem.
>>>>>>> I am not a reviewer so you'll have to get OK from reviewers, likely
>>>>>>> from build-dev and from core-libs.
>>>>>>> 
>>>>>>> Have you submitted the issue in JBS?
>>>>>>> 
>>>>>>> You have to sign OCA to be able to contribute to OpenJDK:
>>>>>>> 
>>>>>>> https://openjdk.java.net/contribute/
>>>>>>> 
>>>>>>> and also
>>>>>>> 
>>>>>>> https://openjdk.java.net/sponsor/
>>>>>>> 
>>>>>>> 
>>>>>>> Regards,
>>>>>>> Alexey
>>>>>>> 
>>>>>>> On 18/11/2018 12:07, Ali İnce wrote:
>>>>>>> 
>>>>>>>> Hi Alexey,
>>>>>>>> 
>>>>>>>> Below is a new patch content that removes JNICALL modifiers from
>>>>>>>> the exported functions of interest. This results in exported
>>>>>>>> functions not to be name decorated and use __cdecl calling convention.
>>>>>>>> 
>>>>>>>> Do you have any more suggestions, or would you please guide me on
>>>>>>>> next steps?
>>>>>>>> 
>>>>>>>> Thanks,
>>>>>>>> 
>>>>>>>> Ali
>>>>>>>> 
>>>>>>>> # HG changeset patch
>>>>>>>> # User Ali Ince 
>>>>>>>> <ali.i...@gmail.com>
>>>>>>>> 
>>>>>>>> # Date 1542542415 0
>>>>>>>> #      Sun Nov 18 12:00:15 2018 +0000
>>>>>>>> # Node ID a41df44e13e1b761f4b3f05a17ed18953067ae39
>>>>>>>> # Parent  16d5ec7dbbb49ef3f969e34be870e3f917ea89ff
>>>>>>>> Remove JNICALL modifiers to prevent name decoration on 32-bit windows
>>>>>>>> builds
>>>>>>>> 
>>>>>>>> diff -r 16d5ec7dbbb4 -r a41df44e13e1
>>>>>>>> src/jdk.jdi/share/native/libdt_shmem/shmemBack.c
>>>>>>>> --- a/src/jdk.jdi/share/native/libdt_shmem/shmemBack.c    Tue Aug
>>>>>>>> 14 14:28:23 2018 +0200
>>>>>>>> +++ b/src/jdk.jdi/share/native/libdt_shmem/shmemBack.c    Sun Nov
>>>>>>>> 18 12:00:15 2018 +0000
>>>>>>>> @@ -339,7 +339,7 @@
>>>>>>>>       return JDWPTRANSPORT_ERROR_NONE;  }  -JNIEXPORT jint JNICALL
>>>>>>>> +JNIEXPORT jint
>>>>>>>>   jdwpTransport_OnLoad(JavaVM *vm, jdwpTransportCallback* cbTablePtr,
>>>>>>>>                        jint version, jdwpTransportEnv** result)  {
>>>>>>>> diff -r 16d5ec7dbbb4 -r a41df44e13e1
>>>>>>>> src/jdk.jdwp.agent/share/native/include/jdwpTransport.h
>>>>>>>> --- a/src/jdk.jdwp.agent/share/native/include/jdwpTransport.h   
>>>>>>>> Tue Aug 14 14:28:23 2018 +0200
>>>>>>>> +++ b/src/jdk.jdwp.agent/share/native/include/jdwpTransport.h   
>>>>>>>> Sun Nov 18 12:00:15 2018 +0000
>>>>>>>> @@ -140,7 +140,7 @@
>>>>>>>>       void (*free)(void *buffer);      /* Call this for all
>>>>>>>> deallocations */
>>>>>>>>   } jdwpTransportCallback;
>>>>>>>>   -typedef jint (JNICALL *jdwpTransport_OnLoad_t)(JavaVM *jvm,
>>>>>>>> +typedef jint (*jdwpTransport_OnLoad_t)(JavaVM *jvm,
>>>>>>>>                                                 
>>>>>>>> jdwpTransportCallback *callback,
>>>>>>>>                                                  jint version,
>>>>>>>>                                                  jdwpTransportEnv**
>>>>>>>> env); diff -r 16d5ec7dbbb4 -r a41df44e13e1
>>>>>>>> src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c
>>>>>>>> ---
>>>>>>>> a/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c   
>>>>>>>> Tue Aug 14 14:28:23 2018 +0200
>>>>>>>> +++
>>>>>>>> b/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c   
>>>>>>>> Sun Nov 18 12:00:15 2018 +0000
>>>>>>>> @@ -1019,7 +1019,7 @@
>>>>>>>>       return JDWPTRANSPORT_ERROR_NONE;  }  -JNIEXPORT jint JNICALL
>>>>>>>> +JNIEXPORT jint
>>>>>>>>   jdwpTransport_OnLoad(JavaVM *vm, jdwpTransportCallback* cbTablePtr,
>>>>>>>>                        jint version, jdwpTransportEnv** env)  {
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>>> On 16 Nov 2018, at 23:03, Alexey Ivanov <alexey.iva...@oracle.com>
>>>>>>>>> 
>>>>>>>>> wrote:
>>>>>>>>> 
>>>>>>>>> Hi Ali,
>>>>>>>>> 
>>>>>>>>> It's exactly what I referred to.
>>>>>>>>> 
>>>>>>>>> Yes, it does change the calling convention.
>>>>>>>>> Yet it's not a (big) problem because both parties will use the
>>>>>>>>> same calling convention.
>>>>>>>>> 
>>>>>>>>> Using a DLL from another build will not be possible. But it's not
>>>>>>>>> a good idea to do so anyway.
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> Mapfiles and export options have been removed by
>>>>>>>>> 
>>>>>>>>> https://bugs.openjdk.java.net/browse/JDK-8200178
>>>>>>>>>  to simplify
>>>>>>>>> managing exported functions. So that to add or remove an exported
>>>>>>>>> function, you don't have modify makefiles and/or mapfiles. You
>>>>>>>>> just edit the source files.
>>>>>>>>> 
>>>>>>>>> Regards,
>>>>>>>>> Alexey
>>>>>>>>> 
>>>>>>>>> On 16/11/2018 22:42, Ali İnce wrote:
>>>>>>>>> 
>>>>>>>>>> Hi Alexey,
>>>>>>>>>> 
>>>>>>>>>> Thanks for your reply.
>>>>>>>>>> 
>>>>>>>>>> I will definitely give it a try though I’m not sure if that’ll be
>>>>>>>>>> a breaking change. This is because JNICALL modifier is defined to
>>>>>>>>>> be __stdcall on windows which is both specified on
>>>>>>>>>> jdwpTransport_OnLoad exported functions both for dt_socket.dll
>>>>>>>>>> and dt_shmem.dll.
>>>>>>>>>> 
>>>>>>>>>> The __stdcall is ignored on x64 platforms and also name
>>>>>>>>>> decoration is not applied
>>>>>>>>>> (
>>>>>>>>>> https://docs.microsoft.com/en-gb/cpp/build/reference/decorated-names?view=vs-2017
>>>>>>>>>> ).
>>>>>>>>>> I believe that’s why we don’t experience any problems on x64 builds.
>>>>>>>>>> 
>>>>>>>>>> Removing JNICALL (thus __stdcall) modifier (apparently only
>>>>>>>>>> applies to x86 builds) will result in the calling convention to
>>>>>>>>>> be changed, and thus will change how parameters are ordered and
>>>>>>>>>> also the stack cleanup rules. I think this may result in problems
>>>>>>>>>> in programs that are designed to load shared libraries and its
>>>>>>>>>> exported functions at runtime (not bound by link time which
>>>>>>>>>> probably won’t cause any issues - assuming that they use the
>>>>>>>>>> shared function signature) - as in
>>>>>>>>>> 
>>>>>>>>>> https://github.com/AdoptOpenJDK/openjdk-jdk11u/blob/5f01925b80ed851b133ee26fbcb07026ac04149e/src/jdk.jdwp.agent/share/native/libjdwp/transport.c#L99
>>>>>>>>>> .
>>>>>>>>>> 
>>>>>>>>>> Any thoughts?
>>>>>>>>>> 
>>>>>>>>>> Regards,
>>>>>>>>>> 
>>>>>>>>>> Ali
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>> On 15 Nov 2018, at 22:14, Alexey Ivanov
>>>>>>>>>>> 
>>>>>>>>>>> <alexey.iva...@oracle.com>
>>>>>>>>>>>  wrote:
>>>>>>>>>>> 
>>>>>>>>>>> Hi Ali,
>>>>>>>>>>> 
>>>>>>>>>>> Can the issue be resolved by using different call modifiers on
>>>>>>>>>>> the affected functions?
>>>>>>>>>>> 
>>>>>>>>>>> Some build / link issues were resolved by adding / removing
>>>>>>>>>>> JNICALL modifier, see
>>>>>>>>>>> 
>>>>>>>>>>> https://bugs.openjdk.java.net/browse/JDK-8201226
>>>>>>>>>>> http://mail.openjdk.java.net/pipermail/build-dev/2018-April/021553
>>>>>>>>>>> 
>>>>>>>>>>> .html
>>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>>>> https://bugs.openjdk.java.net/browse/JDK-8202476
>>>>>>>>>>> http://mail.openjdk.java.net/pipermail/build-dev/2018-May/021913.h
>>>>>>>>>>> 
>>>>>>>>>>> tml
>>>>>>>>>>> 
>>>>>>>>>>> Regards,
>>>>>>>>>>> Alexey
>>>>>>>>>>> 
>>>>>>>>>>> On 15/11/2018 21:43, Ali İnce wrote:
>>>>>>>>>>> 
>>>>>>>>>>>> Hi,
>>>>>>>>>>>> 
>>>>>>>>>>>> An issue
>>>>>>>>>>>> (
>>>>>>>>>>>> https://github.com/AdoptOpenJDK/openjdk-build/issues/709
>>>>>>>>>>>> )
>>>>>>>>>>>> raised against AdoptOpenJDK jdk11 32-bit windows builds led us
>>>>>>>>>>>> to the name decoration problem on built 32-bit dlls -
>>>>>>>>>>>> specifically dt_socket.dll and dt_shmem.dll. Whereas 64-bit
>>>>>>>>>>>> MSVC builds don’t apply any name decorations on exported
>>>>>>>>>>>> functions, 32-bit builds apply them - which requires either def
>>>>>>>>>>>> files or /export flags to be specified on the linker arguments.
>>>>>>>>>>>> 
>>>>>>>>>>>> Although the expected linker arguments were present on previous
>>>>>>>>>>>> jdk makefiles, they were removed in jdk11 makefiles.
>>>>>>>>>>>> 
>>>>>>>>>>>> Below is the proposed patch, which can also be browsed at
>>>>>>>>>>>> 
>>>>>>>>>>>> https://github.com/AdoptOpenJDK/openjdk-jdk11u/pull/1
>>>>>>>>>>>> .
>>>>>>>>>>>> 
>>>>>>>>>>>> Would you please have a look and let me know of any points I
>>>>>>>>>>>> may have missed (I don’t have any background information about
>>>>>>>>>>>> why the export flags were removed in jdk11)?
>>>>>>>>>>>> 
>>>>>>>>>>>> Regards,
>>>>>>>>>>>> 
>>>>>>>>>>>> Ali
>>>>>>>>>>>> 
>>>>>>>>>>>> diff --git a/make/lib/Lib-jdk.jdi.gmk b/make/lib/Lib-jdk.jdi.gmk
>>>>>>>>>>>> index 197b95c2e2..ac6ebf5591 100644
>>>>>>>>>>>> --- a/make/lib/Lib-jdk.jdi.gmk
>>>>>>>>>>>> +++ b/make/lib/Lib-jdk.jdi.gmk
>>>>>>>>>>>> @@ -37,6 +37,7 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
>>>>>>>>>>>>             jdk.jdwp.agent:include \
>>>>>>>>>>>>             jdk.jdwp.agent:libjdwp/export, \
>>>>>>>>>>>>         LDFLAGS := $(LDFLAGS_JDKLIB), \
>>>>>>>>>>>> +      LDFLAGS_windows := -export:jdwpTransport_OnLoad, \
>>>>>>>>>>>>         LIBS := $(JDKLIB_LIBS), \
>>>>>>>>>>>>     ))
>>>>>>>>>>>> 
>>>>>>>>>>>> diff --git a/make/lib/Lib-jdk.jdwp.agent.gmk
>>>>>>>>>>>> b/make/lib/Lib-jdk.jdwp.agent.gmk index 0bc93e0d35..0382e55325
>>>>>>>>>>>> 100644
>>>>>>>>>>>> --- a/make/lib/Lib-jdk.jdwp.agent.gmk
>>>>>>>>>>>> +++ b/make/lib/Lib-jdk.jdwp.agent.gmk
>>>>>>>>>>>> @@ -37,6 +37,7 @@ $(eval $(call SetupJdkLibrary,
>>>>>>>>>>>> BUILD_LIBDT_SOCKET, \
>>>>>>>>>>>>           libjdwp/export, \
>>>>>>>>>>>>       LDFLAGS := $(LDFLAGS_JDKLIB) \
>>>>>>>>>>>>           $(call SET_SHARED_LIBRARY_ORIGIN), \
>>>>>>>>>>>> +    LDFLAGS_windows := -export:jdwpTransport_OnLoad, \
>>>>>>>>>>>>       LIBS_linux := -lpthread, \
>>>>>>>>>>>>       LIBS_solaris := -lnsl -lsocket, \
>>>>>>>>>>>>       LIBS_windows := $(JDKLIB_LIBS) ws2_32.lib, \
>>>>>>>>>>>> 
>>> 
>> 
> 

Reply via email to