ABI是系统与应用之间的协议. 一个BINARY(EXEC, LIB)必需符合ABI才能在相应的系统上运行.
比如我在PC上用不管什么样的COMPILER, 只要产生符合LINUX的ELF文件, 用相应的INSTRUCTION SET(比如INTEL, PPC, SPARC). 就可以在一个LINUX机器上运行. 调用系统或别人的LIB.
ABI定义了BINARY的文件格式, 内容, 以及装载/卸载程序的要求, 函数调用的参数传递规则, 寄存器, 堆栈的使用等.
abi(应用二进制接口)我的理解就是机器代码一层的接口。先说一下api(特指系统调用),
api基本上是和机器硬件平台无关但是和操作系统密切相关的接口,一个api调用定义了一个对内核的操作,以及操作的参数。C语言会议函数的形式调用api。
abi,是比api更贴近硬件的一层接口,它规定的是二进制代码之间的调用规则。举个例子来说吧!
一个应用程序,调用了.so库中的函数或者系统调用,如果它的编译器可以找到被调用函数或者系统
调用的话,则编译可以同过,也就是说,它是用的api是正确的。但是,这个调用离成功还很远。。。。。
首先,如果编译出来的代码和运行库函数和系统调用的代码不是一个硬件平台的,则这个应用根本就不能和被调用代码运行在一起,则调用不会成功。
即使库函数、系统调用和是运行在同一硬件平台上的调用也不一定会趁成功。因为程序最终是被编译成二进制代码的,并且是要加载到内存中运行的。那么,在调用库函数或者系统调用的时候,应用要先要以库函数或者系统调用指定的方式和位置(内存或者寄存器)设置参数,然后通过中断或者其他方式跳转到被调用代码的起始处进行执行,被调用代码从指定位置去到参数,处理完毕之后再将结果放到指定的位置,最后应用再到指定的地方取回结果,调用完毕!
我认为这个过程中,存放参数和结果的位置属于abi规定的范围,被调用程序的跳转地址或者中断号码也是abi规定的范围。如果存取参数、结果的位置没有明确的规范,或者调用、被调用双方没有遵照统一个规范,那么这个调用能够根本就不可能成功;如果系统提供的库函数路径不正确,调用也不会成功;如果中断代码使用错误,调用也不会正确。abi 就是在这个层次上对应用程序的一个规范。
关于EABI
什么是EABI?
Embedded application binary interface, 即嵌入式应用二进制接口,是描述可连接目标代码,库目标代码,可执行文件影像,如何连接,执行和调试,以及目标代码生成过程,和c, c++语言接口的规范,是编译连接工具的基础规范,也是研究它们工作原理的基础,可惜arm的EABI迄今为止没有完全订好。作为EABI的组成部分有过 程调用规范,可执行文件格式规范,c/c++ ABI规范和调试格式规范。
关于ATPCS
什么是ATPCS,什么是PCS?
ATPCS即arm-thumb procedure call standard,PCS即procedure call standard.
PCS 规定了应用程序的函数可以如何分开地写,分开地编译,最后将它们连接在一起,所以它实际上定义了一套有关过程(函数)调用者与被调用者之间的协议。PCS 规范强制实现如下约定:调用函数如何传参(即压栈方法,以何种方式存放参数),被调用函数如何获取参数,以何种方式传递函数返回值。PCS 规范的制订是一系列指标的“tradeoff”(因为很大程度上涉及系统的一些性能),如会涉及生成代码的大小,调试功能的支持,函数调用上下文处理速度 以及内存消耗。当然,通过编译器的支持可以让生成的代码有不同的特性,如gcc编译选项可以支持或不支持framepointer来支持深入调试功能或提 高程序运行性能。
PCS是体系结构密切相关的,直接涉及编译器如何使用处理器提供的应用寄存器,如编译器使用什么寄存器作为栈指针, 利用哪些寄存器作直接传参等。值得注意的是,没有谁规定说ATPCS是必须这样而不是那样的,它是应用相关的,任何一个操作系统和应用可以处于它自身的考 虑定义自己的PCS,当然,如果那样,也必须有自己的编译器,而实际上,在一个处理器设计时,都会有某种假设,所以PCS某种程度上应该是一样的。
ATPCS是基于arm指令集和thumb指令集过程调用的规范。
关于BFD
什么是BFD?
Binary format descriptor, 即二进制文件格式描述符,它是连接工具(ld)和二进制文件操作工具(bin-util)实现对于目标文件操作的标准接口,ld和bin-util通过调用实现BFD接口的库libbfd
来实现它们的目标文件操作功能。
BFD的结构
BFD 整体上简单地可分为前端和后端(就象gcc一样),这样做的目的主要出于可移植性的考虑,前端向应用层提供统一的调用接口,是目标文件格式无关的,后端实 现目标格式相关的部分,前端通过调用后端的相关函数实现真正的具体目标文件格式操作功能。所以如果要支持一种新嵌入式目标文件格式(就象 uclinux支持的简化类coff文件格式BFLT)就只要修改BFD的后端就行了。
BFD的结构
前端的结构和一些主要的功能是:段操作,符号表处理,重定位管理,库操作,及其为了方便用的函数。后端涉及具体的文件格式操作方法的支持,典型的是a.out,coff,和elf.
BFD工作过程简述
每当bin-util工具如(objdump)打开一个目标文件时,工具通过调用BFD库里相关目标文件格式的信息判定该文件的二进制格式。然后抽取库里相 关例程的信息建立对应的二进制格式操作描述符表(实际上诗歌函数指针表,有点象COM的VTABLE),利用这些指针,工具读取分析和操作该目标文件。我 们利用objcopy(操作),objdump(读取、分析),readelf(读取),就是全仰仗BFD的功能。我刚才讲了现成目标文件的工作过程,那 么目标文件的形成过程又是怎样的呢?如上所述,编译器/连接器在处理目标文件符号表等时先会调用前端函数(前端是统一和抽象的过程),然后通过后端处理具 体文件格式的操作函数将符号表等相关信息写到输出文件, 这些任务的就是通过调用内存中的BFD描述符的函数实现的。
原来的转贴:http://www.cnblogs.com/ziip/archive/2010/08/18/1802207.html
原贴:http://blog.163.com/boby_boke/blog/static/12687735420099160172972/