Newlib with ARM CLIBABI

Asked by Petter Österlund

Earlier I have used Sourcery CodeBench. There Newlib did have support for building ARM portable object files.
This was controlled via -D_AEABI_PORTABILITY_LEVEL=1 and all this is described by ARM CLIBABI document.
I thought this was a generic newlib feature but now I see that Launchpad version does not have this.

Making portable library allows receiver of library linking a static library using an other toolchain like armcc.

Is there/has there been any discussions or plans of incorporating this support?
Perhaps this is completely an Newlib issue, or will they not accept special ARM defines in the header files?
If so one could perhaps apply a patch before building.

Basically there is compile-time support for creating portable object files and then link time support for code compiled for it. The link time support is also needed and some variables (such as __aeabi_stdio) needs to be defined in libc (basically change from compile to runtime resolution).

Question information

Language:
English Edit question
Status:
Answered
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Thomas Preud'homme (thomas-preudhomme) said :
#1

Hi Petter,

A patch was made to *glibc* to support __aeabi_stdio so I guess support in GCC must already be there. However support in newlib seems to be missing indeed. We need to assert how much work is required to fix this and prioritize accordingly. I'll create a ticket internally to follow up on this. Given this is not a bugfix I expect it would be done in earliest for our 5.0Q4 release and possibly later.

Best regards.

Revision history for this message
Petter Österlund (petter-osterlund) said :
#2

Hi Thomas,

So it will be a while then, but perhaps a good time to start looking at implementing this part of ARM ABI - I think it isn't that complicated and that some work maybe can be reused. I now expect all work is in newlib. As input to a more detailed understanding and possibility to estimate the work needed I include 3 points below with some details.

===== 1. The clibabi specification can be found here. =====
This describes ARMs ABI to make object code portable to different libc. The goal is to compile with one compiler and be able to link with a different one. Stuff declared in header files such as putc() as macros must be avoided as the internals of FILE type is not portable.

   http://infocenter.arm.com/help/topic/com.arm.doc.ihi0039c/IHI0039C_clibabi.pdf

 ===== 2. Newlib header files. =====
Header files need be be extended with some #ifdefs to avoid / alter the unportable parts, such as putc().
Header files included in Sourcery CodeBench Lite 2013.11-24 can tell a lot of this - and I did not see any additional copyrights in newlib header files so I guess this work could potentially be reused. I (and others) have these. Adaption to newer version of newlib headerfiles may bee needed but most work should already have been done.

An example of such #ifdefs taken from stdio.h:
--------------
#if defined _AEABI_PORTABILITY_LEVEL && _AEABI_PORTABILITY_LEVEL != 0
extern FILE *__aeabi_stdin;
extern FILE *__aeabi_stdout;
extern FILE *__aeabi_stderr;
#define stdin (__aeabi_stdin)
#define stdout (__aeabi_stdout)
#define stderr (__aeabi_stderr)
#else
#define stdin (_REENT->_stdin)
#define stdout (_REENT->_stdout)
#define stderr (_REENT->_stderr)
#endif /* _AEABI_PORTABILITY_LEVEL */
------------------

There are also often additions to remove functions that are not standard, often seen together with #ifdef for STRICT_ANSI. This is an excerpt from string.h where the strpcpy() function prototype is excluded among a bunch of others:
--------
#if !defined __STRICT_ANSI__ && !defined _AEABI_PORTABLE
...
char *_EXFUN(stpcpy,(char *, const char *));
....
#endif
--------

Note that in above example if the prototype is parsed by the *compiler* it will in some cases use strpcpy() instead of strcpy() so not excluding the prototype is not as innocent as it first may seem.

Counting the number of #ifdefs may give a hint on how many places needs modification:

$ find /opt/toolchains/arm-2013.11/arm-none-eabi/include -name "*.h" | xargs grep _AEABI_PORT | wc
     94 516 10474

And the following lists which files are involved
$ find /opt/toolchains/arm-2013.11/arm-none-eabi/include -name "*.h" | xargs grep _AEABI_PORT | awk -F: '{print $1}' | sort | uniq
/opt/toolchains/arm-2013.11/arm-none-eabi/include/assert.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/ctype.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/errno.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/limits.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/locale.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/machine/setjmp.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/math.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/setjmp.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/signal.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/stdio.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/stdlib.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/string.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/sys/errno.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/sys/reent.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/sys/signal.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/time.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/wchar.h
/opt/toolchains/arm-2013.11/arm-none-eabi/include/wctype.h

 ===== 3. Newlib runtime. =====
As some of the header files changes definition of e.g. a constant such as CLK_TCK to a variable there must also be a corresponding definition of it in newlib .c files somewhere. In this example const int __aeabi_CLOCKS_PER_SEC; is expected, else link failure for a portable object file that uses it. Same goes for the __aeabi_stdout (but this will likely need runtime pre-init initialization to setup correctly). So note that there are two parts of this standard; one to compile to portable object code and another to link portable objects to an executable.

In CodeBench they seems to have created a companion file for each modified header-file. I find e.g. this in libc.a:
-----
lib_a-clibabi_time.o:
00000000 R __aeabi_CLOCKS_PER_SEC
-----
Which is the only definition in this file! A complete list of such "clibabi" named files in libc.a may give a hint of the amount of work:

$ arm-none-eabi-nm /opt/toolchains/arm-2013.11/arm-none-eabi/lib/thumb2/libc.a | grep clibabi
lib_a-clibabi_assert.o:
lib_a-clibabi_ctype.o:
lib_a-clibabi_errno.o:
lib_a-clibabi_limits.o:
lib_a-clibabi_locale.o:
lib_a-clibabi_math.o:
lib_a-clibabi_setjmp.o:
lib_a-clibabi_signal.o:
lib_a-clibabi_signal_fns.o:
lib_a-clibabi_stdio.o:
lib_a-clibabi_stdlib.o:
lib_a-clibabi_time.o:

Can you help with this problem?

Provide an answer of your own, or ask Petter Österlund for more information if necessary.

To post a message you must log in.