HarmonyOS Next 方舟字节码文件格式介绍

发布于:2025-02-11 ⋅ 阅读:(145) ⋅ 点赞:(0)

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

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

字节码文件布局

上面图中看到有个可以认识的几个字母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 | is_ascii,其中len是字符串在UTF-16编码中的大小,is_ascii标记该字符串是否仅包含ASCII字符,可能的值是0或1。
data uint8_t[] 以’\0’结尾的MUTF-8编码字符序列。
TaggedValue
名称 格式 说明
tag uint8_t 表示数据种类的标记。
data uint8_t[] 根据不同的标记,data是不同类型的数据或者为空。

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


网站公告

今日签到

点亮在社区的每一天
去签到