link time warning about VPF registers - gcc

I'm trying to port a project from Cortex M0 to Cortex M4 with hardware floating point extension, the new target soc is nRF52832.
The error I am getting from the linker is the following
arm-unknown-eabi/bin/ld: error: x.o uses VFP register arguments, firmware does not
where firmware is the name of the output file fro the linker.
This is an issue with the arm ABI for floating point, I want to use the FPU as it is requested by
the FreeRTOS port I want to use but I don't get how to tweak my linker flags to make it possible.
This is the set of linker flags I'm currently using
-L/path/to/nrfx/mdk
-Wl, --no-undefined
-Wl,--as-needed -march=armv7e-m+fp -mthumb -mfloat-abi=hard -mabi=aapcs
-Wl, --start-group support/libs/libQRCode.a support/libs/libSPIFFS.a
-Wl, --no-undefined
-Wl, --as-needed
-Wl, --gc-sections --specs=nosys.specs -T/path/to/linker_script.ld /toolchain/path/to/lib/libm.a
-Wl, --end-group

The -mfloat-abi flag is a compiler-only flag, so there is no point in passing it to the linker.
In order to be able to build a firmware image that uses the hard-float ABI, all object files passed to the linker must be compiled to use that ABI. You issue is most likely due to the fact that you are passing to the linker one or more object files compiled with the soft-float ABI instead; for example, the /toolchain/path/to/lib/libm.a file path in your linker command line looks suspicious, you should use the hard-float version of libm.a, which you will likely find in the hard/ sub-folder of your toolchain library path.

Related

Enable VPF libraries (hard) with arm-gcc

I'm trying to build an application that links a library that is built with VFP. I have added the flags -mfpu=fpv4-sp-d16 -mfloat-abi=hard to my arm-gcc command, but it complains about that the standard C library (libm.a and the like) is not built using VFP.
I have noticed that in my arm-gcc toolchain directory, in lib, there is a folder called hard which is supposed to contain the arm standard C libraries built with VFP.
How can I make this library folder the standard one for the arm toolchain?
It seems that I had some missing flags. Below I list all of them:
-mcpu=cortex-m7 -mthumb -mabi=aapcs -mfpu=fpv5-d16 -mfloat-abi=hard

Mingw gcc, "-shared -static" passing together

When studying Scintilla's makefile for MinGW under windows, I noticed that it is passing -shared and -static together as LDFLAGS to gcc.
LDFLAGS=-shared -static -mwindows $(LDMINGW)
I googled, and only find some information from clang: https://reviews.llvm.org/D43811
[MinGW, CrossWindows] Allow passing -static together with -shared
In these combinations, link a DLL as usual, but pass -Bstatic instead of -Bdynamic to indicate prefering static libraries.
My question is: Would GCC do the same?
I haven't find any proof yet.
You can pass both -static and -shared in a GCC linkage. Their
combined effect is the same as you found described in your llvm link,
and this has always been the case for GCC.
-shared directs a GCC linkage to produce a shared library rather than a program,
which it achieves by passing on the option -shared to its invocation of
the linker.
-static directs a GCC linkage to ignore shared libraries when resolving
input library options -lname. By default -lname would be resolved by
searching the specified or default linker search directories for either
the shared library libname.so (on Windows, [lib]name.dll)
or the static library libname.a (on Windows also [lib]name.lib) and to prefer
the shared library if both of them are found in the same directory. -static
simply excludes all shared libraries from the search. GCC achieves this by passing the option -Bstatic
through to its invocation of the linker at a position in the generated linker
commandline that precedes all of the -lname options.
The GNU linker documentation of -Bstatic is explicit
that this option is consistent with -shared and that the effect is to produce a shared library
all of whose dependent libraries have been statically resolved.
-Bstatic
-dn
-non_shared
-static
Do not link against shared libraries. This is only meaningful on platforms for which shared libraries are supported.
The different variants of this option are for compatibility with various systems. You may use this option multiple times on the command line:
it affects library searching for -l options which follow it. This option also implies --unresolved-symbols=report-all.
This option can be used with -shared. Doing so means that a shared library is being created but that all of the library’s external references must be resolved by pulling in entries from static libraries.
(emphasis mine).
Although static linkage of shared library is in principle just a linkage restricted
in the same way as static linkage of a program, in practice it frequently encounters
a snag on Unix and Linux because all the object code linked into an ELF shared library
libname.so must be Position Independent Code,
as produced by the GCC compilation option -fPIC, whereas object files that are destined to be
archived in static libraries are customarily not compiled with -fPIC. Linkages using
-shared ... -static are thus apt to fail because necessary static libraries contain
non-PIC object files.
You do not have this worry with GCC on Windows, however, because there
is no such distinction as PIC v. non-PIC in Windows PE
object code.

