from apple

In general, iOS adheres to the generic ABI specified by ARM for the ARM64 architecture. However there are some choices to be made within that framework, and some divergences from it. This document describes these issues.

Choices Made Within the Generic Procedure Call Standard

Procedure Call Standard for the ARM 64-bit Architecture delegates certain decisions to platform designers. Decisions made for iOS are described below.

  • The register x18 is reserved for the platform. Conforming software should not make use of it.

  • wchar_t is 32-bit and long is a 64-bit type.

  • Where applicable, the __fp16 type is IEEE754-2008 format.

  • The frame pointer register (x29) must always address a valid frame record, although some functions—such as leaf functions or tail calls—may elect not to create an entry in this list. As a result, stack traces will always be meaningful, even without debug information.

  • Empty struct types are ignored for parameter-passing purposes. This behavior applies to the GNU extension in C and, where permitted by the language, in C++. (This issue is not directly specified by the generic procedure call standard, but a decision was required.)

Divergences from the Generic Procedure Call Standard

iOS diverges from Procedure Call Standard for the ARM 64-bit Architecture in several ways, as described here.

Argument Passing in General

  • In the generic procedure call standard, all function arguments passed on the stack consume slots in multiples of 8 bytes. In iOS, this requirement is dropped, and values consume only the space required. For example, on entry to the function in Listing 1, s0 occupies 1 byte at sp and s1 occupies 1 byte at sp+1. Padding is still inserted on the stack to satisfy arguments’ alignment requirements.

    Listing 1  Example of space occupied by values

    void two_stack_args(char w0, char w1, char w2, char w3, char w4, char w5, char w6, char w7, char s0, char s1) {}
  • The generic procedure call standard requires that arguments with 16-byte alignment passed in integer registers begin at an even-numbered xN, skipping a previous odd-numbered xN if necessary. The iOS ABI drops this requirement. For example, in Listing 2, the parameter x1_x2 does indeed get passed in x1 and x2 instead of x2 and x3.

    Listing 2  Example of 16-bit aligned arguments passed in integer registers

    void large_type(int x0, __int128 x1_x2) {}
  • The general ABI specifies that it is the callee’s responsibility to sign or zero-extend arguments having fewer than 32 bits, and that unused bits in a register are unspecified. In iOS, however, the caller must perform such extensions, up to 32 bits.

Variadic Functions

The iOS ABI for functions that take a variable number of arguments is entirely different from the generic version.

Stages A and B of the generic procedure call standard are performed as usual—in particular, even variadic aggregates larger than 16 bytes are passed via a reference to temporary memory allocated by the caller. After that, the fixed arguments are allocated to registers and stack slots as usual in iOS.

The NSRN is then rounded up to the next multiple of 8 bytes, and each variadic argument is assigned to the appropriate number of 8-byte stack slots.

The C language requires arguments smaller than int to be promoted before a call, but beyond that, unused bytes on the stack are not specified by this ABI.

As a result of this change, the type va_list is an alias for char * rather than for the struct type specified in the generic PCS. It is also not in the std namespace when compiling C++ code.

Fundamental C Types

The iOS version of the ABI has the following differences from the generic ABI in the fundamental types provided by the C language.

  • Generally, long double is a quad-precision IEEE754 binary floating-point type. In iOS, however, it is a double-precision IEEE754 binary floating-point type. In other words, long double is identical to double in iOS.

  • In iOS, as with other Darwin platforms, both char and wchar_t are signed types.

Red Zone

The ARM64 iOS red zone consists of the 128 bytes immediately below the stack pointer sp. As with the x86-64 ABI, the operating system has committed not to modify these bytes during exceptions. User-mode programs can rely on them not to change unexpectedly, and can potentially make use of the space for local variables.

In some circumstances, this approach can save an sp-update instruction on function entry and exit.

Divergences from the Generic C++ ABI

The generic ARM64 C++ ABI is specified in C++ Application Binary Interface Standard for the ARM 64-bit architecture, which is in turn based on the Itanium C++ ABI used by many UNIX-like systems.

Some sections are ELF-specific and not applicable to the underlying object format used by iOS. There are, however, some significant differences from these specifications in iOS.

Name Mangling

When compiling C++ code, types get incorporated into the names of functions in a process referred to as “mangling.” The iOS ABI differs from the generic specification in the following small ways.

  • Because va_list is an alias for char *, it is mangled in the same way—as Pc instead of St9__va_list.

  • NEON vector types are mangled in the same way as their 32-bit ARM counterparts, rather than using the 64-bit scheme. For example, iOS uses17__simd128_int32_t instead of the generic 11__Int32x4_t.

Other Itanium Divergences

  • In the generic ABI, empty structs are treated as aggregates with a single byte member for parameter passing. In iOS, however, they are ignored unless they have a nontrivial destructor or copy-constructor. If they do have such functions, they are considered as aggregates with one byte member in the generic manner.

  • As with the ARM 32-bit C++ ABI, iOS requires the complete-object (C1) and base-object (C2) constructors to return this to their callers. Similarly, the complete object (D1) and base object (D2) destructors return this. This requirement is not made by the generic ARM64 C++ ABI.

  • In the generic C++ ABI, array cookies change their size and alignment according to the type being allocated. As with the 32-bit ARM, iOS provides a fixed layout of two size_t words, with no extra alignment requirements.

  • In iOS, object initialization guards are nominally uint64_t rather than int64_t. This affects the prototypes of the functions __cxa_guard_acquire,__cxa_guard_release and __cxa_guard_abort.

  • In the generic ARM64 ABI, function pointers whose type differ only in being extern "C" or extern "C++" are interchangeable. This is not the case in iOS.

