WebAssembly 二进制编码介绍(九)

WebAssembly 是基于栈式虚拟机的虚拟二进制指令集(V-ISA),它被设计为高级编程语言的可移植编译目标。长安链使用的是wasm的二进制模块,我们这里着重分析WebAssembly的二进制模块。WebAssembly的各组件含义及关联关系需要一段时间的学习来掌握,需要大家自己不断的研究与琢磨。

WebAssembly的官方介绍: https://www.wasm.com.cn/docs/binary-encoding/

wasm的二进制模块包含11大组件:
二进制模块组件.png

官方文档中提供解析wasm二进制的方式:

  1. magic & version
    magic - uint32 - 0x6d736100
    version - uint32 - 0x1
  2. 根据不同的sec type 分别解析
    section信息.png
  3. 各section有详细字段说明
    section字段描述.png
  4. 在官方文档描述中,字段类型uint32、int32比较好理解4字节。但varuintN、varintN并未见过,这是LEB128编码格式,具体解码方式可参考下述代码
func DecodeUint32(r io.Reader) (ret uint32, num uint64, err error) {
	const (
		uint32Mask  uint32 = 1 << 7
		uint32Mask2        = ^uint32Mask
	)

	for shift := 0; shift < 35; shift += 7 {
		b, err := readByteAsUint32(r)
		if err != nil {
			return 0, 0, fmt.Errorf("readByte failed: %w", err)
		}
		num++
		ret |= (b & uint32Mask2) << shift
		if b&uint32Mask == 0 {
			break
		}
	}
	return
}
  1. 我们以长安链官方合约(镜像chainmaker-go-contract:1.1.1中的合约为例)进行解析。
5.1)执行hexdump main.wasm > main.dump命令以二进制形式查看。使用sublime等编辑工具打开。

hex.png

5.2)magic & version

a) 开始00 61 73 6d四个字节表示magic,二进制使用的是小端方式编码(大小端的含义还需要自行百度学习),实际为:0x6d736100
b) 随后01 00 00 00四个字节表示version,0x01

5.3)Type Section

该组件定义了函数的签名声明信息,定义函数的入参、返回值个数及类型。解析如下:

a) 随后一个字节01表示下面的section为Type Section
b) 随后varuint32类型73一个字节,表示该section的长度,通常在处理的时候会忽略该字段,除非session的id 为0。
c)随后12表示后面有18个type要描述(12是16进制)。
d) 随后60作为每个type的分割符,随后01表示一个形参,随后7f表示该形参的类型为i32。
e)随后00表示函数返回值为0个。
f)重复d,e流程,直到遍历18个type

5.4)Function Section

该组件包含指向Type Section的Index,Function Section是数组结构,数组下标与Code Section组件一一对应,Index表示执行Type Section的函数签名。

5.5)Code Section

该组件包含函数具体的实现逻辑以及本地变量信息,Code Section是一个数组,大小与Function Section相对应。

5.6)Export Section

该组件描述的是外部可访问的内存、变量、方法等。以方法组件为例,每个Export Section元素会关联一个Index,该Index指向Code Section。当外部调用某method,可以先在export区找到匹配的method,在通过export的index,找到要执行的字节码,然后装载执行。

5.7)Data Section

该组件描述对线性的memory进行数据初始化,组件记录数据信息以及要初始化的位置信息。

5.8)Memory Section

该组件描述程序内存块数量以及最大、最小值等。

wasm二进制执行流程可以参照:https://github.com/mathetake/gasm.git,学习字节码的解析流程。长安链基于该开源代码进行bug修复,描述在 chainmaker-go/module/vm/gasm/README.md

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明神特烦恼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值