QtWebengine build error with opus and silk codecs

I am trying to build Qt5.9.1 with QtWebengine for an arm platform.
These are some architecture based arguments i am passing to the build.
QMAKE_CFLAGS_RELEASE += -march=armv7-a -mcpu=cortex-a9
QMAKE_CXXFLAGS_RELEASE += -march=armv7-a -mcpu=cortex-a9
By default i can see that the build is going for these values as well.
-mfloat-abi=hard -mtune=generic-armv7-a -mfpu=vfpv3-d16 -mthumb
THIS is the error i am facing.
As far as i know, in cortex-a9 neon is optional and my particular SoC does not support neon.
Also the -print-multi-lib gives this
arm400-linux-g++ -print-multi-lib
armv5te_arm9;#mcpu=arm926ej-s
a9;#mcpu=cortex-a9
a7;#mcpu=cortex-a7
armv5te_arm9_soft;#mcpu=arm926ej-s#mfloat-abi=soft
armv5te_arm9_vfp;#mcpu=arm926ej-s#mfloat-abi=softfp#mfpu=vfp
a9_soft;#mcpu=cortex-a9#mfloat-abi=soft
a9_softfp_vfp;#mcpu=cortex-a9#mfloat-abi=softfp#mfpu=vfp
a9_softfp_vfpv3-d16;#mcpu=cortex-a9#mfloat-abi=softfp#mfpu=vfpv3-d16
a7_soft;#mcpu=cortex-a7#mfloat-abi=soft
a7_softfp_vfpv4;#mcpu=cortex-a7#mfloat-abi=softfp#mfpu=vfpv4
a7_softfp_neon-vfpv4;#mcpu=cortex-a7#mfloat-abi=softfp#mfpu=neon-vfpv4
a7_hard_neon-vfpv4;#mcpu=cortex-a7#mfloat-abi=hard#mfpu=neon-vfpv4
I have tried passing these three possible architecture arguments in the mkspecs.
QMAKE_CFLAGS_RELEASE += -march=armv7-a -mcpu=cortex-a9 -mfloat-abi=soft
QMAKE_CXXFLAGS_RELEASE += -march=armv7-a -mcpu=cortex-a9 -mfloat-abi=soft
For this i got
"arm400-linux-g++: error: -mfloat-abi=soft and -mfloat-abi=hard may not be used together".
I also tried passing these arguments
-mcpu=cortex-a9 -mfloat-abi=softfp -mfpu=vfp
-mcpu=cortex-a9 -mfloat-abi=softfp -mfpu=vfpv3-d16
But it had the same effect.
libxxxx.a(yyyyy.o) uses VFP register arguments, libQt5WebEngineCore.so.5.9.1 does not
I am running out of options here. Why is this issue coming up ?
You have to build all the libs with the same VFP option as your source code.
According to ATPCS(ARM-Thumb procedure call standard), float parameters are passed by VFP registers if available. Otherwise, they are passed by the ARM integer registers.
If lib A is compiled with the soft-float option, you cannot call its functions due to the ABI conflict from lib B or vice versa.
If you don't have certain lib's source code but the binary, your only option is to match the other projects build options to the lib's.
However, chances are good that you will find different versions of the library with various build options.

