C Lib Clibabi
C Lib Clibabi
C Lib Clibabi
Abstract
This document defines an ANSI C (C89) run-time library ABI for programs written in ARM and Thumb assembly language, C, and stand alone C++.
Keywords
C library ABI, run-time library
Please report defects in this specification to arm dot eabi at arm dot com.
Licence
THE TERMS OF YOUR ROYALTY FREE LIMITED LICENCE TO USE THIS ABI SPECIFICATION ARE GIVEN IN SECTION 1.4, Your licence to use this specification (ARM contract reference LEC-ELA-00081 V2.0). PLEASE READ THEM CAREFULLY. BY DOWNLOADING OR OTHERWISE USING THIS SPECIFICATION, YOU AGREE TO BE BOUND BY ALL OF ITS TERMS. IF YOU DO NOT AGREE TO THIS, DO NOT DOWNLOAD OR USE THIS SPECIFICATION. THIS ABI SPECIFICATION IS PROVIDED AS IS WITH NO WARRANTIES (SEE SECTION 1.4 FOR DETAILS).
Proprietary notice
ARM, Thumb, RealView, ARM7TDMI and ARM9TDMI are registered trademarks of ARM Limited. The ARM logo is a trademark of ARM Limited. ARM9, ARM926EJ-S, ARM946E-S, ARM1136J-S ARM1156T2F-S ARM1176JZ-S Cortex, and Neon are trademarks of ARM Limited. All other products or services mentioned herein may be trademarks of their respective owners.
Page 1 of 35
Contents
1 ABOUT THIS DOCUMENT 5 5 5 5 5 6 6 7 8 9 9 9 10 10 10 10 11 11 13 13 14 14 14 15 15 15 15 15 15 16 17 18 18 18 18
1.1 Change control 1.1.1 Current status and anticipated changes 1.1.2 Change history 1.2 1.3 1.4 1.5 2 3 References Terms and abbreviations Your licence to use this specification Acknowledgements SCOPE INTRODUCTION
3.1 Most C library functions have a standard ABI 3.1.1 Already standardized C library functions 3.1.2 Nearly standardized C library functions 3.1.3 C library functions operating on potentially opaque structures 3.1.4 Miscellanea 3.2 3.3 3.4 4 4.1 A C library is all or nothing Important corollaries of this C library standardization model Private names for private and AEABI-specific helper functions THE C LIBRARY C Library overview
4.2 The C library standardization model 4.2.1 Purpose and principles 4.2.2 Obstacles to creating a C library ABI 4.2.2.1 Compile-time constants that cannot be constant at compile time 4.2.2.2 Inadequately specified structures 4.2.2.3 Inline functions that expose implementation details 4.2.2.4 Under-specified exported data 4.2.3 Our approach to defining a C library ABI 4.2.3.1 Compile time constants 4.2.3.2 Structures used in the C library interface 4.2.3.3 Inline functions 4.2.4 Naming issues in C++ header files 4.2.4.1 Names introduced by this C library ABI into <cyyy> headers 4.2.4.2 C++ names of C library functions 4.2.5 Library file organization
Page 2 of 35
4.3 5
18 20 20 20 20 21 21 22 22 23 23 23 23 24 25 26 26 27 28 28 28 28 28 29 29 30 30 31 31 31
5.1 Introduction and conventions 5.1.1 Detecting whether a header file honors an AEABI portability request 5.2 assert.h
5.3 ctype.h 5.3.1 ctype.h when _AEABI_PORTABILITY_LEVEL != 0 and isxxxxx inline 5.3.1.1 Encoding of ctype table entries and macros (_AEABI_PORTABILITY_LEVEL != 0) 5.4 5.5 5.6 5.7 5.8 5.9 5.10 5.11 5.12 5.13 5.14 5.15 5.16 errno.h float.h inttypes.h iso646.h limits.h locale.h math.h setjmp.h signal.h stdarg.h stdbool.h stddef.h stdint.h
5.17 stdio.h 5.17.1 Background discussion and rationale 5.17.2 Easy stdio.h definitions 5.17.3 Difficult stdio.h definitions 5.18 5.19 5.20 5.21 5.22 stdlib.h string.h time.h wchar.h wctype.h
Page 3 of 35
33
Page 4 of 35
Date 30 October 2003 24 March 2005 4 July 2005 5 October 2005 5 May 2006 25 October 2007
th th th th th th
By LS LS LS LS LS LS LS AC
Change First public DRAFT. First public release. First batch of typographical corrections. Added stdbool.h. Clarified the intention behind __B and isblank() in 5.3.1.1. Fixed the clash with the C99 specification. Corrected misinformation in 5.12 concerning (non-)atomic access to 8-byte types using ldrd/strd/ldm/stm. In 3.4, used the common table of registered vendor names Document renumbered (formerly GENC-003539 v2.04). Added 4.2.4.2 explaining why, in C++ generating portable binary, standard library functions should be used via extern C linkage. 5.2 Clarified the intended method of customizing assert(). 5.11 Corrected calculation of minimum jmp_buf size (previously given as 24 double-words).
2.03
2.04 / A B
th
C r2.09
1.2 References
This document refers to, and is referred to by, the following documents. Ref
AAELF AAPCS BSABI CLIBABI CPPABI RTABI
Title ELF for the ARM Architecture. Procedure Call Standard for the ARM Architecture. ABI for the ARM Architecture (Base Standard).
This document
C Library ABI for the ARM Architecture C++ ABI for the ARM Architecture Run-time ABI for the ARM Architecture.
Page 5 of 35
VFP
Specification means, and is limited to, the version of the specification for the Applications Binary Interface for the ARM Architecture comprised in this document. Notwithstanding the foregoing, Specification shall not include (i) the implementation of other published specifications referenced in this Specification; (ii) any enabling technologies that may be necessary to make or use any product or portion thereof that complies with this Specification, but are not themselves expressly set forth in this Specification (e.g. compiler front ends, code generators, back ends, libraries or other compiler, assembler or linker technologies; validation or debug software or hardware; applications, operating system or driver software; RISC architecture; processor microarchitecture); (iii) maskworks and physical layouts of integrated circuit designs; or (iv) RTL or other high level representations of integrated circuit designs. Use, copying or disclosure by the US Government is subject to the restrictions set out in subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and (2) of the Commercial Computer Software Restricted Rights at 48 C.F.R. 52.227-19, as applicable.
Page 6 of 35
This Specification is owned by ARM or its licensors and is protected by copyright laws and international copyright treaties as well as other intellectual property laws and treaties. The Specification is licensed not sold. 1. Subject to the provisions of Clauses 2 and 3, ARM hereby grants to LICENSEE, under any intellectual property that is (i) owned or freely licensable by ARM without payment to unaffiliated third parties and (ii) either embodied in the Specification or Necessary to copy or implement an applications binary interface compliant with this Specification, a perpetual, non-exclusive, non-transferable, fully paid, worldwide limited licence (without the right to sublicense) to use and copy this Specification solely for the purpose of developing, having developed, manufacturing, having manufactured, offering to sell, selling, supplying or otherwise distributing products which comply with the Specification.
THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO WARRANTIES EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF SATISFACTORY QUALITY, MERCHANTABILITY, NONINFRINGEMENT OR FITNESS FOR A PARTICULAR PURPOSE. THE SPECIFICATION MAY INCLUDE ERRORS. ARM RESERVES THE RIGHT TO INCORPORATE MODIFICATIONS TO THE SPECIFICATION IN LATER REVISIONS OF IT, AND TO MAKE IMPROVEMENTS OR CHANGES IN THE SPECIFICATION OR THE PRODUCTS OR TECHNOLOGIES DESCRIBED THEREIN AT ANY TIME.
2.
3.
This Licence shall immediately terminate and shall be unavailable to LICENSEE if LICENSEE or any party affiliated to LICENSEE asserts any patents against ARM, ARM affiliates, third parties who have a valid licence from ARM for the Specification, or any customers or distributors of any of them based upon a claim that a LICENSEE (or LICENSEE affiliate) patent is Necessary to implement the Specification. In this Licence; (i) affiliate means any entity controlling, controlled by or under common control with a party (in fact or in law, via voting securities, management control or otherwise) and affiliated shall be construed accordingly; (ii) assert means to allege infringement in legal or administrative proceedings, or proceedings before any other competent trade, arbitral or international authority; (iii) Necessary means with respect to any claims of any patent, those claims which, without the appropriate permission of the patent owner, will be infringed when implementing the Specification because no alternative, commercially reasonable, non-infringing way of implementing the Specification is known; and (iv) English law and the jurisdiction of the English courts shall apply to all aspects of this Licence, its interpretation and enforcement. The total liability of ARM and any of its suppliers and licensors under or in relation to this Licence shall be limited to the greater of the amount actually paid by LICENSEE for the Specification or US$10.00. The limitations, exclusions and disclaimers in this Licence shall apply to the maximum extent allowed by applicable law.
1.5 Acknowledgements
This specification has been developed with the active support of the following organizations. In alphabetical order: ARM, CodeSourcery, Intel, Metrowerks, Montavista, Nexus Electronics, PalmSource, Symbian, Texas Instruments, and Wind River.
Page 7 of 35
2 SCOPE
Conformance to the ABI for the ARM architecture [BSABI] supports inter-operation between:
Relocatable objects generated by different tool chains. Executables and shared objects generated for the same execution environment by different tool chains.
This standard for C library functions allows a relocatable object built by one conforming tool chain from ARMThumb assembly language, C, or standalone C++ to be compatible with the static linking environment provided by a different conforming tool chain. Figure 1, Inter-operation between relocatable objects
<header> header <header>
<header> <header>
header header
<header> <header>
Translator #2
Object Object code code Private Private helpers helpers Functions NOT standardized by the AEABI
In this model of inter-working, the standard headers used to build a relocatable object are those associated with the tool chain building it, not those associated with the library with which the object will, ultimately, be linked.
Run-time library
Run-time library
Executable
Page 8 of 35
3 INTRODUCTION
A number of principles of inter-operation are implicit in, or compatible with, Figure 1, above. This section describes these principles precisely, as they apply to a C library, and gives a rationale for each one. The corresponding section (3) of [RTABI] discusses the same principles as they apply to run-time helper functions.
Functions whose type signatures and argument ranges are precisely defined by a combination of the C standard and this ABI standard for data type size and alignment given in the [AAPCS]. These functions already have a standardized binary interface. Functions that would fall in the above category if there were agreement about the layout of a structure that is only partly defined by the C standard, or agreement about the range and meaning of controlling values passed to the function for which the C standard gives only a macro name. Functions that take as arguments pointers to structures whose fields are not defined by the standard (FILE, mbstate_t, fpos_t, jmp_buf), that can be standardized by considering the structures to be opaque. (But beware FILE, which is also expected to be accessed non-opaquely). Miscellanea such as errno, va_arg, va_start, and the ctype functions that are expected to be implemented by macros in ways that are unspecified by the standard. These must be examined case by case.
The C library declares few data objects, so standardization is concerned almost exclusively with functions. Some standard functions may be inlined The C and C++ standards allows compilers to recognize standard library functions and treat them specially, provided that such recognition does not depend on the inclusion of header files. In practice, this allows a compiler to inline any library function that neither reads nor writes program state (such as the state of the heap or the locale) managed by the library.
Its type signature is fixed. Its name is fixed by the C language standard. With some exceptions clearly identified by the C language standard (for example, whether malloc(0) NULL), Its behavior is fixed by the C language standard.
Page 9 of 35
Controlling values For controlling values there are some universal agreements (for example, about the values of NULL, SEEK_*,
EXIT_*) and some disagreements (about the values of LC_*, _IO*BF, etc).
Unfortunately, we must be able to define objects of all of these types except FILE (a library client only ever allocates objects of type FILE *), so the size of each object must be standardized even if the contents are not. Functions that manipulate types opaquely cannot be implemented inline. Thus getc, putc, getchar, putchar, and so on must be out of line functions. This might be acceptable in a deeply embedded application, but is unlikely to be unconditionally acceptable in high performance platform ABIs where there is a history of these functions being implemented by macros that operate on the implementation of FILE.
In 4, below, these functions are considered case by case under the library sub-sections that declare them.
3.1.4 Miscellanea
The implementations of macros such as errno, va_arg, va_start, and the ctype functions are unspecified by the C standard. These must be considered case by case.
The va_* macros essentially disappear. The type va_list and the binary interface to variadic functions are standardized by the AAPCS. We simply require compilers to inline what remains. There is probably no completely satisfactory cross platform definition of errno. 5.4, below, proposes a definition well suited to deeply embedded use, and adequately efficient elsewhere. For the ctype macros there is no escaping calling a function in the general case. (Consider how to handle changing locale, as must be done by an application that processes Chinese, Japanese, or Korean characters, because the C library is defined to start in the C locale).
Page 10 of 35
portable between tool chains (strlen, strcpy, strstr, etc), and vendors will work hard to ensure that a statically linked program will only include the functions it needs. Nonetheless, tangled clumps of implementation might underlie many apparently independent parts of a run-time library's public interface. In some cases, there may be an element of conspiracy between the run-time libraries, the static linker, and the ultimate execution environment. For example, the way that a program acquires its startup code (sometimes called crt0.o) may depend on the library and the static linker, as well as the execution environment. This leads us to a major conclusion for statically linked executables:
The static linker and the language run-time libraries must be from the same tool chain.
Accepting this constraint gives considerable scope for private arrangements (not governed by this ABI) between these tool chain components, restricted only by the requirement to provide a well defined binary interface (ABI) to the functions described in 3.1, above.
The vendor prefix must be registered with the maintainers of this ABI specification. Prefixes must not contain underscore ('_') or dollar ('$'). Prefixes beginning with Anon and anon are reserved to unregistered use. The table of registered vendor prefixes is given below.
Table of registered vendor prefixes Name aeabi AnonXyz anonXyz ARM Vendor Reserved to the ABI for the ARM Architecture (EABI pseudo-vendor) Reserved to private experiments by the Xyz vendor. Guaranteed not to clash with any registered vendor name. ARM Ltd (Note: the company, not the processor).
Page 11 of 35
Name cxa FSL GHS gnu iar intel ixs llvm PSI RAL TASKING TI tls WRS
Vendor C++ ABI pseudo-vendor Freescale Semiconductor Inc. Green Hills Systems GNU compilers and tools (Free Software Foundation) IAR Systems Intel Corporation Intel Xscale The LLVM/Clang projects PalmSource Inc. Rowley Associates Ltd Altium Ltd. TI Inc. Reserved for use in thread-local storage routines. Wind River Systems.
To register a vendor prefix with ARM, please E-mail your request to arm.eabi at arm.com.
Page 12 of 35
4 THE C LIBRARY
4.1 C Library overview
The C Library ABI for the ARM architecture is associated with the headers listed in Table 1 below. Some are defined by the ANSI 1989 (ISO 1990) standard for C (called C89 in this document), some by addenda to it, and some by the 1999 standard for C (called C99 in this document). Most are in the set of headers considered by 17.4.1.2 of the ANSI 1998 C++ standard to provide Headers for C Library Facilities. These are denoted in the table below by C. Table 1, C library headers Header assert.h ctype.h errno.h float.h inttypes.h iso646.h limits.h locale.h math.h setjmp.h signal.h stdarg.h stdbool.h stddef.h stdint.h stdio.h stdlib.h string.h time.h wchar.h wctype.h Origin C C C C C99 C C C C C C C C99 C C99 C C C C C C Comment See 5.2. Standardize __aeabi_assert(const char*, const char*, int). See 5.3. Inlined macros cause difficulties for standardization. See 5.4. Defined by ARMs choice of 32 and 64-bit IEEE 2s complement format. Defined by the AAPCS and commonsense. Defined by entirely the C standard. See 5.8. Defined by the AAPCS (save for MB_LEN_MAX). See 5.9. See 5.10. All fixed apart from HUGE_VAL and related C99 definitions. jmp_buf must be defined, setjmp and longjmp must not be inlined. See 5.12. Definitions of SIG_DFL, SIG_IGN, SIG_ERR, & signal #s are controversial. va_list is defined by AAPCS. Other artifacts are inline (compiler-defined) Defined by entirely the C standard Defined by the AAPCS. Defined by the ARM architecture + AAPCS + C standard. See 5.17. Inlined macros and properties of the environment cause difficulties. See 5.18. All fixed apart from MB_CUR_MAX. The interface is fixed by the AAPCS data type size rules. See 5.20. CLOCKS_PER_SEC is a property of the execution environment. See 5.21. No issues apart from mbstate_t. See 5.22. Defined by the AAPCS and commonsense.
Page 13 of 35
An application is built using a single tool chain. The executable may include statically linkable binary code from a 3rd party, built using a different tool chain. It may later be dynamically linked into an execution environment based on, or built by, yet another tool chain. A portable binary may be relocatable object code for static linking or an executable for dynamic linking. Principles Whatever we do to support the creation of an ABI standard for the C library must be compatible with the library sections of the C and C++ language standards, from the perspective of application code. It can conflict with and overrule these language standards only if invited to do so by portable code. Corollary: Anything reducing the guarantees given by a language standard must be guarded by:
#if _AEABI_PORTABILITY_LEVEL != 0
The ability to make portable binaries must impose no costs on non-portable application code. Portable code may incur costs including reduced performance and, or, loss of standard language guarantees. The cost of supporting portable binaries must be moderate for run-time libraries. Ideally, we should restrict the requirements to that which existing run-time libraries can support via pure extension and additional veneers.
Function declarations. Most of these have no consequences for binary compatibility because: For non-variadic functions the C standard guarantees that a function with that name will exist (because the user is entitled to declare it without including any library header). The meaning of the function is specified by the standard. The type signature involves only primitive types, and these are tightly specified by the AAPCS.
Macro definitions. Many expand to constants, a few to implementation functions. Many of the constant values follow from the C standard, the IEEE 754 FP standard, and the AAPCS. There is no choice of value for ARM-Thumb. Some constants such as EOF and NULL are uncontroversial and can be standardized.
An ABI issue arises if a constant does not have a consensus value and if a function is inlined.
Structure and type definitions. Most C library typedefs name primitive types fully defined by the AAPCS. Structure declarations affect binary inter-working only if there is variation in the size, alignment, or order of fields.
An ABI issue arises if the content and field order of a structure is not fully specified by the standard. ARM IHI 0039C
Copyright 2003-2007, 2009, 2012 ARM Limited. All rights reserved.
Page 14 of 35
Isdigit can be inlined in 2 ARM or Thumb instructions. Inline isxdigit takes 5 ARM or 8 Thumb instructions compared to 2-3 using a 256 byte helper table.
Everyone agrees all the values. Examples include NULL, SEEK_*, EXIT_*. These remain constants. Different implementations disagree about the values. Examples include _IO*BF, LC_*. This is the black list. Most implementations agree about most of the values. Examples include EDOM, ERANGE, and SIG* excluding SIGABRT. This is the grey list.
Page 15 of 35
Black list items must become link-time constants or run-time queries. Link-time constants are more efficient for the client and no more difficult for the execution environment. In both cases they can be supported as a thin veneer on an existing execution environment. Name-space pollution is the only serious standardization issue, but use of names of the form __aeabi_xxx and _AEABI_XXX deals with that for C. Because this change violates the ANSI standard, it must be guarded by:
#if _AEABI_PORTABILITY_LEVEL != 0.
Grey list items are a little more difficult. There are two options.
Treat each group as black or white on a case by case basis. Treat the consensus members as white and the remainder as black.
Consider EDOM, ERANGE, and EILSEQ from errno.h. This is a grey list category because there is consensus that EDOM = 33 and ERANGE = 34, but no consensus (even among Unix-like implementations) about EILSEQ. In practice, these values will be rarely accessed by portable code, so there is no associated performance or size issue, and they should all be considered black to maximize portability. A similar argument suggests all the SIG* values should be considered black. Portable code will rarely raise a signal, and there is no overhead on the run-time environment to define the link-time constants, so we might as well err on the side of portability. Thus a clear principle emerges that seems to work robustly and satisfy all of principles and goals stated in 4.2.1. Namely, if any member of a related group of manifest constants does not have a consensus value, the whole group become link-time constants when _AEABI_PORTABILITY_LEVEL != 0. A general template for managing this is:
#if _AEABI_PORTABILITY_LEVEL == 0 # define XXXX .... #else extern const int __aeabi_XXXX; # define XXXX (__aeabi_XXXX) #endif
In other words, the compile time constant XXXX becomes the constant value __aeabi_XXXX (unless XXXX begins with an underscore, in which case underscores are omitted until only one remains after __aeabi).. This much imposes no overheads on non-portable (application) code, only trivial compliance overhead (provide a list of constant definitions) on tool chains and execution environments, and only a small tax on portable binaries.
A portable binary must contrive to obtain any needed jmp_buf structures from its client environment, either via parameters or extern data, and neither setjmp nor longjmp can be inlined.
(Aside: A link-time value __aeabi_JMP_BUF_SIZE would support allocating a jmp_buf using malloc. End aside).
Page 16 of 35
The *div_t structures are formal requirements of the C standard. They are unlikely to be used in the ARM world. We will define them consistent with the ARM helper functions for division. When _AEABI_PORTABILITY_LEVEL != 0 the definitions should simply disappear (in order to remove a marginal portability hazard). Two structures tm and lconv are definitely not opaque, and we discuss them further below. struct tm Most implementers agree that struct tm should be declared to be the C89/C99 fields in the order listed in the standards. BSD systems add two additional fields at the end relating to the time zone. It is a defect in BSD that a call to strftime() with a struct tm in which the additional fields have not been initialized properly can crash, even when the format string has no need to access the fields. We have reported this defect to the BSD maintainers. This ABI defines struct tm to contain two extra, trailing words that must not be used by ABI-conforming code. struct lconv Unfortunately, lconv has been extended between C89 and C99 (with 6 additional fields) and the C89 field order has changed in the C99 standard (though the new fields are listed last). Fortunately, lconv is generated by a C library, but not consumed by a C library. It is output only. That allows us to define the field order for portable objects, provided a portable object never passes a struct lconv to a non-portable object. In other words, when _AEABI_PORTABILITY_LEVEL != 0, struct lconv should be replaced by struct __aeabi_lconv, and localeconv by __aeabi_localeconv. We define the field order to be the C89 order followed by the new fields, so in many cases __aeabi_localeconv will simply be a synonym for localeconv. At worst it will be a small veneer.
They can be out of line (isdigit excepted). This always works, imposes no overhead on the execution environment, and delivers the semantic guarantees of the standard to portable code. There can be a defined tabular implementation that the execution environment must support.
The second option can be a near zero cost addition to an existing execution environment provided a portable binary can bind statically to its ctype locale. All that needs to be provided are tables with defined names. No upheaval is required in the underlying ctype/locale system. The choice available to a user building a portable binary is then between the following.
All ctype functions are out of line (save isdigit and, perhaps, isxdigit). This is the appropriate choice when ctype performance does not matter, or the code must depend on the dynamic choice of ctype locale.
All ctype functions are inlined using a helper table appropriate to the statically chosen ctype locale. The implementation is sketched in 5.3, below. The binding is managed by defining _AEABI_LC_CTYPE to be one of C, ISO8859_1, or SJIS. This is the appropriate choice when the ctype locale is known statically and performance does matter.
Page 17 of 35
Those declared in the standard interface to the C library. In many cases a user can legitimately declare these in a source program without including any library header file. Those defined by the AEABI to be standard helper functions or data (this specification and [RTABI]).
Page 18 of 35
Those provided with the relocatable file (as part of the relocatable file, or as a separate, freely distributable library provided with the relocatable file).
When generating a portable relocatable file, a compiler must not generate a reference to any other library entity. Note that a platform environment will often require all platform-targeted tool chains to use the same header files (defined by the platform). Such objects are not portable, but exportable only to a single environment.
Page 19 of 35
The required definition (independent of _AEABI_PORTABILITY_LEVEL). Or, the recommended definition when _AEABI_PORTABILITY_LEVEL = 0 (if there is one), and the required definition when _AEABI_PORTABILITY_LEVEL != 0.
Library header
5.2 assert.h
Although the standard does not specify it, a failing assert macro must eventually call a function of 3 arguments as shown in Table 3, below. As specified by the C standard, this function must print details of the failing diagnostic then terminate by calling abort. A C library implementation can fabricate a lighter weight, no arguments, nonprinting, non-conformant version of assert() by calling abort directly, so we define no variants of __aeabi_assert(). Table 3, Assert.h declarations Name assert Required definition (when generating a message) void __aeabi_assert(const char *expr, const char *file, int line); #define assert(__e) ((__e) ? (void)0 : __aeabi_assert(#__e, __FILE__, __LINE__))
Page 20 of 35
5.3 ctype.h
The ctype functions are fully defined by the C standard and the [AAPCS]. Each function takes an int parameter whose value is restricted to the values {unsigned char, EOF}, and returns an int result. The ctype functions are often implemented inline as macros that test attributes encoded in a table indexed by the characters value (from EOF = -1 to UCHAR_MAX = 255). Using a fixed data table does not sit comfortably with being able to change locale in an execution environment in which all tables are in ROM. The functions isdigit and isxdigit have locale-independent definitions so they can be inlined under the assumption that the encoding of common characters will follow 7-bit ASCII in all locales. Under this assumption, isdigit can be defined as an unsigned range test that takes just two instructions.
#define isdigit(c) (((unsigned)(c) - '0') < 10)
The analogous implementation of isxdigit takes 12 Thumb or 7 ARM instructions (24-28 bytes), which is usually unattractive to inline. However, implementations can inline this without creating a portability hazard.
#define isxdigit(c) (((unsigned)(c) & ~0x20) 0x41) < 6 || isdigit(c))
Not to inline the ctype functions (other than isdigit and, perhaps, isxdigit, as described above). To implement these functions inline as described in the next subsection.
A conforming C library implementation must support both alternatives. A conforming ctype.h must signal its conformance as described in 5.1.1.
Where expxxxxx is an expression that evaluates its the argument c only once and __aeabi_ctype_table is a table of character attributes indexed from 0 to 256 inclusive. We define link-time selection of the attribute table in a locale-dependent way using the following structure. The same character translations and locale bindings should be used by the toxxxx macros and functions.
/* Mandatory character attribute arrays indexed from 0 to 256 */ extern unsigned char const __aeabi_ctype_table_C[257]; /* "C" locale */ extern unsigned char const __aeabi_ctype_table_[257]; /* default locale */ /* The default locale might be the C locale */ /* Optional character attribute arrays indexed from 0 to 256. */ /* These do not have to be provided by every execution environment */ /* but, if provided, shall be provided with these names and meaning. */ extern unsigned char const __aeabi_ctype_table_ISO8859_1[257]; extern unsigned char const __aeabi_ctype_table_SJIS[257]; extern unsigned char const __aeabi_ctype_table_BIG5[257]; extern unsigned char const __aeabi_ctype_table_UTF8[257]; #ifdef _AEABI_LC_CTYPE # define _AEABI_CTYPE_TABLE(_X) __aeabi_ctype_table_ ## _X # define _AEABI_CTYPE(_X) _AEABI_CTYPE_TABLE(_X) # define __aeabi_ctype_table _AEABI_CTYPE(_AEABI_LC_CTYPE) #else # define __aeabi_ctype_table __aeabi_ctype_table_ #endif
Page 21 of 35
To make a link-time selection of the ctype locale for this compilation unit, define _AEABI_PORTABILITY_LEVEL != 0 and _AEABI_LC_CTYPE to one of the values listed below before including ctype.h.
Leave _AEABI_LC_CTYPE undefined or defined with no value (D_AEABI_LC_CTYPE= or #define _AEABI_LC_CTYPE) to statically bind to the default locale. Define _AEABI_LC_CTYPE to be C, to statically bind to the C locale. Define _AEABI_LC_CTYPE to be one of the defined locale names ISO8859_1, SJIS, BIG5, or UTF8 to bind to the corresponding locale name.
(Aside: A conforming environment shall support the C locale and a default locale for ctype. The default locale may be the C locale. Relocatable files binding statically to any other ctype locale shall provide the ctype table encoded as described in 5.3.1.1, in a COMDAT section or in an adjunct library. End aside).
isspace(x) isalpha(x) isalnum(x) isprint(x) isupper(x) islower(x) isxdigit(x) isblank(x) isgraph(x) iscntrl(x) ispunct(x)
((__aeabi_ctype_table+1)[x] & __S) ((__aeabi_ctype_table+1)[x] & __A) ((__aeabi_ctype_table+1)[x] << 30) // test for __A and __X ((__aeabi_ctype_table+1)[x] << 28) // test for __A, __X, __P and __B ((__aeabi_ctype_table+1)[x] & __U) ((__aeabi_ctype_table+1)[x] & __L) ((__aeabi_ctype_table+1)[x] & __X) (isblank)(x) /* C99 isblank() is not a simple macro */ ((__aeabi_ctype_table+1)[x] << 29) // test for __A, __X and __P ((__aeabi_ctype_table+1)[x] & __C) ((__aeabi_ctype_table+1)[x] & __P)
In the "C" locale, the C99 function isblank() returns true for precisely space and tab while the C89 function isprint() returns true for any character that occupies one printing position (hence excluding tab). isblank(x) can be simply implemented as (x == \t || ((__aeabi_ctype_table+1)[x] & __B)) , but because x is evaluated twice in this expression, it is not a satisfactory (standard conforming) macro. A compiler may, nonetheless, safely inline this implementation of the isblank() function.
5.4 errno.h
There are many reasons why accessing errno should call a function call. We define it as shown in Table 4, below.
Page 22 of 35
Table 4, errno.h definitions Name and signature errno EDOM ERANGE EILSEQ (C89 NA 1/ C99) Recommended value (*__aeabi_errno_addr()) 33 34 47 (42, or 84) Required portable definition
volatile int *__aeabi_errno_addr(void); (*__aeabi_errno_addr()) extern const int __aeabi_EDOM = 33; (__aeabi_EDOM) extern const int __aeabi_ERANGE = 34; (__aeabi_ERANGE) extern const int __aeabi_EILSEQ = 47; (__aeabi_EILSEQ)
(Aside: There seems to be general agreement on 33 and 34, the long established Unix values of EDOM and ERANGE. There is little consensus about EILSEQ. 47 is claimed to be the IEEE 1003.1 POSIX value. End aside).
5.5 float.h
The values in float.h follow from the choice of 32/64-bit 2s complement IEEE format floating point arithmetic. This header does not define _AEABI_PORTABLE (5.1.1).
5.6 inttypes.h
This C99 header file refers only to types and values standardized by the AEABI. It declares only constants and real functions whose type signatures involve only primitive types. Note that plain char is unsigned [AAPCS]. This header does not define _AEABI_PORTABLE (5.1.1).
5.7 iso646.h
This header contains macros only. The definitions are standardized by a C89 normative addendum (and by C++). This header does not define _AEABI_PORTABLE (5.1.1).
5.8 limits.h
Other than MB_LEN_MAX, the values of the macros defined by limits.h follow from the data type sizes given in the AAPCS and the use of 2s complement representations. Conforming implementations must also define the C99 macros LLONG_MIN, LLONG_MAX, and ULLONG_MAX, and define _AEABI_PORTABLE when _AEABI_PORTABILITY_LEVEL != 0 (as specified in 5.1.1) Table 5, The value of MB_LEN_MAX Name MB_LEN_MAX Recommended value 6 Required portable definition
extern const int __aeabi_MB_LEN_MAX = 6; (__aeabi_MB_LEN_MAX)
Page 23 of 35
5.9 locale.h
Locale.h defines 6 macros for controlling constants (Table 8) and struct lconv. The setlocale and localeconv functions are otherwise tightly specified by their type signatures, and AAPCS data type size and alignment. The C standard requires a minimum set of fields in struct lconv and places no constraints on their order. The C99 standard mandates an additional six fields, and lists them last. Unfortunately, it lists the C89 fields in a different order to that given in the C89 standard. Prior art generally defines the C89 fields in the same order as listed in the C89 standard, or the C99 fields in the same order as in the C99 standard. No order is compatible with both. The localeconv function returns a pointer to a struct lconv. This must be correctly interpreted by clients using the C89 specification and clients using the C99 specification. Consequently:
The structure must contain all the C99-specified fields. The order of the C89-specified fields must be as listed in the C89 standard.
To support layering on run-time libraries that do not implement the full C99 definition of struct lconv, or that implement it with a different field order, we define struct __aeabi_lconv and __aeabi_localeconv. In the C++ header <clocale> both must be declared in namespace std::. When _AEABI_PORTABILITY_LEVEL != 0, the declarations of struct lconv and localeconv must be hidden, and _AEABI_PORTABLE should be defined as specified in 5.1.1. Table 6, struct __aeabi_lconv
struct char char char char char char char char char char char char char char char char char char /* The char char char char char char }; __aeabi_lconv { *decimal_point; *thousands_sep; *grouping; *int_curr_symbol; *currency_symbol; *mon_decimal_point; *mon_thousands_sep; *mon_grouping; *positive_sign; *negative_sign; int_frac_digits; frac_digits; p_cs_precedes; p_sep_by_space; n_cs_precedes; n_sep_by_space; p_sign_posn; n_sign_posn; following fields are added by C99 */ int_p_cs_precedes; int_n_cs_precedes; int_p_sep_by_space; int_n_sep_by_space; int_p_sign_posn; int_n_sign_posn;
Page 24 of 35
__aeabi_lconv __aeabi_localeconv
As in Table 6, above.
struct __aeabi_lconv *__aeabi_localeconv(void)
5.10 math.h
Math.h functions are functions of primitive types only and raise no standardization issues. The definitions of HUGE_VAL and its C99 counterparts HUGE_VALF, HUGE_VALL, NAN and INFINITY are slightly problematic in strict C89. HUGE_VAL must either expand to a constant specified by some non-C89 means (for example, as a C99 hexadecimal FP bit pattern), or it must expand to a location in the C library initialized with the appropriate value by some non-C89 means (for example, using assembly language). Tool chains that define these macros as listed in the required value column of Table 9 can use the same definitions inline when _AEABI_PORTABILITY_LEVEL != 0. Otherwise, the alternative portable definition must be used when _AEABI_PORTABILITY_LEVEL != 0. The macro _AEABI_PORTABLE should be defined as described in 5.1.1. Table 9, math.h definitions Name HUGE_VAL HUGE_VALL HUGE_VALF INFINITY NAN Required value 0d_7FF0000000000000 0d_7FF0000000000000 0d_7F800000 0f_7F800000 0f_7FC00000 Alternative portable definition extern const double __aeabi_HUGE_VAL extern const long double __aeabi_HUGE_VALL extern const float __aeabi_HUGE_VALF extern const float __aeabi_INFINITY extern const float __aeabi_NAN Comment Double infinity Long double infinity Float infinity Float infinity Quiet NaN
Page 25 of 35
5.11 setjmp.h
The type and size of jmp_buf are defined by setjmp.h. Its contents are opaque, so setjmp and longjmp must be from the same library, and called out of line. In deference to VFP, XScale Wireless MMX, and other co-processors manipulating 8-byte aligned types, a jmp_buf must be 8-byte aligned. The minimum jmp_buf size is calculated as follows: SP, LR: 2x4; reserved to setjmp implementation: 4x4; Total 3x8 bytes General purpose register save: 8x4; Total 4x8 bytes Floating point register save: 8x8; Total 8x8 bytes WMMX (if present): 5x8; Total 5x8 bytes Total: 20x8 = 160 bytes = 20 8-byte double-words. If WMMX can be guaranteed not to be present this can be reduced to 15x8 = 120 bytes. If floating point hardware can be guaranteed not to be present this can be further reduced to 7x8 = 56 bytes. An implementation may define the size of a jmp_buf to be larger than the ABI-defined minimum size. If code allocates a jmp_buf statically using a compile-time constant size smaller than the "maximum minimum" value of 160 bytes, the size of the jmp_buf becomes part of its interface contract. Portable code is urged not to do this. The link-time constant __aeabi_JMP_BUF_SIZE gives the actual size of a target system jmp_buf measured in 8byte double-words. When _AEABI_PORTABILITY_LEVEL != 0, the required definition of jmp_buf cannot be used to create jmp_buf objects. Instead, a jmp_buf must be passed as a parameter or allocated dynamically. Table 10, setjmp.h definitions Name jmp_buf __aeabi_JMP_BUF_SIZE Recommended definition
(_AEABI_PORTABILITY_LEVEL = 0)
5.12 signal.h
Signal.h declares the typedef sig_atomic_t which is unused in the signal interface. ARM processors from architecture v4 onwards support uni-processor atomic access to 1, 2, and 4 byte data. Uniprocessors that do not use low latency mode might support atomic access to 8-byte data via LDM/STM and/or LDRD/STRD. In architecture v6, LDREX/STREX gives multi-processor-safe atomic access to 4-byte data, and from v7 onwards the load/store exclusive instruction family gives MP-safe atomic access to 1, 2, 4, and 8 byte data. The only access size likely to work with all ARM CPUs, buses, and memory systems is 4-bytes, so we strongly recommend sig_atomic_t to be int (and require this definition when _AEABI_PORTABILITY_LEVEL != 0).
Page 26 of 35
Also declared are function pointer constants SIG_DFL, SIG_IGN, and SIG_ERR. Usually, these are defined to be suitably cast integer constants such as 0, 1, and -1. Unfortunately, when facing an unknown embedded system, there are no address values that can be safely reserved, other than addresses in the program itself. It is a quality of implementation whether at least one byte of program image space will be allocated to each of __aeabi_SIG_* listed in Table 11, or whether references to those values will be relocated to distinct, targetdependent constants. Signal.h defines six SIGXXX macros. We recommend the common Linux/Unix values listed in Table 12. All signal values are less than 64. With the exception of SIGABRT, these are also the Windows SIGXXX values. When _AEABI_PORTABILITY_LEVEL != 0, conforming implementations should define _AEABI_PORTABLE as specified in 5.1.1. Table 11, signal.h standard handler definitions Name
sig_atomic_t SIG_DFL
SIG_IGN
SIG_ERR
Recommended value
6
SIGFPE
SIGILL
SIGINT
SIGSEGV
11
SIGTERM
15
5.13 stdarg.h
Stdarg.h declares the type va_list defined by the [AAPCS] and three macros, va_start, va_arg, and va_end. Only va_list appears in binary interfaces. This header does not define _AEABI_PORTABLE (5.1.1).
Page 27 of 35
5.14 stdbool.h
Stdbool.h defines the type bool and the values true and false. This header does not define _AEABI_PORTABLE (5.1.1).
5.15 stddef.h
The size and alignment of each typedef declared in stddef.h is specified by the [AAPCS]. This header does not define _AEABI_PORTABLE (5.1.1).
5.16 stdint.h
The types declared in this C99 header are defined by the ARM architecture and [AAPCS]. This header does not define _AEABI_PORTABLE (5.1.1).
5.17 stdio.h
5.17.1 Background discussion and rationale
Stream-oriented library functions can only be useful if the end user (of a deeply embedded program), or the underlying operating environment, can implement the stream object (that is, the FILE structure). To standardize portably what can be standardized in binary form:
A FILE must be opaque. Writing to a stream must reduce to a sequence of calls to a lowest common denominator stream operation such as fputc (sensible for fprintf, but less so for fwrite). Similarly, reading from a stream must reduce to a sequence of calls to fgetc. putc, putchar, getc, and getchar cannot be inlined in applications, but must expand to an out of line call to a function from the library. We must take care with stdin, stdout, and stderr, as discussed in 4.2.2.4.
Surprisingly, these constraints can be compatible with high performance implementations of fread, fwrite, and fprintf. For example, if __flsbuf is included from the RVCT C library (effectively ARMs implementation of fputc), a faster fwrite, aware of the FILE implementation, replaces use of the generic fputc-using fwrite. In principle the same trick can be used with fprintf (probably not worthwhile) and fread (definitely worthwhile). The most contentious issue remaining is that of not being able to inline getc and putc. However, the effect of such inlining on performance will usually be much less dramatic than might be imagined.
The essential work of putc takes about 10 cycles (ARM9-class CPU) and uses four registers in almost any plausible implementation. Getc is similar, but needs only 3 registers. Fputc and fgetc both embed a conditional tail continuation and use most of the AAPCS scratch registers, so the difference in effect on register allocation between putc inline and a call to fputc will often be small.
In essence, the inescapable additional cost of putc out of line (getc is similar) is only:
The cost of the call and return, typically about 6 cycles. A move of the stream handle to r1 (r0 for getc), costing 1 cycle.
Page 28 of 35
Given some loop overhead and some, even trivial, processing of each character, it is hard to see how moving putc (or getc) out of line could add more than 25% to the directly visible per-character cycle count. Given that buffer flushing and filling probably doubles the visible per-character cycle count, the overall impact on performance is unlikely to be more than 10-15%, even when almost no work is being done on each character written or read. When _AEABI_PORTABILITY_LEVEL != 0, conforming implementations should define _AEABI_PORTABLE as specified in 5.1.1.
256 8
Page 29 of 35
256 256
(__aeabi_TMP_MAX) extern const int __aeabi_FILENAME_MAX = 256; (__aeabi_FILENAME_MAX) extern const int __aeabi_L_tmpnam = 256; (__aeabi_L_tmpnam)
Among these difficult constants, BUFSIZ is least difficult. It is merely the default for a value that can be specified by calling setvbuf. A cautious application can use a more appropriate value. FOPEN_MAX is the minimum number of files the execution environment guarantees can be open simultaneously. Similarly, TMP_MAX is the minimum number of distinct temporary file names generated by calling tmpnam.
(Aside: In the 1.7M lines of source code in the ARM code size database encompassing a broad spectrum of applications from deeply embedded to gcc_cc1 and povray L_tmpnam is unused, FILENAME_MAX is used just 5 times [in 1 application], and there are no uses of TMP_MAX save in one application that simulates a run-time environment. End aside).
5.18 stdlib.h
Stdlib.h contains the following interface difficulties.
The div_t and ldiv_t structures and div and ldiv functions. We think these functions are little used, so we define the structures in the obvious way. Because the functions are pure, compilers are entitled to inline them. The values of EXIT_FAILURE and EXIT_SUCCESS. There is near universal agreement that success is 0 and failure is non-0, usually 1. MB_CUR_MAX. This can only expand into a function call (to get the current maximum length of a localespecific multi-byte sequence. This is a marginal issue for embedded applications, though not for platforms.. We do not standardize the sequence computed by rand(). If an application depends on pseudo-random numbers, we believe it will use its own generator. Getenv and system are both questionable candidates for an embedded (rather than platform) ABI standard. We do not standardize either function.
When _AEABI_PORTABILITY_LEVEL != 0, a conforming implementation must define _AEABI_PORTABLE as specified in 5.1.1. Table 15, stdlib.h definitions Name div_t ldiv_t lldiv_t EXIT_SUCCESS EXIT_FAILURE MB_CUR_MAX Required definition struct { int quot, rem; } struct { long int quot, rem; } struct { long long int quot, rem; } 0 1 (__aeabi_MB_CUR_MAX()) Comment / Required portable definition div and ldiv are pure and can be inlined. lldiv_t and lldiv are C99 extensions. Everyone agrees. int __aeabi_MB_CUR_MAX(void);
5.19 string.h
String.h poses no interface problems. It contains only function declarations using standard basic types. With the exception of strtok (which has static state), and strcoll and strxfrm (which depend on the locale setting), all functions are pure may be inlined by a compiler. This header does not define _AEABI_PORTABLE (5.1.1).
Page 30 of 35
5.20 time.h
The time.h header defines typedefs clock_t and time_t, struct tm, and the constant CLOCKS_PER_SEC. The constant is properly a property of the execution environment. Portable code should not assume that time_t or clock_t are either signed or unsigned, and should generate only positive values no larger than INT_MAX. When _AEABI_PORTABILITY_LEVEL != 0, a conforming implementation must define _AEABI_PORTABLE as specified in 5.1.1. Table 16, time.h definitions Name time_t; clock_t; struct tm {} Required portable definition unsigned int; unsigned int; All and only the fields listed in the C89 standard, in the published order, together with 2 additional 4-byte trailing fields (as discussed in 4.2.3.2, above). extern const int __aeabi_CLOCKS_PER_SEC; (__aeabi_CLOCKS_PER_SEC)
CLOCKS_PER_SEC
5.21 wchar.h
The interface to entities declared in this header is largely defined by the AAPCS. It must also define wint_t, WEOF, and mbstate_t. There is little reason for wint_t to be other than int, and for WEOF to be other than -1. For mbstate_t we define a structure field big enough to hold the data from an incomplete multi-byte character together with its shift state. 32-bits suffice for any CJK-specific encoding such as shift-JIS, Big-5, UTF8, and UTF16. Because the structure is always addressed indirectly, we also include some headroom. When _AEABI_PORTABILITY_LEVEL != 0, conforming implementations must not inline functions read or write an mbstate_t, and should define _AEABI_PORTABLE as specified in 5.1.1. Table 17, wchar.h definitions Name wint_t WEOF mbstate_t Required definition int ((wint_t)-1) struct { unsigned state1, state2;} Big enough for CJK-specifics, UTF8 and UTF16, and some headroom. Comment
5.22 wctype.h
This header is mostly defined by the AAPCS and wchar.h. The only additional types defined are wctype_t and wctrans_t. Both are handles passed to or produced by wide character functions. When _AEABI_PORTABILITY_LEVEL != 0, conforming implementations must not inline functions that accept or produce these handles, and should define _AEABI_PORTABLE as specified in 5.1.1. Table 18, wctype.h definitions Name Required definition Comment
Page 31 of 35
wctype_t wctrans_t
void * void *
Page 32 of 35
Summary of conformance requirements Must declare __aeabi_assert (Table 3). Must define isxxxx(c) to be ((isxxxx)(c)) etc [no inline implementation] or implement the inline versions as described in 5.3.1. errno is (*__aeabi_errno()); EDOM, ERANGE, etc are link-time constants (Table 4)
MB_LEN_MAX is a link-time constant (Table 5). Must hide struct lconv and localeconv and declare struct __aeabi_lconv and __aeabi_localeconv (Table 6, Table 7). LC_* are link-time constants (Table 8). Must define HUGE_VAL and similar using non-C89 means (e.g. C99 hex float notation) or provide suitably initialized const library members (Table 9). Must declare jmp_buf[] to preclude creating such objects. __aeabi_JMP_BUF_SIZE is a link-time constant (Table 10). SIG_* are defined by the library (Table 11); SIG* are link-time const (Table 12).
time_t ,clock_t, and struct tm must be as specified in Table 16. CLOCKS_PER_SEC must be a link-time constant. wint_t, WEOF, and mbstate_t must be declared as specified in Table 17. wctype_t and wctrans_t must be opaque handles as specified in Table 18.
Affected headers (only) must #define _AEABI_PORTABLE if (and only if) they honor their portability obligations and _AEABI_PORTABILITY_LEVEL has been defined by the user (5.1.1).
Page 33 of 35
Table 20, Summary of link-time constants (when _AEABI_PORTABILITY_LEVEL != 0) Header errno.h ANSI C macro
EDOM ERANGE EILSEQ
limits.h locale.h
setjmp.h signal.h
None
SIGABRT SIGFPE SIGILL SIGINT SIGSEGV SIGTERM
stdio.h
time.h
CLOCKS_PER_SEC
If possible, link-time constants should be defined with visibility STV_HIDDEN [AAELF], and linked statically with client code. Dynamic linking is possible, but will almost always be significantly less efficient. Table 21, Additional functions (when _AEABI_PORTABILITY_LEVEL != 0) Header ANSI C macro AEABI function
Page 34 of 35
assert.h
assert
void __aeabi_assert( const char *expr, const char *file, int line); volatile int *__aeabi_errno_addr(void); (*__aeabi_errno_addr()) struct __aeabi_lconv *__aeabi_localeconv(void); extern void __aeabi_SIG_DFL(int); extern void __aeabi_SIG_IGN(int); extern void __aeabi_SIG_ERR(int); int __aeabi_MB_CUR_MAX(void);
errno
None
SIG_DFL SIG_IGN SIG_ERR
stdlib.h
MB_CUR_MAX
It is an implementation choice whether __aeabi_SIG_* occupy space in the run-time library, or whether they resolve to absolute symbols. As with other link-time constants, these should be defined with visibility STV_HIDDEN [AAELF], and linked statically with client code. Dynamic linking is possible, but will almost always be significantly less efficient.
Page 35 of 35