beam文件是erlang編譯器生成的文件格式,能夠直接加載到erlang vm中運行的文件格式。html
beam文件的文件佈局以下:git
文件由一個文件頭加各類塊構成,塊的結構由塊頭加自定義結構組成。在beam文件中atom塊,code塊,字符串塊,導入表,導出表,是必須出現的塊。其它可選(意思是你沒用到beam文件就不會出現這些塊)。函數
接下來逐一介紹這些塊:工具
4字節 | 4字節 | 4字節 |
"FOR1" | Size | "BEAM" |
"FOR1": 符合EA IFF 85 文件格式
Size:文件剩餘大小,也就說文件大小=Size + 8
"BEAM":beam文件佈局
4字節 | 4字節 | 4字節 | 1字節 | N1字節 | 1字節 | N2字節 | ... |
"Atom" | Size | Count | N1 | 原子 | N2 | 原子 | ... |
Atom:原子塊標識
Size:原子表大小
Count:原子個數
N1:第一個原子長度
原子:第一個原子,ascii碼
N2:第二個原子長度
原子:第二個原子ui
而後一直到Count個原子. (ps:第一個原子必定是模塊名)atom
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:代碼spa
(ps. 當一個erlang vm發現version跟本身不一樣或者beam文件的opcodemax大於本身時,不會加載這個beam文件)debug
4字節 | 4字節 | 4字節 |
"StrT" | Size | string |
"StrT":字符串塊標識
size:剩餘字符串塊的大小
string:具體字符串調試
(ps. 如有人能告訴我什麼樣的數據會放在字符串表,不勝感激)
4字節 | 4字節 | 4字節 | 4字節 | 4字節 | 4字節 | 4字節... |
"ImpT" | Size | n | M | F | A | M … |
"ImpT":導入表標識
size:剩餘導入表大小
n:導入表中有n個函數記錄
MFA:一條記錄由一個MFA標識,因爲原子已經在原子塊中定義,因此這裏
只須要保存是第幾個原子。
4字節 | 4字節 | 4字節 | 4字節 | 4字節 | 4字節 | 4字... |
"ExpT" | Size | n | F | A | L | F... |
"ExpT":導出表標識
size:剩餘導出表大小
n:導出表記錄個數
F:函數原子id
A:參數個數
L:函數代碼位置
4字節 | 4字節 | 4字節 | 4字節 | 4字節 | 4字節 | 4字... |
"LocT" | Size | n | F | A | L | F... |
"LocT":本地函數標識
size:剩餘表大小
n:表中記錄個數
F:函數名原子id
A:參數個數
L:代碼位置
(ps. 跟導出表佈局同樣)
4字節 | 4字節 | 4字節 |
"Attr" | Size | data |
"Attr":表標識
size:剩餘表大小
data:數據(erlang擴展格式方式存放)
4字節 | 4字節 | 4字節 |
"Cinf" | Size | data |
"CInf":編譯信息塊標識
size:剩餘塊大小
data:編譯選項數據(erlang擴展格式存放)
4字節 | 4字節 | 4字節 |
"AbsT" | Size | data |
"AbsT":塊標識
size:剩餘塊大小
data:數據(編譯時加debug_info選項會用到這個塊,能夠從中解析出源碼)
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值,如有明白的,請告訴我)
4字節 | 4字節 | 4字節 | 4字節 |
"LitT" | Size | uncompress-size | data |
"LitT":文字塊標識
size:塊剩餘大小
uncompress-size:未壓縮時數據的大小
data:壓縮的數據
(ps. 這裏壓縮採用zlib壓縮,能夠用zlib:uncompress解壓數據,解壓後的數是長度+erlang擴展格式+長度+擴展格式+.....)
beam文件還會存在一些跟調試相關的塊,如何Line塊,Trac塊,但這些塊中具體意義還不瞭解,因此不作介紹。
如上圖所示:標識了這個例子中出現的一些塊。
如下是本身寫的beam文件格式解析工具:
程序地址: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. 雖然資料比較老,可是不少仍是沒變...)。