问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

HarmonyOS Next 方舟字节码文件格式详解

创作时间:
作者:
@小白创作中心

HarmonyOS Next 方舟字节码文件格式详解

引用
CSDN
1.
https://m.blog.csdn.net/sjw890821sjw/article/details/145496806

在HarmonyOS Next开发中,ArkTS代码最终会被编译成方舟字节码。本文将深入解析方舟字节码的文件格式,帮助开发者更好地理解这一底层技术。

在开发中,可读的编程语言要编译成二进制的字节码格式才能被机器识别。在HarmonyOS Next开发中,arkts会编译成方舟字节码。方舟字节码长什么样呢?我们以一个demo编译出的abc文件:

二进制就是长这样,怎么去理解呢?就需要理解方舟字节码的文件格式。

字节码文件布局

上面图中看到有个可以认识的几个字母PANDA,什么意思呢?先了解下字节码文件布局。

字节码文件起始于Header结构。文件中的所有结构均可以从Header出发,直接或间接地访问到。字节码文件中结构的引用方式包括偏移量和索引。偏移量是一个32位长度的值,表示当前结构的起始位置在字节码文件中相对于文件头的距离,从0开始计算。索引是一个16位长度的值,表示当前结构在索引区域中的位置。

Header

先来看看Header结构:

名称
格式
说明
magic
uint8_t[8]
文件头魔数,值必须是’P’ ‘A’ ‘N’ ‘D’ ‘A’ ‘\0’ ‘\0’ ‘\0’。
checksum
uint32_t
字节码文件除文件头魔数和本校验字段之外的内容的adler32校验和。
version
uint8_t[4]
字节码文件的版本号 (Version) 。
file_size
uint32_t
字节码文件的大小,以字节为单位。
foreign_off
uint32_t
一个偏移量,指向外部区域。外部区域中仅包含类型为ForeignClass或ForeignMethod的元素。foreign_off指向该区域的第一个元素。
foreign_size
uint32_t
外部区域的大小,以字节为单位。
num_classes
uint32_t
ClassIndex结构中元素的数量,即文件中定义的Class的数量。
class_idx_off
uint32_t
一个偏移量,指向ClassIndex。
num_lnps
uint32_t
LineNumberProgramIndex结构中元素的数量,即文件中定义的Line number program的数量。
lnp_idx_off
uint32_t
一个偏移量,指向LineNumberProgramIndex。
reserved
uint32_t
方舟字节码文件内部使用的保留字段。
reserved
uint32_t
方舟字节码文件内部使用的保留字段。
num_index_regions
uint32_t
IndexSection结构中元素的数量,即文件中IndexHeader的数量。
index_section_off
uint32_t
一个偏移量,指向IndexSection。
  • magic:最开始的0x50、0x41、0x4e、0x44、0x41对应的就是PANDA的ASCII码,接下来是三个0
  • checksum:四个字节的校验位0x5d、0xe8、0xde、0xdf
  • version:自个字节的版本号0x0C、0x00、0x06、0x00

Version

字节码版本号由4个部分组成,格式为:主版本号.次版本号.特性版本号.编译版本号。

名称
格式
说明
主版本号
uint8_t
标识整体架构调整引入的字节码文件格式变更。
次版本号
uint8_t
标识局部架构调整或者重大特性调整引入的字节码文件格式变更。
特性版本号
uint8_t
标识中小特性引入的字节码文件格式变更。
编译版本号
uint8_t
标识缺陷修复引入的字节码文件格式变更。

ForeignClass

描述字节码文件中的外部类。外部类在其他文件中声明,并在当前字节码文件中被引用。

名称
格式
说明
name
String
外部类的名称,命名遵循TypeDescriptor语法。

ForeignMethod

描述字节码文件中的外部方法。外部方法在其他文件中声明,并在当前字节码文件中被引用。

名称
格式
说明
class_idx
uint16_t
一个指向该方法所从属的类的索引,指向一个在ClassRegionIndex中的位置,该位置的值是一个指向Class或ForeignClass的偏移量。
reserved
uint16_t
方舟字节码文件内部使用的保留字段。
name_off
uint32_t
一个偏移量,指向字符串,表示方法名称。
index_data
uleb128
方法的MethodIndexData数据。

通过ForeignMethod的偏移量,可以找到适当的IndexHeader以解析class_idx。

此外还有Class、Class、ClassAccessFlag、ClassTag、Field、FieldTag、Method、MethodIndexData、MethodTag、Code、TryBlock、CatchBlock、Annotation、AnnotationElementTag、AnnotationElement、Value formats、LineNumberProgramIndex、DebugInfo、IndexSection、IndexHeader、ClassRegionIndex、Type、MethodStringLiteralRegionIndex、LiteralArray、Literal,这里不一一介绍。

接下来介绍下字节码文件数据类型。

字节码文件数据类型

整型

名称
说明
uint8_t
8-bit无符号整数。
uint16_t
16-bit无符号整数,采用小端字节序。
uint32_t
32-bit无符号整数,采用小端字节序。
uleb128
leb128编码的无符号整数。
sleb128
leb128编码的有符号整数。

字符串

名称
格式
说明
utf16_length
uleb128
值为len << 1
data
uint8_t[]
以’\0’结尾的MUTF-8编码字符序列。

TaggedValue

名称
格式
说明
tag
uint8_t
表示数据种类的标记。
data
uint8_t[]
根据不同的标记,data是不同类型的数据或者为空。

字节码文件中所有的多字节值均采用小端字节序。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号