The GNU C library supplied with Sourcery G++ Lite uses the new EABI-based kernel syscall interface. This means applications compiled with Sourcery G++ require at least a 2.6.16 kernel with EABI syscalls enabled.
By default Sourcery G++ generates Linux binaries that require
an ARMv5 or later CPU. To build applications or libraries capable
of running on ARMv4t CPUs, use the -march=armv4t
command-line option.
Runtime libraries suitable for ARMv4t systems are supplied in the
armv4t
subdirectory.
Code compiled for ARMv4t is ABI compatible with ARMv5 code. Code and binaries compiled for different architectures may be mixed freely.
There are several other ways to tell the compiler to generate
ARMv4t code. However -march=armv4t
must be used
when linking to ensure the correct libraries and startup code are
selected.
Sourcery G++ includes support for automatic generation of NEON SIMD vector code. Autovectorization is a compiler optimization in which loops involving normal integer or floating-point code are transformed to use NEON SIMD instructions to process several data elements at once.
To enable generation of NEON vector code, use the command-line options
-ftree-vectorize -mfpu=neon -mfloat-abi=softfp
.
The -mfpu=neon
option
also enables generation of VFPv3 scalar floating-point code.
Sourcery G++ also includes support for manual generation
of NEON SIMD code using C intrinsic functions. These intrinsics,
the same as those supported by the ARM
RealView® compiler, are defined
in the arm_neon.h
header
and are documented in the 'ARM NEON Intrinsics' section of the GCC
manual. The command-line options -mfpu=neon
-mfloat-abi=softfp
must be specified to use these
intrinsics; -ftree-vectorize
is not required.
Sourcery G++ for ARM GNU/Linux includes support for half-precision (16-bit) floating point, including the new __fp16 data type in C and C++, support for generating conversion instructions when compiling for processors that support them, and library functions for use in other cases.
ARM supports two incompatible representations for half-precision floating-point values. You must choose one of the representations and use it consistently in your program. The linker gives an error if objects compiled or assembled with different half-precision float attributes are combined in the same executable.
Compiling or assembling with -mfp16-format=ieee
selects the representation defined in the
IEEE 754-2008 standard,
with 1 sign bit, 5 exponent bits, and 10 significand bits
(11 bits of significand precision, approximately 3 decimal digits).
This format is capable of representing normalized values in the range of
2-14 to 65504. It includes support for
infinities and NaNs, following the usual IEEE 754 rules.
ARM also supports an alternative half-precision representation,
which you can select with
-mfp16-format=alternative
. This format does not
include support for infinities and NaNs. Instead, the range of
exponent values is extended, so that this format can represent
normalized values in the range of 2-14
to 131008.
The default for this option is -mfp16-format=none
,
which disables support for half-precision floats.
When you compile with -mfp16-format=ieee
or
-mfp16-format=alternative
, GCC defines the
__fp16 data type to represent half-precision
float values. Objects of this type have a size of 2 bytes and
a natural alignment of 2 bytes.
The __fp16 type is a storage format only. For purposes of arithmetic and other operations, __fp16 values are automatically promoted to float. In addition, you cannot declare a function with a return value or parameters of type __fp16.
Note that conversions from double to __fp16 involve an intermediate conversion to float. Because of rounding, this can sometimes produce a different result than a direct conversion.
ARM provides hardware support for conversions between
__fp16 and float values
as an extension to VFP and NEON (Advanced SIMD). GCC generates
code using the instructions provided by this extension if you compile
with the options -mfpu=neon-fp16 -mfloat-abi=softfp
,
in addition to the -mfp16-format
option to select
a half-precision format.
In other cases, conversions between __fp16 and float values are implemented as library calls.
The Application Binary Interface (ABI) for the ARM Architecture is a collection of standards, published by ARM Ltd. and other organizations. The ABI makes it possible to combine tools from different vendors, including Sourcery G++ and ARM RealView®.
Sourcery G++ implements the ABI as described in these documents, which are available from the ARM Information Center:
Sourcery G++ currently produces DWARF version 2, rather than DWARF version 3 as specified in AADWARF.
It is possible to create object files using Sourcery G++ for ARM EABI that are link-compatible with the GNU C library provided with Sourcery G++ for ARM GNU/Linux as well as with the Newlib C library provided with the ARM EABI toolchain. These object files are additionally link-compatible with other ARM C Library ABI-compliant static linking environments and toolchains.
To use this feature, when compiling your files with the bare-metal
ARM EABI toolchain define the preprocessor constant
_AEABI_PORTABILITY_LEVEL
to 1
before including any system header files.
For example, pass the option -D_AEABI_PORTABILITY_LEVEL=1
on your compilation command line.
No special options are required when linking the resulting object files.
When building applications for ARM EABI,
files compiled with this definition may be linked freely with those
compiled without it.
Files compiled in this manner may not use the
functions fgetpos
or fsetpos
, or reference the
type fpos_t. This is because Newlib assumes a
representation for fpos_t that is not AEABI-compliant.
Note that object files are only portable from EABI to GNU/Linux, and not vice versa; object files compiled for ARM GNU/Linux targets cannot be linked into ARM EABI executables.
In order to run and debug programs produced by Sourcery G++ on a GNU/Linux target, you must install runtime support files on the target. You may also need to set appropriate build options so that your executables can find the correct dynamic linker and libraries at runtime.
The runtime support files, referred to as the sysroot,
are found in the arm-none-linux-gnueabi/libc
directory of your
Sourcery G++ Lite installation. The sysroot consists of the contents of the
etc
, lib
, sbin
,
and usr
directories. There may be other
directories in arm-none-linux-gnueabi/libc
that contain
additional sysroots customized for particular combinations of
command-line compiler flags, or multilibs.
Refer to the section called “Library Configurations” for a list of the included multilibs
in this version of Sourcery G++ Lite.
The sysroots provided in Windows host packages for Sourcery G++ are not directly usable on the Linux target because of differences between the Windows and Linux file systems. Some files that are hard links, or copies, in the sysroot as installed on the Windows file system should be symbolic links on the Linux target. Additionally, some files in the sysroot which should be marked executable on the Linux target are not marked executable on Windows. If you intend to use the sysroot provided with Sourcery G++ on a Windows host system as the basis for your Linux target filesystem, you must correct these issues after copying the sysroot to the target. If you are a Professional Edition customer and need assistance with these modifications, please contact CodeSourcery's support team.
There are three choices for installing the sysroot on the target:
You can install the files in the filesystem root, replacing the system-provided files. All applications automatically use the Sourcery G++ libraries. This method is primarily useful when you are building a GNU/Linux system from scratch. Otherwise, overwriting your existing C library may break other applications on your system, or cause it to fail to boot.
You can install the sysroot in an alternate location and build your
application with the -rpath
and
--dynamic-linker
linker options to specify the sysroot
location.
You can install the sysroot in an alternate location and explicitly invoke your application through the dynamic linker to specify the sysroot location. If you are just getting started with Sourcery G++ Lite, this may be the easiest way to get your application running, but this method does not support use of the debugger.
Setting the environment variable LD_LIBRARY_PATH
on the target is not sufficient, since executables produced by Sourcery G++
depend on the Sourcery G++ dynamic linker included in the sysroot as well
as the Sourcery G++ runtime libraries.
If you are modifying an existing system, rather than creating a new system from scratch, you should place the sysroot files in a new directory, rather than in the root directory of your target system.
If you choose to overwrite your existing C library, you may not be able to boot your system. You should back up your existing system before overwriting the C library and ensure that you can restore the backup even with your system offline.
When running Sourcery G++ on a GNU/Linux host, you have the alternative of installing the sysroot on the target at the same pathname where it is installed on the host system. One way to accomplish this is to NFS-mount the installation directory on both machines in the same location, rather than to copy files.
In many cases, you do not need to copy all of the files in the sysroot.
For example, the usr/include
subdirectory contains
files that are only needed if you will actually be running the compiler
on your target system. You do not need these files for non-native compilers.
You also do not need any .o
or .a
files; these are used by the compiler when linking programs, but are not
needed to run programs. You should definitely copy all
.so
files and the executable files in
usr/bin
and sbin
.
You need to install the sysroot(s) corresponding to
the compiler options you are using for your applications. The tables in
the section called “Library Configurations” tell you which sysroot directories correspond
to which compiler options. If you are unsure what sysroot is being referenced
when you build your program, you can
identify the sysroot by adding -v
to your compiler
command-line options, and looking at the --sysroot=
pathname
in the compiler output.
If you have installed the sysroot on the target in a location other than
the file system root, you can use the -rpath
and
--dynamic-linker
linker options to specify the sysroot
location.
If you are using Sourcery G++ from the command line, follow these steps:
First find the correct sysroot directory, dynamic linker, and library
subdirectory for your
selected multilib. Refer to the section called “Library Configurations”.
In the following steps,
sysroot
is the absolute path to the
sysroot directory on the target corresponding to your selected multilib.
For the default multilib, the dynamic linker path relative to the sysroot is
lib/ld-linux.so.3
, and the library subdirectory is
lib
.
This is used in the example below.
When invoking arm-none-linux-gnueabi-gcc to link your executable, include the command-line options:
-Wl,-rpath=sysroot
/lib:sysroot
/usr/lib \ -Wl,--dynamic-linker=sysroot
/lib/ld-linux.so.3
where sysroot
is the absolute path to the
sysroot directory on the target corresponding to your selected multilib.
Copy the executable to the target and execute it normally.
Note that if you specify an incorrect path for
--dynamic-linker
, the common failure mode seen when running
your application on the target is similar to
> ./hello ./hello: No such file or directory
or
> ./hello ./hello: bad ELF interpreter: No such file or directory
This can be quite confusing since it appears from the error message
as if it is the ./hello
executable that is
missing rather than the dynamic linker it references.
You can invoke the Sourcery G++ dynamic linker on the target to run your application without having to compile it with specific linker options.
To do this, follow these steps:
Build your application on the host, without any additional linker options, and copy the executable to your target system.
Find the correct sysroot directory, dynamic linker, and library
subdirectory for your
selected multilib. Refer to the section called “Library Configurations”.
In the following steps,
sysroot
is the absolute path to the
sysroot directory on the target corresponding to your selected multilib.
For the default multilib, the dynamic linker is
lib/ld-linux.so.3
, and the library subdirectory is
lib
.
This is used in the example below.
On the target system, invoke the dynamic linker with your executable as:
>sysroot
/lib/ld-linux.so.3 \ --library-pathsysroot
/lib:sysroot
/usr/lib \/path/to/your-executable
where sysroot
is the absolute path to the
sysroot directory on the target corresponding to your selected
multilib.
Invoking the linker in this manner requires that
you provide either an absolute pathname to your executable, or a relative
pathname prefixed with ./
. Specifying only the name
of a file in the current directory does not work.
The GDB server utility provided with Sourcery G++ Lite can be used to debug a GNU/Linux application. While Sourcery G++ runs on your host system, gdbserver and the target application run on your target system. Even though Sourcery G++ and your application run on different systems, the debugging experience when using gdbserver is very similar to debugging a native application.
The GDB server executables are included in the sysroot in ABI-specific
subdirectories of
. Use the
executable from the sysroot and library subdirectory
that match your program.
See the section called “Library Configurations” for details.
sysroot
/usr
You must copy the sysroot to your target system as described in the section called “Installing the Sysroot”. You must also copy the executable you want to debug to your target system.
If you have installed the sysroot in the root directory of the filesystem on the target, you can invoke gdbserver as:
> gdbserver :10000 program arg1 arg2 ...
where program
is the path to the program you
want to debug and arg1 arg2 ...
are the arguments
you want to pass to it. The :10000
argument indicates
that gdbserver should listen for connections from GDB
on port 10000.
You can use a different port, if you prefer.
If you have installed the sysroot in an alternate directory, invoking gdbserver becomes more complicated. You must build your application using the link-time options to specify the location of the sysroot, as described in the section called “Using Linker Options to Specify the Sysroot Location”. You must also invoke gdbserver itself using the dynamic linker provided in the Sourcery G++ sysroot, as described in the section called “Specifying the Sysroot Location at Runtime”. In other words, the command to invoke gdbserver in this case would be similar to:
>sysroot
/lib/ld-linux.so.3 \ --library-pathsysroot
/lib:sysroot
/usr/lib \sysroot
/usr/lib/bin/gdbserver :10000program arg1 arg2 ...
You can connect to GDB server by using the following command from within GDB:
(gdb) target remote target
:10000
where target
is the host name or IP address
of your target system.
When your program exits, gdbserver exits too.
If you want to debug the program again, you must restart
gdbserver on the target.
Then, in GDB, reissue the target
command shown above.
In order to debug shared libraries, GDB needs to map the pathnames of shared libraries on the target to the pathnames of equivalent files on the host system. Debugging of multi-threaded applications also depends on correctly locating copies of the libraries provided in the sysroot on the host system.
In some situations, the target pathnames are valid on the host system. Otherwise, you must tell GDB how to map target pathnames onto the equivalent host pathnames.
In the general case, there are two GDB commands required to set up the mapping:
(gdb) set sysroot-on-targettarget-pathname
(gdb) set sysroothost-pathname
This causes GDB to replace all instances of the
target-pathname
prefix in shared library
pathnames reported by the target with
host-pathname
to get the location of the
equivalent library on the host.
If you have installed the sysroot in the root filesystem on the target, you can omit the set sysroot-on-target command, and use only set sysroot to specify the location on the host system.
Refer to the section called “Installing the Sysroot” for more information about installing the sysroot on the target. Note that if you have installed a stripped copy of the provided libraries on the target, you should give GDB the location of an unstripped copy on the host.