Clibabi 32
Clibabi 32
2023Q3
1.2 Keywords
C library ABI, run-time library
2
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
1.4 Licence
This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of
this license, visit http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative Commons, PO Box 1866,
Mountain View, CA 94042, USA.
Grant of Patent License. Subject to the terms and conditions of this license (both the Public License and this Patent
License), each Licensor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and
otherwise transfer the Licensed Material, where such license applies only to those patent claims licensable by such
Licensor that are necessarily infringed by their contribution(s) alone or by combination of their contribution(s) with the
Licensed Material to which such contribution(s) was submitted. If You institute patent litigation against any entity
(including a cross-claim or counterclaim in a lawsuit) alleging that the Licensed Material or a contribution incorporated
within the Licensed Material constitutes direct or contributory patent infringement, then any licenses granted to You
under this license for that Licensed Material shall terminate as of the date such litigation is filed.
1.6 Contributions
Contributions to this project are licensed under an inbound=outbound model such that any such contributions are
licensed by the contributor under the same terms as those in the Licence section.
1.8 Copyright
Copyright (c) 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
3
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
Contents
1 Preamble 2
1.1 Abstract 2
1.2 Keywords 2
1.3 Latest release and defects report 2
1.4 Licence 3
1.5 About the license 3
1.6 Contributions 3
1.7 Trademark notice 3
1.8 Copyright 3
2 About this document 6
2.1 Change control 6
2.1.1 Current status and anticipated changes 6
2.1.2 Change history 6
2.2 Terms and abbreviations 7
2.3 Acknowledgements 8
3 Scope 8
4 Introduction 10
4.1 Most C library functions have a standard ABI 10
4.1.1 Already standardized C library functions 10
4.1.2 Nearly standardized C library functions 10
4.1.3 C library functions operating on potentially opaque structures 11
4.1.4 Miscellanea 11
4.2 A C library is all or nothing 11
4.3 Important corollaries of this C library standardization model 12
4.4 Private names for private and AEABI-specific helper functions 12
5 The C library 14
5.1 C Library overview 14
5.2 The C library standardization model 15
5.2.1 Purpose and principles 15
5.2.2 Obstacles to creating a C library ABI 15
5.2.3 Our approach to defining a C library ABI 16
5.2.4 Naming issues in C++ header files 19
5.2.5 Library file organization 19
5.3 Summary of the inter-toolchain compatibility model 19
6 The C library section by section 21
6.1 Introduction and conventions 21
6.1.1 Detecting whether a header file honors an AEABI portability request 21
4
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
6.2 assert.h 21
6.3 ctype.h 22
6.3.1 ctype.h when _AEABI_PORTABILITY_LEVEL != 0 and isxxxxx inline 22
6.4 errno.h 24
6.5 float.h 24
6.6 inttypes.h 24
6.7 iso646.h 24
6.8 limits.h 25
6.9 locale.h 25
6.10 math.h 26
6.11 setjmp.h 27
6.12 signal.h 28
6.13 stdarg.h 29
6.14 stdbool.h 29
6.15 stddef.h 29
6.16 stdint.h 29
6.17 stdio.h 29
6.17.1 Background discussion and rationale 29
6.17.2 Easy stdio.h definitions 30
6.17.3 Difficult stdio.h definitions 31
6.18 stdlib.h 32
6.19 string.h 33
6.20 time.h 33
6.21 wchar.h 33
6.22 wctype.h 34
7 Summary of requirements on C Libraries 35
5
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
2 About this document
2.1 Change control
2.01 4th July 2005 First batch of typographical corrections. Added stdbool.h.
2.02 5th October 2005 Clarified the intention behind __B and isblank() in Encoding of ctype table
entries and macros (_AEABI_PORTABILITY_LEVEL != 0). Fixed the clash
with the C99 specification.
2.03 5th May 2006 Corrected misinformation in signal.h concerning (non-)atomic access to
8-byte types using ldrd/strd/ldm/stm.
2.04 / A 25th October 2007 In Private names for private and AEABI-specific helper functions, used the
common table of registered vendor names Document renumbered (formerly
GENC-003539 v2.04).
B 4th November 2009 Added C++ names of C library functions explaining why, in C++ generating
portable binary, standard library functions should be used via extern “C”
linkage.
C r2.09 30th November 2012 assert.h Clarified the intended method of customizing assert(). setjmp.h
Corrected calculation of minimum jmp_buf size (previously given as 24
double-words).
6
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
Issue Date Change
th
D r2.10 24 November 2015 wchar.h Permit wint_t to be unsigned int.
2021Q1 12th April 2021 Suggest placement of BTI after setjmp calls.
This document refers to, and is referred to by, the following documents.
1. The specifications to which an executable must conform in order to execute in a specific execution
environment. For example, the Linux ABI for the Arm Architecture.
2. A particular aspect of the specifications to which independently produced relocatable files must conform in
order to be statically linkable and executable. For example, the AAELF32, RTABI32, ...
AEABI
(Embedded) ABI for the Arm architecture (this ABI...)
Arm-based
... based on the Arm architecture ...
Branch Target Identification
Security technique ensuring a degree of control flow integrity by marking valid targets of indirect branches.
core registers
The general purpose registers visible in the Arm architecture’s programmer’s model, typically r0-r12, SP, LR, PC,
and CPSR.
EABI
An ABI suited to the needs of embedded, and deeply embedded (sometimes called free standing), applications.
7
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
Q-o-I
Quality of Implementation – a quality, behavior, functionality, or mechanism not required by this standard, but
which might be provided by systems conforming to it. Q-o-I is often used to describe the toolchain-specific means
by which a standard requirement is met.
VFP
The Arm architecture’s Floating Point architecture and instruction set. In this ABI, this abbreviation includes all
floating point variants regardless of whether or not vector (V) mode is supported.
2.3 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.
3 Scope
Conformance to the ABI for the Arm architecture [BSABI32] supports inter-operation between:
This standard for C library functions allows a relocatable object built by one conforming toolchain from Arm-Thumb
assembly language, C, or standalone C++ to be compatible with the static linking environment provided by a different
conforming toolchain.
8
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
< header> " header" < header>
< header> " header" < header>
< header> " header" < header>
Source File
Source File
Source File
Translat or Translat or
#1 #2
Syst em headers
describe bot h
AEABI and non- Object Object
AEABI funct ions code
Object code
Object
code code
Privat e Privat e
helpers
Privat e helpers
Privat e
helpers helpers
Run-t im e library
Run-t im e library
st andardized st andardized
by t he AEABI by t he AEABI
St at ic St at ic
linker # 1 linker # 2
AEABI AEABI
st andard st andard
funct ions funct ions
In this model of inter-working, the standard headers used to build a relocatable object are those associated with the
toolchain building it, not those associated with the library with which the object will, ultimately, be linked.
9
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
4 Introduction
A number of principles of inter-operation are implicit in, or compatible with, clibabi32-fig1, above. This section
describes these principles precisely, as they apply to a C library, and gives a rationale for each one. The
corresponding section of [RTABI32] 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 [AAPCS32]. 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.
10
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
Structure layout
The C standard defines only the fields that must be present in the structures it defines (lconv, tm, div_t, ldiv_t). It does
not define the order of fields, and it gives latitude to implementers to add fields.
In practice, most implementations use only the defined fields in the order listed in the C standard. In conjunction with
the POD structure layout rules given in the AAPCS this effectively standardizes the ABI to functions that manipulate
these structures.
Note
fpos_t, mbstate_t, and FILE, which have no standard-defined fields, do not have this property.
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 The C library, below, these functions are considered case by case under the library sub-sections that declare them.
4.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. errno.h, 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).
The ctype functions are discussed further in ctype.h, below.
11
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
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 toolchain.
Accepting this constraint gives considerable scope for private arrangements (not governed by this ABI) between these
toolchain components, restricted only by the requirement to provide a well defined binary interface (ABI) to the
functions described in Most C library functions have a standard ABI, above.
Aside
That does not preclude compiler-specific directives that are properly guarded in a standard conforming way.
For example: #ifdef __CC_ARM... #pragma..., and so on. However, such directives must not change the ABI
conformance of the generated binary.
12
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
Registered Vendors
Name Vendor
aeabi Reserved to the ABI for the Arm Architecture (EABI pseudo-vendor)
AnonXyz anonXyz Reserved to private experiments by the Xyz vendor. Guaranteed not to clash with any
registered vendor name.
TI TI Inc.
To register a vendor prefix with Arm, please E-mail your request to arm.eabi at arm.com.
13
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
5 The C library
5.1 C Library overview
The C Library ABI for the Arm architecture is associated with the headers listed in C library headers 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’.
C library headers
float.h C Defined by Arm’s choice of 32 and 64-bit IEEE 2’s complement format.
math.h C See math.h. All fixed apart from HUGE_VAL and related C99 definitions.
setjmp.h C jmp_buf must be defined, setjmp and longjmp must not be inlined.
signal.h C See signal.h. Definitions of SIG_DFL, SIG_IGN, SIG_ERR, & signal #s are controversial.
stdio.h C See stdio.h. Inlined macros and properties of the environment cause difficulties.
string.h C The interface is fixed by the AAPCS data type size rules.
14
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
5.2 The C library standardization model
An application is built using a single toolchain. The executable may include statically linkable binary code from a 3rd
party, built using a different toolchain. It may later be dynamically linked into an execution environment based on, or
built by, yet another toolchain.
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.
• 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.
• Most C library typedefs name primitive types fully defined by the AAPCS.
15
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
• 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.
• Everyone agrees all the values. Examples include NULL, SEEK_*, EXIT_*. These remain constants.
16
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
• 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.
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.
Consider , ERANGE, and EILSEQ from errno.h. This is a grey list category because there is consensus that = 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 Purpose
and principles. 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 toolchains and execution environments, and only a small tax on portable binaries.
17
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
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
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).
18
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
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 ctype.h, 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.
19
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
A compiler generates references to 3 kinds of library entity.
• 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 [RTABI32]).
• 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 toolchains to use the same header files
(defined by the platform). Such objects are not portable, but exportable only to a single environment.
20
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
6 The C library section by section
6.1 Introduction and conventions
For each section of the C library we describe what must be specified that is not precisely specified by the ANSI C
standard in conjunction with the data type size and alignment rules given in the [AAPCS32].
Aspects not listed explicitly are either fully specified as a consequence of the AAPCS data type size and alignment
rules or (like NULL and EOF) have obvious consensus definitions.
For all aspects mentioned explicitly in this section we tabulate either:
#ifndef _AEABI_PORTABLE
# error "AEABI not supported by header.h"
#endif
6.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 Assert.h declarations, 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,
non-printing, non-conformant version of assert() by calling abort directly, so we define no variants of __aeabi_assert().
Assert.h declarations
assert
void __aeabi_assert(const char *expr, const char *file, int line);
#define assert(__e) ((__e) ? (void)0 : __aeabi_assert(#__e, __FILE__, __LINE__))
21
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
A conforming implementation must signal its conformance as described in Detecting whether a header file honors an
AEABI portability request.
6.3 ctype.h
The ctype functions are fully defined by the C standard and the [AAPCS32]. 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
character’s 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.
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.
• 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 Detecting whether a header file honors an AEABI portability request.
Where expxxxxx is an expression that evaluates it’s 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.
22
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
#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
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.
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 Encoding of ctype table entries and macros (_AEABI_PORTABILITY_LEVEL != 0), in a
COMDAT section or in an adjunct library.
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
23
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
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.
6.4 errno.h
There are many reasons why accessing errno should call a function call. We define it as shown in errno.h definitions
errno.h definitions
EILSEQ (C89 NA 1/ C99) 47 (42, or 84) 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 and ERANGE. There
is little consensus about EILSEQ. 47 is claimed to be the IEEE 1003.1 POSIX value.
6.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 (Detecting whether a header file honors an AEABI portability
request).
6.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 [AAPCS32].
This header does not define _AEABI_PORTABLE (Detecting whether a header file honors an AEABI portability
request).
6.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 (Detecting whether a header file honors an AEABI portability
request).
24
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
6.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 2’s 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 Detecting whether a header
file honors an AEABI portability request)
MB_LEN_MAX 6
extern const int __aeabi_MB_LEN_MAX = 6;
(__aeabi_MB_LEN_MAX)
6.9 locale.h
Locale.h defines 6 macros for controlling constants (LC_* macros) 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:
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 Detecting whether a header file honors an AEABI portability
request.
struct __aeabi_lconv {
char *decimal_point;
char *thousands_sep;
char *grouping;
char *int_curr_symbol;
char *currency_symbol;
char *mon_decimal_point;
char *mon_thousands_sep;
char *mon_grouping;
char *positive_sign;
char *negative_sign;
char int_frac_digits;
char frac_digits;
char p_cs_precedes;
char p_sep_by_space;
char n_cs_precedes;
25
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
char n_sep_by_space;
char p_sign_posn;
char n_sign_posn;
/* The following fields are added by C99 */
char int_p_cs_precedes;
char int_n_cs_precedes;
char int_p_sep_by_space;
char int_n_sep_by_space;
char int_p_sign_posn;
char int_n_sign_posn;
};
__aeabi_lconv As above.
LC_* macros
6.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, 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 math.h definitions 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 Detecting whether a header file honors an AEABI
portability request.
math.h definitions
26
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
Name Required value Alternative portable definition Comment
6.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 8-byte
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.
If the Branch Target Identification mechanism is enabled, longjmp may transfer control using a BTI-setting instruction
that requires a BTI-clearing instruction at the destination.
setjmp.h definitions
Recommended definition
(_AEABI_PORTABILITY_LEVEL = Required portable definition
Name 0) (_AEABI_PORTABILITY_LEVEL != 0)
__aeabi_JMP_BUF_SIZE A value not less than 20. extern const int __aeabi_JMP_BUF_SIZE = ...
27
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
6.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.
Uni-processors 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).
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 signal.h standard handler definitions, or whether references to those values will be relocated
to distinct, target-dependent constants.
Signal.h defines six SIGXXX macros. We recommend the common Linux/Unix values listed in Standard signal names
and values. 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 Detecting whether a header file honors an AEABI portability request.
sig_atomic_t
typedef int sig_atomic_t;
SIG_DFL
extern void __aeabi_SIG_DFL(int);
#define SIG_DFL (__aeabi_SIG_DFL)
SIG_IGN
extern void __aeabi_SIG_IGN(int);
#define SIG_IGN (__aeabi_SIG_IGN)
SIG_ERR
extern void __aeabi_SIG_ERR(int);
#define SIG_ERR (__aeabi_SIG_ERR)
sigabrt 6
extern const int __aeabi_SIGABRT = ...
(__aeabi_SIGABRT)
SIGFPE 8
extern const int __aeabi_SIGFPE = ...
(__aeabi_SIGFPE)
28
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
Name Recommended value Required portable definition
SIGILL 4
extern const int __aeabi_SIGILL = ...
(__aeabi_SIGILL)
SIGINT 2
extern const int __aeabi_SIGINT = ...
(__aeabi_SIGINT)
SIGSEGV 11
extern const int __aeabi_SIGSEGV = ...
(__aeabi_SIGSEGV)
SIGTERM 15
extern const int __aeabi_SIGTERM = ...
(__aeabi_SIGTERM)
6.13 stdarg.h
Stdarg.h declares the type va_list defined by the [AAPCS32] and three macros, va_start, va_arg, and va_end. Only
va_list appears in binary interfaces.
This header does not define _AEABI_PORTABLE (Detecting whether a header file honors an AEABI portability
request).
6.14 stdbool.h
Stdbool.h defines the type bool and the values true and false.
This header does not define _AEABI_PORTABLE (Detecting whether a header file honors an AEABI portability
request).
6.15 stddef.h
The size and alignment of each typedef declared in stddef.h is specified by the [AAPCS32].
This header does not define _AEABI_PORTABLE (Detecting whether a header file honors an AEABI portability
request).
6.16 stdint.h
The types declared in this C99 header are defined by the Arm architecture and [AAPCS32].
This header does not define _AEABI_PORTABLE (Detecting whether a header file honors an AEABI portability
request).
6.17 stdio.h
29
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
• 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 Under-specified exported data.
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 Arm’s 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:
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 Detecting whether a header file honors an AEABI portability request.
30
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
Name Required definition Comment
SEEK_CUR 1
SEEK_END 2
stdin
extern FILE * __aeabi_stdin;
stdout extern FILE *__aeabi_stdout;
extern FILE *__aeabi_stderr;
stderr
_IOFBF 0
extern const int __aeabi_IOFBF = 0;
(__aeabi_IOFBF)
_IOLBF 1 extern const int __aeabi_IOLBF = 1;
(__aeabi_IOLBF)
extern const int __aeabi_IONBF = 2;
_IONBF 2 (__aeabi_IONBF)
BUFSIZ ≥ 256
extern const int __aeabi_BUFSIZ = 256;
(__aeabi_BUFSIZ)
FOPEN_MAX ≥8
extern const int __aeabi_FOPEN_MAX = 8;
(__aeabi_FOPEN_MAX)
TMP_MAX ≥ 256
extern const int __aeabi_TMP_MAX = 256;
(__aeabi_TMP_MAX)
FILENAME_MAX ≥ 256
extern const int __aeabi_FILENAME_MAX = 256;
(__aeabi_FILENAME_MAX)
extern const int __aeabi_L_tmpnam = 256;
L_tmpnam
(__aeabi_L_tmpnam)
31
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
Note
• 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.
6.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 locale-specific
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.
stdlib.h definitions
EXIT_FAILURE 1
32
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
Comment / Required portable
Name Required definition definition
6.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 (Detecting whether a header file honors an AEABI portability
request).
6.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 Detecting whether a header file honors an AEABI portability request.
time.h definitions
struct tm {...} 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 Structures used in the C library interface,
above).
CLOCKS_PER_SEC
extern const int __aeabi_CLOCKS_PER_SEC;
(__aeabi_CLOCKS_PER_SEC)
6.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 WEOF to be anything 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 Detecting whether a header file honors an AEABI
portability request.
wchar.h definitions
33
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
Name Required definition Comment
WEOF ((wint_t)-1)
6.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 Detecting whether a header file honors
an AEABI portability request.
wctype.h definitions
34
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
7 Summary of requirements on C
Libraries
Summary of conformance requirements when _AEABI_PORTABILITY_LEVEL != 0
ctype..h Yes Must define isxxxx(c) to be ((isxxxx)(c)) etc [no inline implementation] or implement
the inline versions as described in ctype.h when _AEABI_PORTABILITY_LEVEL != 0
and isxxxxx inline.
errno.h Yes errno is (*__aeabi_errno()); , ERANGE, etc are link-time constants (errno.h
definitions)
float.h No
inttypes.h No
iso646.h No
locale.h Yes Must hide struct lconv and localeconv and declare struct __aeabi_lconv and
__aeabi_localeconv (__aeabi_lconv, locale.h required portable definitions). LC_* are
link-time constants (LC_* macros).
math.h Yes Must define HUGE_VAL and similar using non-C89 means (e.g. C99 hex float
notation) or provide suitably initialized const library members (math.h definitions).
setjmp.h Yes Must declare jmp_buf[] to preclude creating such objects. __aeabi_JMP_BUF_SIZE
is a link-time constant (setjmp.h definitions).
signal.h Yes SIG_* are defined by the library (signal.h standard handler definitions); SIG* are
link-time const (Standard signal names and values).
stdarg.h No
stdbool.h No
stddef.h No
stdint.h No
stdio.h Yes Get/put macros must expand to function-calls; stdin, stdout, and stderr must
expand to pointers, not addresses of FILE objects; FILE must be opaque. Some
consensus constants must be defined as in Easy stdio.h definitions table; other
controlling values become link-time constants as defined in
Difficult stdio.h definitions table
stdlib.h Yes MB_CUR_MAX must expand to the function call __aeabi_MB_CUR_MAX(); div_t,
ldiv_t, EXIT_* must be declared as described in stdlib.h definitions.
string.h No
35
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
Header Affected Summary of conformance requirements
time.h Yes time_t ,clock_t, and struct tm must be as specified in time.h definitions.
CLOCKS_PER_SEC must be a link-time constant.
wchar.h Yes wint_t, WEOF, and mbstate_t must be declared as specified in wchar.h definitions.
wctype.h Yes wctype_t and wctrans_t must be opaque handles as specified in wctype.h definitions.
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 (Detecting whether a header file honors an AEABI
portability request).
ERANGE __aeabi_ERANGE
EILSEQ __aeabi_EILSEQ
LC_CTYPE __aeabi_LC_CTYPE
LC_MONETARY __aeabi_LC_MONETARY
LC_NUMERIC __aeabi_LC_NUMERIC
LC_TIME __aeabi_LC_TIME
LC_ALL __aeabi_LC_ALL
SIGFPE __aeabi_SIGFPE
SIGILL __aeabi_SIGILL
SIGINT __aeabi_SIGINT
SIGSEGV __aeabi_SIGSEGV
SIGTERM __aeabi_SIGTERM
36
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.
Header ANSI C macro AEABI name (extern const int __attribute__(STV_HIDDEN) …)
_IOLBF __aeabi_IOLBF
_IONBF __aeabi_IONBF
BUFSIZ __aeabi_BUFSIZ
FOPEN_MAX __aeabi_FOPEN_MAX
TMP_MAX __aeabi_TMP_MAX
FILENAME_MAX __aeabi_FILENAME_MAX
L_tmpnam __aeabi_L_tmpnam
If possible, link-time constants should be defined with visibility STV_HIDDEN [AAELF32], and linked statically with
client code. Dynamic linking is possible, but will almost always be significantly less efficient.
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 [AAELF32], and linked statically
with client code. Dynamic linking is possible, but will almost always be significantly less efficient.
37
Copyright © 2003, 2005-2007, 2009, 2012, 2015, 2018, 2020-2023, Arm Limited and its affiliates. All rights reserved.