erlang beam 文件格式

beam文件是erlang编译器生成的文件格式,可以直接加载到erlang vm中运行的文件格式。

一. 文件格式

beam文件的文件布局如下:

1

文件由一个文件头加各种块构成,块的结构由块头加自定义结构组成。在beam文件中atom块,code块,字符串块,导入表,导出表,是必须出现的块。其它可选(意思是你没用到beam文件就不会出现这些块)。

接下来逐一介绍这些块:

1. 文件头

4字节 4字节 4字节
"FOR1" Size "BEAM"

"FOR1": 符合EA IFF 85 文件格式
Size:文件剩余大小,也就说文件大小=Size + 8
"BEAM":beam文件

2. Atom块

4字节 4字节 4字节 1字节 N1字节 1字节 N2字节 ...
"Atom" Size Count N1 原子 N2 原子 ...

Atom:原子块标识
Size:原子表大小
Count:原子个数
N1:第一个原子长度
原子:第一个原子,ascii码
N2:第二个原子长度
原子:第二个原子

然后一直到Count个原子. (ps:第一个原子一定是模块名)

3. Code块

4字节 4字节 4字节 4字节 4字节 4字节 4字节 4字节
"Code" Size sub-size version opcode-max lables fun-count code

"Code":代码块标识
size:剩余块长度
sub-size:头部扩展使用(目前用来计算代码开始位置,因为sub-size到code距离16字节,所以这里目前一定是16)
version:指令集版本
opcode-max:代码中使用最大opcode,目前是153
labels:代码label的个数(可生成.S文件查看具体信息)
fun-count:代码中函数个数
code:代码

(ps. 当一个erlang vm发现version跟自己不同或者beam文件的opcodemax大于自己时,不会加载这个beam文件)

4. 字符串块

4字节 4字节 4字节
"StrT" Size string

"StrT":字符串块标识
size:剩余字符串块的大小
string:具体字符串

(ps. 若有人能告诉我什么样的数据会放在字符串表,不胜感激)

5. 导入表

4字节 4字节 4字节 4字节 4字节 4字节 4字节...
"ImpT" Size n M F A M …

"ImpT":导入表标识
size:剩余导入表大小
n:导入表中有n个函数记录
MFA:一条记录由一个MFA标识,由于原子已经在原子块中定义,所以这里
只需要保存是第几个原子。

6. 导出表

4字节 4字节 4字节 4字节 4字节 4字节 4字...
"ExpT" Size n F A L F...

"ExpT":导出表标识
size:剩余导出表大小
n:导出表记录个数
F:函数原子id
A:参数个数
L:函数代码位置

7. 本地函数表

4字节 4字节 4字节 4字节 4字节 4字节 4字...
"LocT" Size n F A L F...

"LocT":本地函数标识
size:剩余表大小
n:表中记录个数
F:函数名原子id
A:参数个数
L:代码位置

(ps. 跟导出表布局一样)

8. Attributes 表

4字节 4字节 4字节
"Attr" Size data

"Attr":表标识
size:剩余表大小
data:数据(erlang扩展格式方式存放)

9. 编译信息块

4字节 4字节 4字节
"Cinf" Size data

"CInf":编译信息块标识
size:剩余块大小
data:编译选项数据(erlang扩展格式存放)

10. abstract_code 块

4字节 4字节 4字节
"AbsT" Size data

"AbsT":块标识
size:剩余块大小
data:数据(编译时加debug_info选项会用到这个块,可以从中解析出源码)

11. 匿名函数表

4字节 4字节 4字节 4字节 4字节 4字节 4字节 4字节 4字节 4字节..
"FunT" Size n F A L index free olduiq F...

"FunT":表标识
size:剩余表大小
n:函数个数
F:函数名原子id
A:参数个数(包含自由变量)
L:代码位置
index:表中第几个函数
free:匿名函数中自由变量的个数
olduiq:唯一标识(ps. 不知道确切含义,貌似是模块中函数的hash值,若有明白的,请告诉我)

12. 文字块

4字节 4字节 4字节 4字节
"LitT" Size uncompress-size data

"LitT":文字块标识
size:块剩余大小
uncompress-size:未压缩时数据的大小
data:压缩的数据

(ps. 这里压缩采用zlib压缩,可以用zlib:uncompress解压数据,解压后的数是长度+erlang扩展格式+长度+扩展格式+.....)

13. 其它块

beam文件还会存在一些跟调试相关的块,如何Line块,Trac块,但这些块中具体意义还不了解,所以不做介绍。

二. 实例分析

2

如上图所示:标识了这个例子中出现的一些块。

以下是自己写的beam文件格式解析工具:

4

程序地址:https://gitcafe.com/QuietBoy/erlBeam

三. 参考资料

1. beam文件格式
https://synrc.com/publications/cat/Functional%20Languages/Erlang/BEAM.pdf
http://www.erlang.se/~bjorn/beam_file_format.html

(ps. 虽然资料比较老,但是很多还是没变...)。

原文地址:https://www.cnblogs.com/quitboy/p/4256762.html