Is it possible to link libraries created with ARM's proprietary tools (ADS, RVCT, and RVDS) with object files created by Sourcery CodeBench?

Question

Is it possible to link libraries created with ARM's proprietary tools (ADS, RVCT, and RVDS) with object files created by Sourcery CodeBench?

Answer

CodeSourcery's 2005-Q1 (and later) toolchains can interoperate with RVDS 2.2 (and later). Earlier versions of either toolchain cannot interoperate; for example, you cannot mix object files from ADS 1.2 with CodeSourcery's toolchains. The problem is that the tools used different Application Binary Interfaces (ABIs), so there are inconsistencies between the toolchains. In some cases, you can force the linker to combine the object files, but whether or not the resulting program will work correctly depends on a complex set of factors.

The ABI mandates calling conventions, i.e., what values are passed in what registers. It mandates the layout of basic types and structures, i.e., how many bytes are in an int and how much alignment is required for a given structure. It mandates object-file formats, i.e., what relocations the linker must be able to process. It requires that the C library provide a subset of the ISO C library functionality in a particular way.

Object files produced by RVDS 2.2 and later are compatible with GCC object files, and can be linked by GCC. However if the source code compiled by RVDS uses anything other than the special subset of the C library, including any use of the C++ library, then it is no longer compatible. At that point, all uses of the libraries must be in code compiled with the same compiler, and you must link with that compiler's linker.

Interoperation with RVDS 2.2 requires that you use the RVDS -Ono-known-library option. If you are using CodeSourcery's toolchains to build GNU/Linux applications, you also need to use the RVDS --no-hide-all option, unless you plan to link your entire application statically.

Also documented in Section 5.16.3 of the C Library for the ARM Architecture is the instruction to define _AEABI_PORTABILITY_LEVEL to a nonzero value. This results in a portable version of some C library headers (e.g. stdio.h). Note however that CodeSourcery's runtime libraries do not currently implement all of the features required to support _AEABI_PORTABILITY_LEVEL. This limitation will be addressed in future releases. As a workaround to provide objects required by portable code using stdio.h, compile the following code and include it in your application:

#include <stdio.h>

FILE *__aeabi_stdin;
FILE *__aeabi_stdout;
FILE *__aeabi_stderr;

static void __attribute__ ((used)) setup_aeabi_stdio()
{
    __aeabi_stdin = stdin;
    __aeabi_stdout = stdout;
    __aeabi_stderr = stderr;
}

static void (*fp) (void)
__attribute__ ((used, section (".preinit_array")))
= setup_aeabi_stdio;
The final statement in the code makes the initialization occur in the pre-initialization phase, before other user constructors are called, in case a constructor uses stdin, stdout, or stderr.

For more information, see ARM's Application Note 150.


This entry was last updated on 8 March 2013.