当前位置: 首页 > article >正文

LuaJit分析(三)luajit字节码文件格式

Luajit字节码文件格式的完整信息如上图所示,包括文件头Header和原型Proto,一个原型可以对应lua源码中的一个函数或源文件。
一、文件头
文件标志:占用三个字节,始终是0x1B4C4A,表示这是一个luajit文件
版本:占用一个字节,最新版2.1.0-beta3显示为2
Flags标志:占用一个字节,官方定义为:

#define BCDUMP_F_BE   0x01
#define BCDUMP_F_STRIP    0x02
#define BCDUMP_F_FFI    0x04
#define BCDUMP_F_FR2    0x08

BE表示是否大端对齐,默认0表示小端对齐
STRIP表示是否去除调试信息,0表示没去除,包含调试信息
FFI表示是否有调用外部C函数库
FR2表示是否使用开启了FR2,64位模式编译时FR2 = 1
文件名大小(STRIP=0):源文件名占用的字节大小
文件名(STRIP=0):源文件名

二、原型
1、原型头
原型大小:uleb128类型,表示整个原型占用字节大小,为0标志结束
原型flags标志:定义如下:

#define PROTO_CHILD   0x01  /* Has child prototypes. */
#define PROTO_VARARG    0x02  /* Vararg function. */
#define PROTO_FFI   0x04  /* Uses BC_KCDATA for FFI datatypes. */
#define PROTO_NOJIT   0x08  /* JIT disabled for this function. */
#define PROTO_ILOOP   0x10  /* Patched bytecode with ILOOP etc. */

第一位proto_child定义是否是一个子函数,即闭包
第二位proto_vararg 函数是否返回多个值
第三位 proto_ffi 是否使用了扩展
第四位proto_nojit标志是否禁用了jit模式
第五位 proto_iloop标志是否有iloop循环指令
参数个数:函数有几个参数
Frame大小:使用栈帧的大小
upvalue个数:使用外部函数中变量的个数
复杂常量个数:
数值常量个数:
指令个数:
调试信息大小(STRIP=0):后面调试信息占用字节的大小
起始行(STRIP=0):原型的在文件中的起始行
行数(STRIP=0):原型占用的总行数
2、原型体
指令:原型的字节码指令,每条指令占四个字节,默认对齐时,第一个字节为opcode,
个数为原型头中的指令个数
Upvalues:upvalue,uint16,个数为原型头中指定的个数
复杂常量:保存了多种类型的常量,定义如下: 

typedef struct {
uleb128 tp;
MSize constant_type = uleb128_value(tp);
if (constant_type >= BCDUMP_KGC_STR) {
int32 len = constant_type - BCDUMP_KGC_STR;
char str[len]
} else if (constant_type == BCDUMP_KGC_TAB) {
Table t;
} else if (constant_type != BCDUMP_KGC_CHILD) {
TNumber num;
if constant_type == BCDUMP_KGC_COMPLEX:
            Tnumber num;
} else {
prototype val = prototypes.pop();
}
}ComplexConstant

第一个uleb128表示这个复杂常量的类型,如下:

enum {
BCDUMP_KGC_CHILD = 0,
BCDUMP_KGC_TAB = 1,
BCDUMP_KGC_I64 = 2,
BCDUMP_KGC_U64 = 3,
BCDUMP_KGC_COMPLEX = 4,
BCDUMP_KGC_STR = 5
};

主要包括了字符串,数值,table 和 child (prototype自身)
Table定义如下:

typedef struct {
uleb128 array_items_count;
uleb128 hash_items_count;
local int32 array_items_count_ = uleb128_value(array_items_count);
local int32 hash_items_count_ = uleb128_value(hash_items_count);
while (array_items_count_-- > 0) {
ArrayItem array_item;
}
while (hash_items_count_-- > 0) {
HashItem hash_item;
}
} Table;

HashItem定义如下:

typedef struct {
ComplexConstant key;
ComplexConstant value;
} HashItem;

数值常量:保存数值类型的常量,可以表示整数和浮点数,定义如下:

typedef struct {
uleb128_33 lo;
if (lo.val[0] & 0x1)
uleb128 hi;
} NumericConstant;

调试信息(STRIP=0):包括三个部分,定义如下:

typedef struct{
if (debuginfo_size > 0) {
LineInfo lineinfo(lines_count, instructions_count);
if (upvalues_count > 0)
UpValueNames upvalue_names(upvalues_count);
VarInfos varinfos;
}
} DebugInfo

Lineinfo记录了每条指令所在的行,upvalue_names记录了upvalue的字符串信息,varinfos记录了每个变量的字符串,定义如下:

typedef struct(uchar tp) {
local uchar tp_ = tp;
if (tp >= VARNAME__MAX) {
string str;
} else {
VARNAME_TYPE vartype;
}
if (tp != VARNAME_END) {
uleb128 start_addr;
uleb128 end_addr;
}
} VarInfo;

Varinfo记录了变量的类型,以及变量作用域的起始行和结束行


http://www.kler.cn/news/290389.html

相关文章:

  • 【C++】string的模拟实现
  • 1119 Pre- and Post-order Traversals
  • Django学习(二)
  • 基因对应身体的需求 平衡饮食的重要性 第四篇
  • 8个优质视频素材库,商用无忧
  • AT+MQTT指令连接华为云实现数据上传
  • 使用linux命令导出mysql数据为CSV文件
  • 【开源风云】从若依系列脚手架汲取编程之道(三)
  • 低代码表单 FormCreate 中组件的生成规则详解
  • 机器学习和深度学习中常见损失函数,包括损失函数的数学公式、推导及其在不同场景中的应用
  • 从python应用app向微软Microsoft Teams Channel发送消息message
  • Kafka3.x 使用 KRaft 模式部署 不依赖 ZooKeeper
  • Redis数据结构与连接
  • 快速掌握GPTEngineer:用AI创建网页应用的实用教程
  • 从laborer一词掌握单词记忆的秘诀
  • 《NLP自然语言处理》—— 关键字提取之TF-IDF算法
  • 代码随想录八股训练营第三十一天| C++
  • flutter 提示框2 Dialog
  • Leetcode Hot 100刷题记录 -Day6(滑动窗口)
  • 【护网相关知识】
  • Linux【5】远程管理
  • Python数据结构类型总结
  • 力扣SQL仅数据库(175~185)
  • Linux日志-lastlog日志
  • 网络编程(学习)2024.9.3
  • 3GPP R18 Network energy savings(NES) 之cell DTX/DRX
  • 「MyBatis」图书管理系统 v1.0
  • 对同一文件夹下所有excel表进行相同操作(数据填充、删除、合并)
  • 论文阅读笔记:RepViT: Revisiting Mobile CNN From Vit Perspective
  • blender 快速LOD