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.rhkb.cn/news/412792.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

时序预测 | 基于VMD-SSA-LSSVM+LSTM多变量时间序列预测模型(Matlab)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 旧时回忆,独此一家。基于VMD-SSA-LSSVMLSTM多变量时间序列预测模型(Matlab) ——————组合模型预测结果—————————— 预测绝对平均误差MAE LSTM VMDSSALSSVM 组合模型 …

Java项目:基于SpringBoot+mysql在线拍卖系统(含源码+数据库+答辩PPT+毕业论文)

一、项目简介 本项目是一套基于SSM框架mysql在线拍卖系统 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,eclipse或者idea 确保可以运行! 该系统功能完善、界面美观、操作简单、功能齐全、…

基层医疗云HIS系统源码:云计算、大数据等现代信息技术研发

云HIS源码,基层云HIS系统源码,基层医疗云HIS系统 利用云计算、大数据等现代信息技术研发的基层医疗云HIS系统实现了医院信息化从局域网向互联网转型,重新定义医疗卫生信息化建设的理念、构架、功能和运维体系。实现了医院信息化由局域网向互…

分享两个方法分析python打包exe

在Python开发中,常常需要将Python脚本打包成独立的可执行文件,以便在没有Python环境的电脑上运行。你是否曾为此感到困惑,不知道该选择哪种工具来实现这一目标?其实,打包Python脚本并不难,关键在于选择合适…

C++从入门到起飞之——list模拟实现 全方位剖析!

​ ​ ​ 🌈个人主页:秋风起,再归来~🔥系列专栏:C从入门到起飞 🔖克心守己,律己则安 目录 ​ ​1、list的整体框架 2、list迭代器 >整体分析 >整体框架 >成员函数 >运…

windows安全软件之火绒杀毒的密码忘记后处理

一、问题描述 某次,想升级系统补丁,但多次尝试后都失败,排查杀毒软件影响过程中,发现火绒杀毒配置了密码保护,但因时间太久,密码已无从考证,那我们应该怎样处理这种情况呢? 二、处…

开发知识付费小程序的秘诀:从设计到上线一步到位

在移动互联网时代,知识付费小程序成为内容创作者和教育者的热门选择。它不仅降低了用户的使用门槛,还具备高效传播的优势。本文将带你一步步了解如何开发一个功能齐全的知识付费小程序,从设计规划到技术实现,最后顺利上线。 一、…

QT接收并解析GPS模块串口数据

目录 一、QT读取串口数据 二、解析数据 目标: 使用QT,读取gps模块的串口数据,并解析其中的经纬高数据,然后进行处理 一、QT读取串口数据 变量定义 QSerialPort *serial; QSerialPortInfo SerialPortInfo; QByteArray lineData…

RKNPU2从入门到实践 --- 【10】RKNPU2零拷贝API实现RKNN模型在RK3588开发板上的部署

目录 一、为什么叫零拷贝API? 二、零拷贝API执行流程(代码解读) 2.1 前奏工作 2.2 main.cc文件的编写(代码的编写) 2.2.1 第一步:rknn_init接口创建rknn_context对象、加载RKNN模型 2.2.2 第二步…

C# 传值参数

传值参数 1.值类型 值参数创建变量的副本:当传递值参数时,实际上是创建了原始变量的一个副本,然后将副本传递给方法。对值参数的操作永远不影响变量的值:由于是复制了一份新的副本,所以对副本进行操作不会影响原始变量…

python,json数据格式,pyecharts模块,pycharm中安装pyecharts

json数据格式 JSON是一种轻量级的数据交互格式 可以按照JSON指定的格式去组织和封装数据 JSON本质上是一个带有特定格式的字符串 主要功能: json就是一种在各个编程语言中流通的数据格式,负责不同编程语言中的数据传递和交互. 类似于: 国…

普元Devops-在云主机上拉取harbor的docker镜像并部署

1 前言 本文讲解如何从普元Devops配置构建,从而实现在云主机上拉取Docker镜像,然后运行Docker容器,实现云主机的Docker部署。 2 主要步骤说明 首先,我们有一个Devops服务器,还有一个云主机服务器,还有一个…

【微信小程序】如何触发按钮事件,例如调起微信客服

需求 实现一个如下图的效果, 点击客服按钮, 调起微信客服功能, 需要和button组合使用 效果图 实现思路 客服只能通过button按钮调起, 所以我们需要写一个button按钮, open-type“contact”, 然后把它隐藏起来。给客服图标加一个label, 设置for“btnId”, 这样点击图片就会触…

在ElementUI项目中集成iconfont图标库

在前端项目开发中经常会遇到使用的组件库提供的ICON图标不够用的情况。最常见的解决方案无非就是把设计图的图标切图引入到项目中。还有就是使用svg图标,封装一个渲染组件在项目里面直接引入这个组件。 本文将介绍另一种方法,即集成iconfont图标库的图标…

养老小程序源码家政服务小程序开发方案

预约上门养老小程序,是php开发预约,前端是uniapp,有开发好的小程序案例,可源码,也可以二开,也可以定制开发。 一 用户端:服务分类、服务内容详情介绍、在线下单支付,管理我的订单。…

前缀和差分【算法 13】

在算法领域中,前缀和与差分数组是两种高效处理区间问题的技术。它们能在特定问题场景下将时间复杂度从 (O(n)) 降到 (O(1)),适用于频繁的区间查询与修改操作。本文将简要介绍这两种技术及其应用。 1. 前缀和 (Prefix Sum) 前缀和是指一个数组的第 (i)…

利用TOPSIS算法进行生长素和施肥量对农作物各指标影响力的分析

文章目录 1 摘要2 问题的重述1. 背景介绍2. 问题的产生及进行数学建模的意义 3 TOPSIS算法1. TOPSIS算法介绍2. TOPSIS算法使用步骤 4 问题的分析1. 对问题一的分析及解答2. 对问题二的分析及解答3. 对问题三的分析及解答 5 模型的改进1. 验证2.模型改进…

整理了几十家高频面试题,让你避坑软件测试公司面试的套路,收藏收藏刷起来...

俗话说金九银十,就要到找工作的高峰期了 年前找我拿面试题的姐妹已经收到offer了,准备换工作的抓紧背起来哦 去面试的,一定要提前了解一下,这些面试题。可能不是特别全面,但是已经够用了。你们面试时还遇到了哪些奇葩…

Redis中的数据类型及应用场景(面试版)

五种常用数据类型介绍 Redis中存储的都是key-value对结构的数据,其中key都是字符串类型,value有5种常用的数据类型: 字符串 string 哈希 hash 列表 list 集合 set 有序集合 sorted set / zset 各种数据类型特点 解释说明: …

【C++】vector(下)--上篇

个人主页~ vector(上)~ vector 二、vector的模拟实现1、了解组成2、vector.h(1)为什么有了size_t参数的vector构造函数还要再写一个int参数的重载vector构造函数(2)为什么reserve不用memcpy(3&…