• 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. 虽然资料比较老,但是很多还是没变...)。

  • 相关阅读:
    CF Round 594
    [转载]CSP-J/S 第一轮知识点选讲
    10.17 模拟赛
    10.16 模拟赛
    10.15模拟赛
    10.14模拟赛
    10.12 模拟赛
    Peaks Gym 100365H
    手写Bitset优化
    Sums gym100753M
  • 原文地址:https://www.cnblogs.com/quitboy/p/4256762.html
Copyright © 2020-2023  润新知