Cross compiling - Error: selected processor does not support `fmrx r3,fpexc' in ARM mode - Beaglebone

I'm trying to cross-compile a file to flash into the Beaglebone Black.
All works fine, but if I try to enable the FPU with
#define set_en_bit_in_fpexc() do { \
int dummy; \
__asm__ __volatile__ ("fmrx %0,fpexc\n\t" \
"orr %0,%0,#0x40000000\n\t" \
"fmxr fpexc,%0" : "=r" (dummy) : :); \
} while (0)
I get the following error
Error: selected processor does not support `fmrx r3,fpexc' in ARM mode
Error: selected processor does not support `fmxr fpexc,r3' in ARM mode
I also tried with thumb mode, but I get the same errors.
Of course if I remove the part of the code that initialize the FPU it works fine.
Why I get those errors?
Makefile
[...]
CROSSPATH?=/usr/bin
CROSSPFX=$(CROSSPATH)/arm-none-eabi-
CC=$(CROSSPFX)gcc
AS=$(CROSSPFX)as
LD=$(CROSSPFX)ld
NM=$(CROSSPFX)nm
OBJCOPY=$(CROSSPFX)objcopy
OBJDUMP=$(CROSSPFX)objdump
CFLAGS=-Wall -Wextra -O2 -ffreestanding
ARCHFLAGS=-mcpu=cortex-a8 -march=armv7-a -mfpu=neon
CCARCHFLAGS=$(ARCHFLAGS) -marm
[...]
I'm on Arch, kernel 4.8.1
P.S. My professor uses the linaro cross-compiler and it works just fine
Most of the Linaro toolchains are configured for ARMv7 hard-float by default (certainly the Linux ones, I'm less sure about the bare-metal ones). Looking at the configuration of the arm-none-eabi toolchain as packaged by Arch, I surmise it's just using the GCC defaults for things like that, which implies something like ARMv4t, and crucially, soft-float ABI.
Whilst the -mfpu option controls code generation in terms of which floating-point instructions may be used, apparently it's the float ABI which controls whether it'll let you do things which really only make sense on a hardware FPU, rather than under floating-point emulation.
When it's not configured by default, you need to explicitly select a floating-point ABI implying an actual hardware FPU, i.e. -mfloat-abi=hard (or -mfloat-abi=softfp, but there's really no reason to use that unless you need to link against other soft-float code).
-mfpu=vfpv3-d16 -mfloat-abi=hard
Just to give a more direct solution, I had to add -mfpu=vfpv3-d16.
Test code a.S:
fmrx r2, fpscr
Working command:
sudo apt-get install binutils-arm-linux-gnueabihf
arm-linux-gnueabihf-as -mfpu=vfpv3-d16 -mfloat-abi=hard a.S
Note that -mfloat-abi=hard is enabled by default on this particular build of arm-linux-gnueabihf-as, and could be omitted.
The default value of float-abi likely depends on -msoft-float vs -mhard-float controlled at GCC build time with:
./configure --with-float=soft
as documented at: https://gcc.gnu.org/install/configure.html You can get the flags used for your toolchain build with gcc -v as mentioned at: What configure options were used when building gcc / libstdc++? I could not however easily determine its default value if not given.
You may also be interested in -mfloat-abi=softfp which can produce hard floats for the executable, but generate soft function calls: ARM compilation error, VFP registered used by executable, not object file
The possible values of -mfpu= can be found at: https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/ARM-Options.html#ARM-Options
Also note that FMRX is the pre-UAL syntax for VMRS which the newer recommended syntax, see also: Are ARM instructuons SWI and SVC exactly same thing?
Tested on Ubuntu 16.04, arm-linux-gnueabihf-as 2.26.1.

GCC Cortex-M4 -mfpu=vfpv4 vs. -mfpu=fpv4-sp-d16

I'm using a Freescale K22 (Cortex-M4F) with Kinetis Design Studio, which includes a GNU toolchain. I'm trying to use a binary-only library provided by Invensense, and they compiled it with GCC for use on a the Cortex-M4F using the compiler's CPU options "-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=vfpv4"
The Freescale toolchain defaults to "-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16". When I try to link my program with the vendor binary-only library, I get link errors like:
c:/freescale/kds_1.1.1/toolchain/bin/../lib/gcc/arm-none-eabi/4.8.0/../../../../arm-none-eabi/bin/ld.exe: error: ./startup/startup.o uses VFP register arguments, 22F_eval_spi_to_invensense_CHECKED_IN.elf does not
c:/freescale/kds_1.1.1/toolchain/bin/../lib/gcc/arm-none-eabi/4.8.0/../../../../arm-none-eabi/bin/ld.exe: failed to merge target specific data of file ./startup/startup.o
I can rebuild the Kinetis platform library for -mfpu=vfpv4, but I still get the link errors, presumably because other Kinetis libraries are compiled with
"-mfpu=fpv4-sp-d16".
Since both are intended for the Cortex-M4 with FPU, is there any actual difference between GCC generated code for vpfv4 and fpv4-sp-d16? Are they actually incompatible, or is the linker just overly pedantic?

Resources