jdk9-arm3264 libjvm.so link error with arm-sflt
Simon Nash
simon at cjnash.com
Wed Dec 7 20:57:17 UTC 2016
On 07/12/2016 17:59, Bob Vandette wrote:
>> On Dec 7, 2016, at 12:30 PM, Simon Nash <simon at cjnash.com> wrote:
>>
>> On 07/12/2016 15:30, Bob Vandette wrote:
>>>> On Dec 7, 2016, at 5:31 AM, Simon Nash <simon at cjnash.com> wrote:
>>>>
>>>> On 06/12/2016 19:54, Bob Vandette wrote:
>>>>>> On Dec 6, 2016, at 2:38 PM, Simon Nash <simon at cjnash.com> wrote:
>>>>>>
>>>>>> On 07/11/2016 13:00, Bob Vandette wrote:
>>>>>>>> On Nov 6, 2016, at 1:07 PM, Simon Nash <simon at cjnash.com <mailto:simon at cjnash.com>> wrote:
>>>>>>>>
>>>>>>>> Bob Vandette wrote:
>>>>>>>>> In the soft-float binaries we’ve distributed in the past, we linked our binary against an external library.
>>>>>>>>> In order to achieve Java level floating point accuracy (and pass the TCK), you’ll need to do the same.
>>>>>>>>> Here’s the library that we used:
>>>>>>>>> http://www.jhauser.us/arithmetic/SoftFloat.html
>>>>>>>>> We modify this library to map their fadd,dadd,fsub,dsub functions to __aeabi_xxxx_glibc function names.
>>>>>>>>> You should be able to temporarily work around your link problems by removing the _glibc from the references
>>>>>>>>> in the hotspot and jdk sources. There are only a few files that are impacted.
>>>>>>>>> The problem stems from the fact that the normal glibc functions prefer speed over accuracy. The accuracy difference is extremely minimal but we fail the TCK for a few tests causing us to use this extra library.
>>>>>>>>> Hope this help,
>>>>>>>>> Bob.
>>>>>>>> Thanks very much! I thought about removing the _glibc suffix but the signatures
>>>>>>>> are different. For example, __aeabi_fadd_glibc takes two floats and returns double
>>>>>>>> but __aeabi_fadd takes two floats and returns float.
>>>>>>>>
>>>>>>>> From a quick look at the Hauser library, there is a similar signature mismatch there
>>>>>>>> as well, so I presume it would be necessary to write a small wrapper function to
>>>>>>>> convert both float32 arguments to float64 and then call the f64_add function in the
>>>>>>>> library. If I have misunderstood this, please correct my assumption.
>>>>>>> Here’s the wrapper code we used with softfloat-2b. Notice that we build two different libraries.
>>>>>>> The JDK functions override the normal entry point but the hotspot version uses a unique name.
>>>>>>> This was done to allow the normal float/double operations done by the VM to use the faster
>>>>>>> inlined glibc functions but the functions called during bytecode processing use the accurate ones.
>>>>>> I have used a modified version of this code to solve the problem with
>>>>>> building a soft-float version of libjvm.so. This has enabled me to complete
>>>>>> an ARMv5 soft-float build of the client JRE, which seems to be working OK.
>>>>>> Many thanks for your help with this.
>>>>>>
>>>>>> I have tried to use the alternative JDK_BUILD version of the wrapper code
>>>>>> to build JDK native shared libraries with accurate versions of these four
>>>>>> functions. This is failing because the linker is pulling in overlapping code
>>>>>> from libgcc.a and producing multiple definition errors for these symbols.
>>>>>>
>>>>>> For example, libmanagement_ext.so depends on both __aeabi_dadd and
>>>>>> __aeabi_ul2d. The linker brings in __aeabi_dadd from my wrapper, then
>>>>>> tries to resolve __aeabi_ul2d by bringing in _arm_addsubsf3.o from libgcc.a.
>>>>>> Because _arm_addsubsf3.o defines __aeabi_dadd as well as __aeabi_ul2d,
>>>>>> there are multiple definitions for __aeabi_dadd and the link fails.
>>>>>>
>>>>>> Perhaps I have misunderstood the purpose of the JDK_BUILD version of this
>>>>>> wrapper code. If it is intended to be included in JDK native libraries such
>>>>>> as libmanagement_ext.so, how do you solve the multiple definition problem?
>>>>> In JDK8, we built the soft-float library including the wrapper into a single archive and
>>>>> added this library to the link of each native library. We add -z muldefs to avoid
>>>>> the muliply defined errors.
>>>>> sflt_glibc_jdk.a -Xlinker -z -Xlinker muldefs
>>>> Thanks for the pointer to -z muldefs. With this change, I have been able to
>>>> build the JDK libraries with accurate floating-point support.
>>>>
>>>> While setting up a configuration to do this, I found a problem in the
>>>> configure script. On line 1286 of common/autoconf/flags.m4, the line
>>>> $2JDKLIB_LIBS="-ljava -ljvm"
>>>> should be changed to
>>>> $2JDKLIB_LIBS="[$]$2JDKLIB_LIBS -ljava -ljvm"
>>>> as is done for the similar case of JVM_LIBS in line 1297 and following.
>>>> This allows the user to pass the floating-point library to the configure
>>>> script by setting the JDKLIB_LIBS variable.
>>>>
>>>> I would also be inclined to remove line 1262:
>>>> $2JDKLIB_LIBS=""
>>>> so that any user setting of JDKLIB_LIBS is preserved when using the
>>>> Microsoft toolchain.
>>>>
>>>> Should I submit a patch for this?
>>> To do this properly, you’d have to add a new configure option —with-sfltfloat-lib=xxx
>>> and then reference this library in the abi-profile logic I added.
>> This seems cleaner but there would need to be separate options for the JDK
>> softfloat archive and the JVM softfloat archive, as these have different names.
> There’s no real evidence that this is necessary. You could use the same library
> for both the VM and the JDK libraries. We were just concerned that the
> VM’s performance might suffer if the replacement functions were used throughout
> the VM but we never found a test that showed this regression. Our implementation
> limited the replacement functions in the VM to JIT and interpreter floating point
> operations. But in reality, the VM does very little floating point calculations during
> it’s normal course of execution outside of the areas we replaced.
>
Using grep, I found 3109 uses of double in the hotspot .cpp files and
1758 usues of float. This suggests at least the possibility of some overhead
and I would prefer to play safe and continue with the dual-archive approach
that was used in JDK 8 and which I now have working.
>> It is also necessary to add a -L option for the directory containing the
>> softfloat archives. The --with-extra-ldflags option could be used for this
>> as it does no harm to specify this directory when linking files that don't
>> require the softfloat library.
>>
>> The option -z muldefs needs to be used when linking the JDK native libraries.
>> Again, this could be added to --with-extra-ldflags but I don't feel entirely
>> comfortable with having this as a global option as this could prevent the
>> linker from reporting genuine problems when linking libraries that don't use
>> the JDK softfloat archive.
>
> It would be nice if you could experiment with options to try to avoid the multiply defined
> symbols so we don’t need this.
>
> If the softfloat library is seen first in the link line, you shouldn’t have this problem since
> it should not attempt to load the alternative unless all math functions are packaged in
> a single module (.o file). It’s possible that this problem is caused by our static linking
> of libgcc or the fact that we put libstdc++ first. Check out lib-std.m4.
>
The accurate routines are loaded first but libgcc.a is packaged in a way that
can cause a duplicate version of the same symbol to be loaded as a result of
loading a different symbol that happens to be part of the same .o file as the
duplicate symbol.
I don't know whether the same problem would happen with dynamic linking of
libgcc but I would be reluctant to make this change because this would require
a compatible version of libgcc_s.so.1 on the user machine and this might
limit what machines could run the build.
>
>>> For abi profile "arm-sflt”, you could add this library to the ARM_ARCH_TYPE_FLAGS
>>> which ends up getting added to EXTRA_LDFLAGS.
>> I tried using LDFLAGS settings for the archive name option but this doesn't
>> work because the LDFLAGS settings appear before the object files in the link
>> command and the linker doesn't pull in anything from an archive if there are
>> no unsatisfied references from a preceding object file. The LIBS settings
>> appear after the object files, so having the archive name in LIBS is fine.
>
> Then you might need to adjust lib-std.m4.
>
I'm sure this could be done but this is turning out to be much more complex
than the two-line change I had originally suggested. I have a configuration
that seems to work and create suitable binaries, so perhaps I should stay with
this for now and work around the JDKLIB_LIBS issue.
Simon
>>> Since I’m trying to get the current sources integrated into openjdk9, I’d prefer
>>> to not add any more changes until that’s complete. Once that happens (we
>>> should know one way or another next week), you can work on a patch and get
>>> it reviewed by the build-dev at openjdk.java.net team.
>> I am happy to wait for this.
>
> Thanks,
> Bob.
>
>> Simon
>>
>>> Bob.
>>>> Simon
>>>>
>>>>> Bob.
>>>>>> Simon
>>>>>>
>>>>>>> /* GLIBC Equivalent Soft-Float Implementations */
>>>>>>> #ifndef JDK_BUILD
>>>>>>> double __aeabi_dadd_glibc( double a, double b )
>>>>>>> #else
>>>>>>> double __aeabi_dadd( double a, double b )
>>>>>>> #endif
>>>>>>> {
>>>>>>> flag aSign, bSign;
>>>>>>> float64 f64a, f64b;
>>>>>>> f64a.d = a;
>>>>>>> f64b.d = b;
>>>>>>> aSign = extractFloat64Sign( f64a );
>>>>>>> bSign = extractFloat64Sign( f64b );
>>>>>>> if ( aSign == bSign ) {
>>>>>>> return addFloat64Sigs( f64a, f64b, aSign ).d;
>>>>>>> }
>>>>>>> else {
>>>>>>> return subFloat64Sigs( f64a, f64b, aSign ).d;
>>>>>>> }
>>>>>>> }
>>>>>>> #ifndef JDK_BUILD
>>>>>>> double __aeabi_dsub_glibc( double a, double b )
>>>>>>> #else
>>>>>>> double __aeabi_dsub( double a, double b )
>>>>>>> #endif
>>>>>>> {
>>>>>>> flag aSign, bSign;
>>>>>>> float64 f64a, f64b;
>>>>>>> f64a.d = a;
>>>>>>> f64b.d = b;
>>>>>>> aSign = extractFloat64Sign( f64a );
>>>>>>> bSign = extractFloat64Sign( f64b );
>>>>>>> if ( aSign == bSign ) {
>>>>>>> return subFloat64Sigs( f64a, f64b, aSign ).d;
>>>>>>> }
>>>>>>> else {
>>>>>>> return addFloat64Sigs( f64a, f64b, aSign ).d;
>>>>>>> }
>>>>>>> }
>>>>>>> #ifndef JDK_BUILD
>>>>>>> float __aeabi_fadd_glibc( float a, float b ) #else
>>>>>>> float __aeabi_fadd( float a, float b )
>>>>>>> #endif
>>>>>>> {
>>>>>>> ufloat32 f32a, f32b, f32result;
>>>>>>> f32a.f = a;
>>>>>>> f32b.f = b;
>>>>>>> f32result.i32 = float32_add(f32a.i32, f32b.i32);
>>>>>>> return (f32result.f);
>>>>>>> }
>>>>>>> #ifndef JDK_BUILD
>>>>>>> float __aeabi_fsub_glibc( float a, float b )
>>>>>>> #else
>>>>>>> float __aeabi_fsub( float a, float b )
>>>>>>> #endif
>>>>>>> {
>>>>>>> ufloat32 f32a, f32b, f32result;
>>>>>>> f32a.f = a;
>>>>>>> f32b.f = b;
>>>>>>> f32result.i32 = float32_sub(f32a.i32, f32b.i32);
>>>>>>> return (f32result.f);
>>>>>>> }
>>>>>>> Bob.
>>>>>>>> Best regards,
>>>>>>>> Simon
>>>>>>>>
>>>>>>>>>> On Nov 6, 2016, at 11:06 AM, Simon Nash <simon at cjnash.com <mailto:simon at cjnash.com>> wrote:
>>>>>>>>>>
>>>>>>>>>> I am trying to build the current jdk9-arm3264 source for arm-sflt and I am
>>>>>>>>>> getting some link errors from libjvm.so as follows:
>>>>>>>>>>
>>>>>>>>>> /sd1/jdk9-arm3264/build/softfp/hotspot/variant-server/libjvm/objs/c1_LIRGenerator_arm.o: In function `GrowableArray<Instruction*>::at_put_grow(int, Instruction* const&, Instruction* const&)':
>>>>>>>>>> /sd1/jdk9-arm3264/hotspot/src/share/vm/utilities/growableArray.hpp:291: undefined reference to `__aeabi_fadd_glibc'
>>>>>>>>>> /sd1/jdk9-arm3264/hotspot/src/share/vm/utilities/growableArray.hpp:291: undefined reference to `__aeabi_dadd_glibc'
>>>>>>>>>> /sd1/jdk9-arm3264/hotspot/src/share/vm/utilities/growableArray.hpp:291: undefined reference to `__aeabi_fsub_glibc'
>>>>>>>>>> /sd1/jdk9-arm3264/hotspot/src/share/vm/utilities/growableArray.hpp:291: undefined reference to `__aeabi_dsub_glibc'
>>>>>>>>>> /sd1/jdk9-arm3264/build/softfp/hotspot/variant-server/libjvm/objs/c1_Runtime1_arm.o: In function `Runtime1::pd_name_for_address(unsigned char*)':
>>>>>>>>>> /sd1/jdk9-arm3264/hotspot/src/cpu/arm/vm/c1_Runtime1_arm.cpp:1220: undefined reference to `__aeabi_fadd_glibc'
>>>>>>>>>> /sd1/jdk9-arm3264/hotspot/src/cpu/arm/vm/c1_Runtime1_arm.cpp:1220: undefined reference to `__aeabi_fsub_glibc'
>>>>>>>>>> /sd1/jdk9-arm3264/hotspot/src/cpu/arm/vm/c1_Runtime1_arm.cpp:1220: undefined reference to `__aeabi_dadd_glibc'
>>>>>>>>>> /sd1/jdk9-arm3264/hotspot/src/cpu/arm/vm/c1_Runtime1_arm.cpp:1220: undefined reference to `__aeabi_dsub_glibc'
>>>>>>>>>> /sd1/jdk9-arm3264/build/softfp/hotspot/variant-server/libjvm/objs/templateTable_arm.o: In function `TemplateTable::fop2(TemplateTable::Operation)':
>>>>>>>>>> /sd1/jdk9-arm3264/hotspot/src/cpu/arm/vm/templateTable_arm.cpp:1718: undefined reference to `__aeabi_fadd_glibc'
>>>>>>>>>> /sd1/jdk9-arm3264/hotspot/src/cpu/arm/vm/templateTable_arm.cpp:1718: undefined reference to `__aeabi_fsub_glibc'
>>>>>>>>>> /sd1/jdk9-arm3264/build/softfp/hotspot/variant-server/libjvm/objs/templateTable_arm.o: In function `TemplateTable::dop2(TemplateTable::Operation)':
>>>>>>>>>> /sd1/jdk9-arm3264/hotspot/src/cpu/arm/vm/templateTable_arm.cpp:1761: undefined reference to `__aeabi_dadd_glibc'
>>>>>>>>>> /sd1/jdk9-arm3264/hotspot/src/cpu/arm/vm/templateTable_arm.cpp:1761: undefined reference to `__aeabi_dsub_glibc'
>>>>>>>>>> collect2: error: ld returned 1 exit status
>>>>>>>>>>
>>>>>>>>>> I am using a soft-float Linaro cross-compiler to do the build. Here is my configure command:
>>>>>>>>>>
>>>>>>>>>> bash ./configure --with-jdk-variant=normal --with-jvm-variants=server --with-abi-profile=arm-sflt --with-conf-name=softfp \
>>>>>>>>>> --with-debug-level=release --disable-warnings-as-errors --with-extra-cflags=-D__SOFTFP__ --openjdk-target=arm-linux-gnueabi \
>>>>>>>>>> --with-tools-dir=/sd1/linaro/gcc-linaro-arm-linux-gnueabi-2012.04-20120426_linux/bin \
>>>>>>>>>> --with-sys-root=/sd1/linaro/gcc-linaro-arm-linux-gnueabi-2012.04-20120426_linux/arm-linux-gnueabi/libc \
>>>>>>>>>> --with-cups=/sd1/armel/cups --with-freetype=/sd1/armel/freetype2 --with-alsa=/sd1/armel/alsa \
>>>>>>>>>> --x-includes=/sd1/armel/X11/include --x-libraries=/sd1/armel/X11/lib \
>>>>>>>>>> --disable-freetype-bundling --disable-hotspot-gtest --with-boot-jdk=/sd1/java/jdk1.8.0_25 \
>>>>>>>>>> CC=arm-linux-gnueabi-gcc CXX=arm-linux-gnueabi-g++ CPP=arm-linux-gnueabi-cpp CXXCPP=arm-linux-gnueabi-cpp \
>>>>>>>>>> LIBS="-Wl,-rpath-link /sd1/armel/freetype2/lib -Wl,-rpath-link /sd1/armel/X11/lib"
>>>>>>>>>>
>>>>>>>>>> Where are the missing functions such as __aeabi_fadd_glibc defined? I have found
>>>>>>>>>> __aeabi_fadd but I have not been able to find __aeabi_fadd_glibc.
>>>>>>>>>>
>>>>>>>>>> Simon
>
>
More information about the aarch32-port-dev
mailing list