jdk9-arm3264 libjvm.so link error with arm-sflt

Bob Vandette bob.vandette at oracle.com
Wed Dec 7 17:59:49 UTC 2016


> 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.

> 
> 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.


> 
>> 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.

> 
>> 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