Data Types and Data Alignment

Using the correct data types for your variables helps to maximize the performance and portability of your programs. Data alignment specifies how data is laid out in memory. A data type’s natural alignment specifies the default alignment of values of that that type.

Table 1 lists the integer data types and their sizes and natural alignment in the ARM64 environment.

Table 1  Size and alignment of integer data types

Data type

Size (in bytes)

Natural alignment (in bytes)

BOOLbool

1

1

char

1

1

short

2

2

int

4

4

long

8

8

long long

8

8

pointer

8

8

size_t

8

8

NSInteger

8

8

CFIndex

8

8

fpos_t

8

8

off_t

8

8

[转]ARM64 Function Calling Conventions的更多相关文章

  1. function calling convention

    这是2013年写的一篇旧文,放在gegahost.net上面 http://raison.gegahost.net/?p=31 February 19, 2013 function calling c ...

  2. PatentTips – Java native function calling

    BACKGROUND OF INVENTION This invention relates to a system and method for providing a native functio ...

  3. __cdecl & __stdcall calling conventions

    (一) __cdecl: c declaration C语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈.C/C++默认的调用方式,可用于函数参数不确定的情况下. ...

  4. [转] iOS ABI Function Call Guide

    source: apple ARMv6 Function Calling Conventions When functions (routines) call other functions (sub ...

  5. linux内核调试指南

    linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级调试 ***第一部分:基础知识*** 总纲:内核世界的陷阱 源码阅读的陷阱 代码调试的陷阱 原理理解的陷阱 ...

  6. Linux Kernel - Debug Guide (Linux内核调试指南 )

    http://blog.csdn.net/blizmax6/article/details/6747601 linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级 ...

  7. (C/C++) Callback Function 回调(diao)函数

    原文: http://www.codeguru.com/cpp/cpp/cpp_mfc/callbacks/article.php/c10557/Callback-Functions-Tutorial ...

  8. C&C++ Calling Convention

    tkorays(tkorays@hotmail.com) 调用约定(Calling Convention) 是计算机编程中一个比较底层的设计,它主要涉及: 函数参数通过寄存器传递还是栈? 函数参数从左 ...

  9. FFI (语言交互接口(Foreign Function Interface))

    FFI(Foreign Function Interface)是用来与其它语言交互的接口, 在有些语言里面称为语言绑定(language bindings), Java 里面一般称为 JNI(Java ...

随机推荐

  1. JSON多层数据添加与访问

    最近项目中有要用到,JSON的多层数据对象,相当是一个json格式数组里面嵌套一个json对象吧,至于我为什么要用到这个呢,引入业务场景: 两组数据   1:    user_id    user_h ...

  2. ASP.NET的CMS

    最受欢迎的ASP.NET的CMS下载 1. Umbraco 项目地址 | 下载 Umbraco是一个开放源码的CMS内容管理系统,基于asp.net建立,使用mssql进行存储数据. 使用Umbrac ...

  3. 我在Github上的flare-spark项目

    Flare-Spark 介绍 我在自己的github上建了个flare-spark项目,本身是Apache Spark项目Master分支的镜像.在Spark的基础上,添加了flare子项目. 估计大 ...

  4. ARM指令集中经常使用的存储和载入指令

    ARM微处理器支持载入/存储指令用于在寄存器和存储器之间传送数据,载入指令用于将存储器中的数据传送到寄存器,存储指令则完毕相反的操作.经常使用的载入存储指令例如以下: -  LDR     字数据载入 ...

  5. openstack shelve/unshelve/stop浅析

    声明: 本博客欢迎转发,但请保留原作者信息! 博客地址:http://blog.csdn.net/halcyonbaby 内容系本人学习.研究和总结,如有雷同,实属荣幸! stop的虚拟机仅仅是将虚拟 ...

  6. 安卓MonkeyRunner源码分析之工作原理架构图及系列集合

    花了点时间整理了下MonkeyRunner的工作原理图,请配合本人博客里面MonkeyRunner其他源码分析文章进行阅读.下面整理成相应系列列表方便大家阅读: MonkeyRunner源码分析之-谁 ...

  7. Redis查看帮助文档

    Redis查看帮助文档的方式,目前我用到的主要有两种: 1.访问官方文档: Redis文档 2.在redis-cli中通过命令查看,输入"?"或者"help"回 ...

  8. VMware7安装CentOS6.5教程

    VMware7安装CentOS6.5教程 http://www.91linux.com/html/2014/CentOS_0415/9727.html工欲善其事,必先利其器.学习linux系统,必须先 ...

  9. [译]Java 设计模式之迭代器

    (文章翻译自java-design-pattern-iterator) 迭代器模式用于迭代遍历一个集合对象.它是一个经常被用到的模式,你可能以前使用过它.不管在任何时候你看见一些方法像hasNext( ...

  10. .net的页面在大并发下出现503错误

    .net的页面在大并发下偶尔出现503错误 我们开发了一个回调页面,由一个工具负责调用,由于压力非常大,回调页面通过6台服务器负载均衡的: 最近业务系统又再次扩容,回调页面压力成倍增加,在高峰时间段偶 ...