本文档描述了.dex
文件的布局和内容,这些文件用于保存一组类定义及其相关的附属数据。
类型指南
姓名 | 描述 |
---|---|
字节 | 8 位有符号整数 |
优字节 | 8 位无符号整数 |
短的 | 16 位有符号整数,小端序 |
超短 | 16 位无符号整数,小端 |
整数 | 32 位有符号整数,小端序 |
单位 | 32 位无符号整数,小端序 |
长 | 64 位有符号整数,小端 |
乌龙 | 64 位无符号整数,小端 |
sleb128 | 有符号 LEB128,可变长度(见下文) |
uleb128 | 无符号 LEB128,可变长度(见下文) |
uleb128p1 | 无符号 LEB128 加1 ,可变长度(见下文) |
LEB128
LEB128(“ L ittle- E ndian Base 128 ”)是用于任意有符号或无符号整数的可变长度编码。该格式是从DWARF3规范中借用的。在.dex
文件中,LEB128 仅用于编码 32 位数量。
每个 LEB128 编码值由一到五个字节组成,它们共同代表一个 32 位值。每个字节都有其最高有效位设置,除了序列中的最后一个字节,它的最高有效位被清除。每个字节的其余七位是有效载荷,第一个字节中数量的最低七位,第二个字节中接下来的七位,依此类推。在有符号 LEB128 ( sleb128
) 的情况下,序列中最后一个字节的最高有效载荷位被符号扩展以产生最终值。在无符号情况下( uleb128
),任何未明确表示的位都被解释为0
。
两字节 LEB128 值的按位图 | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
第一个字节 | 第二个字节 | ||||||||||||||
1 | 位6 | 位5 | 位4 | 位3 | 位2 | 位1 | 位0 | 0 | 位13 | 第 12位 | 位11 | 位10 | 位9 | 位8 | 位7 |
变体uleb128p1
用于表示有符号值,其中表示是值加一编码为uleb128
。这使得-1
的编码(或者被认为是无符号值0xffffffff
) - 但没有其他负数 - 单个字节,并且在表示的数字必须是非负数或-1
(或0xffffffff
),并且不允许其他负值(或者不太可能需要大的无符号值)。
以下是一些格式示例:
编码序列 | 作为sleb128 | 作为uleb128 | 作为uleb128p1 |
---|---|---|---|
00 | 0 | 0 | -1 |
01 | 1 | 1 | 0 |
7f | -1 | 127 | 126 |
80 7f | -128 | 16256 | 16255 |
文件布局
姓名 | 格式 | 描述 |
---|---|---|
标题 | header_item | 标题 |
string_ids | string_id_item[] | 字符串标识符列表。这些是此文件使用的所有字符串的标识符,用于内部命名(例如,类型描述符)或作为代码引用的常量对象。此列表必须按字符串内容排序,使用 UTF-16 代码点值(不是以区域设置敏感的方式),并且不得包含任何重复条目。 |
type_ids | type_id_item[] | 类型标识符列表。这些是此文件引用的所有类型(类、数组或原始类型)的标识符,无论是否在文件中定义。此列表必须按string_id 索引排序,并且不得包含任何重复条目。 |
proto_ids | proto_id_item[] | 方法原型标识符列表。这些是此文件引用的所有原型的标识符。此列表必须按返回类型(按type_id 索引)主要顺序排序,然后按参数列表(字典顺序,单个参数按type_id 索引排序)。该列表不得包含任何重复条目。 |
field_ids | field_id_item[] | 字段标识符列表。这些是此文件引用的所有字段的标识符,无论是否在文件中定义。此列表必须排序,其中定义类型(按type_id 索引)是主要顺序,字段名称(按string_id 索引)是中间顺序,类型(按type_id 索引)是次要顺序。该列表不得包含任何重复条目。 |
方法ID | method_id_item[] | 方法标识符列表。这些是此文件引用的所有方法的标识符,无论是否在文件中定义。此列表必须排序,其中定义类型(按type_id 索引)是主要顺序,方法名称(按string_id 索引)是中间顺序,方法原型(按proto_id 索引)是次要顺序。该列表不得包含任何重复条目。 |
类定义 | class_def_item[] | 类定义列表。必须对类进行排序,以使给定类的超类和实现的接口在列表中出现在引用类之前。此外,同名类的定义在列表中出现多次是无效的。 |
call_site_ids | call_site_id_item[] | 呼叫站点标识符列表。这些是此文件引用的所有呼叫站点的标识符,无论是否在文件中定义。此列表必须按call_site_off 的升序排序。 |
方法句柄 | 方法处理项[] | 方法句柄列表。此文件引用的所有方法句柄的列表,无论是否在文件中定义。此列表未排序并且可能包含在逻辑上对应于不同方法句柄实例的重复项。 |
数据 | 优字节[] | 数据区,包含上面列出的表格的所有支持数据。不同的项目有不同的对齐要求,如果需要,可以在每个项目之前插入填充字节以实现正确的对齐。 |
链接数据 | 优字节[] | 静态链接文件中使用的数据。本节中的数据格式未在本文档中指定。这部分在未链接的文件中是空的,运行时实现可以根据需要使用它。 |
位域、字符串和常量定义
DEX_FILE_MAGIC
嵌入 header_item
常量数组/字符串DEX_FILE_MAGIC
是必须出现在.dex
文件开头的字节列表,以便被识别。该值有意包含换行符( "\n"
或0x0a
)和空字节( "\0"
或0x00
),以帮助检测某些形式的损坏。该值还将格式版本号编码为三个十进制数字,预计随着格式的发展随着时间的推移单调增加。
ubyte[8] DEX_FILE_MAGIC = { 0x64 0x65 0x78 0x0a 0x30 0x33 0x39 0x00 } = "dex\n039\0"
注意: Android 9.0 版本中添加了对039
版格式的支持,该版本引入了两个新字节码const-method-handle
和const-method-type
。 (这些都在字节码集摘要表中进行了描述。)在 Android 10 中,版本039
扩展了 DEX 文件格式,以包含仅适用于引导类路径上的 DEX 文件的隐藏 API 信息。
注意: Android 8.0 版本中添加了对038
版格式的支持。 038
版添加了新的字节码( invoke-polymorphic
和invoke-custom
)和方法句柄的数据。
注意: Android 7.0 版本中添加了对037
版格式的支持。在037
版之前,大多数 Android 版本都使用035
版格式。 035
和037
版本的唯一区别是添加了默认方法和invoke
的调整。
注意:至少有几个早期版本的格式已在广泛可用的公共软件版本中使用。例如, 009
版用于 Android 平台的 M3 版本(2007 年 11 月至 2007 年 12 月),而013
版用于 Android 平台的 M5 版本(2008 年 2 月至 3 月)。在几个方面,这些早期版本的格式与本文档中描述的版本有很大不同。
ENDIAN_CONSTANT 和 REVERSE_ENDIAN_CONSTANT
嵌入 header_item
常量ENDIAN_CONSTANT
用于指示找到它的文件的字节序。尽管标准的.dex
格式是小端的,但实现可以选择执行字节交换。如果实现遇到endian_tag
是REVERSE_ENDIAN_CONSTANT
而不是ENDIAN_CONSTANT
的标头,它将知道该文件已从预期形式进行字节交换。
uint ENDIAN_CONSTANT = 0x12345678; uint REVERSE_ENDIAN_CONSTANT = 0x78563412;
NO_INDEX
嵌入在 class_def_item 和 debug_info_item
常量NO_INDEX
用于指示索引值不存在。
注意:此值未定义为0
,因为这实际上通常是一个有效索引。
NO_INDEX
的选定值可表示为uleb128p1
编码中的单个字节。
uint NO_INDEX = 0xffffffff; // == -1 if treated as a signed int
access_flags 定义
嵌入在 class_def_item、encoded_field、encoded_method 和 InnerClass 中
这些标志的位域用于指示类和类成员的可访问性和整体属性。
姓名 | 价值 | 对于类(和InnerClass 注释) | 对于字段 | 对于方法 |
---|---|---|---|---|
ACC_PUBLIC | 0x1 | public : 随处可见 | public : 随处可见 | public : 随处可见 |
ACC_PRIVATE | 0x2 | private :仅对定义类可见 | private :仅对定义类可见 | private :仅对定义类可见 |
ACC_PROTECTED | 0x4 | protected : 对包和子类可见 | protected : 对包和子类可见 | protected : 对包和子类可见 |
ACC_STATIC | 0x8 | static : 不是用外部this 引用构造的 | static : 全局定义类 | static : 不接受this 参数 |
ACC_FINAL | 0x10 | final : 不可子类化 | final :构造后不可变 | final : 不可覆盖 |
ACC_SYNCHRONIZED | 0x20 | synchronized :在调用此方法时自动获取关联锁。注意:这仅在设置 | ||
ACC_VOLATILE | 0x40 | volatile :有助于线程安全的特殊访问规则 | ||
ACC_BRIDGE | 0x40 | bridge 方法,由编译器自动添加为类型安全的桥 | ||
ACC_TRANSIENT | 0x80 | transient :默认序列化不保存 | ||
ACC_VARARGS | 0x80 | 最后一个参数应被编译器视为“休息”参数 | ||
ACC_NATIVE | 0x100 | native : 在本机代码中实现 | ||
ACC_INTERFACE | 0x200 | interface :可多次实现的抽象类 | ||
ACC_ABSTRACT | 0x400 | abstract :不能直接实例化 | abstract :此类未实现 | |
ACC_STRICT | 0x800 | strictfp :浮点运算的严格规则 | ||
ACC_SYNTHETIC | 0x1000 | 未在源代码中直接定义 | 未在源代码中直接定义 | 未在源代码中直接定义 |
ACC_ANNOTATION | 0x2000 | 声明为注解类 | ||
ACC_ENUM | 0x4000 | 声明为枚举类型 | 声明为枚举值 | |
(没用过) | 0x8000 | |||
ACC_CONSTRUCTOR | 0x10000 | 构造方法(类或实例初始化器) | ||
ACC_DECLARED_ 同步的 | 0x20000 | 声明为synchronized 。注意:这对执行没有影响(除了反映这个标志本身)。 |
InnerClass
注释中使用,并且不能在class_def_item
中使用。
MUTF-8(修改的 UTF-8)编码
作为对遗留支持的让步, .dex
格式将其字符串数据编码为事实上的标准修改 UTF-8 格式,以下称为 MUTF-8。这种形式与标准 UTF-8 相同,除了:
- 仅使用一、二和三字节编码。
-
U+10000
…U+10ffff
范围内的代码点被编码为代理对,每个代理对都表示为一个三字节编码值。 - 代码点
U+0000
以两字节形式编码。 - 一个普通的空字节(值
0
)表示字符串的结尾,标准 C 语言解释也是如此。
上面的前两项可以概括为: MUTF-8 是 UTF-16 的编码格式,而不是 Unicode 字符更直接的编码格式。
上面的最后两项可以同时将代码点U+0000
包含在字符串中,并且仍然将其作为 C 风格的以空字符结尾的字符串进行操作。
但是, U+0000
的特殊编码意味着,与普通的 UTF-8 不同,在一对 MUTF-8 字符串上调用标准 C 函数strcmp()
的结果并不总是表明比较不相等字符串的正确签名结果.当排序(不仅仅是相等)是一个问题时,比较 MUTF-8 字符串最直接的方法是逐个字符地解码它们,然后比较解码后的值。 (然而,更聪明的实现也是可能的。)
有关字符编码的更多信息,请参阅Unicode 标准。 MUTF-8 实际上更接近(相对不太知名的)编码CESU-8 ,而不是 UTF-8 本身。
编码值编码
嵌入 annotation_element 和 encoded_array_item
encoded_value
值是(几乎)任意分层结构化数据的编码片段。编码意味着既紧凑又易于解析。
姓名 | 格式 | 描述 |
---|---|---|
(value_arg << 5) |值类型 | 优字节 | 字节指示紧随其后的value 的类型以及高三位中的可选澄清参数。有关各种value 定义,请参见下文。在大多数情况下, value_arg 以字节为单位对紧接后继value 的长度进行编码,如(size - 1) ,例如, 0 表示该值需要一个字节,而7 表示它需要八个字节;但是,也有一些例外情况,如下所述。 |
价值 | 优字节[] | 表示值的字节,长度可变,对于不同的value_type 字节有不同的解释,尽管总是小端。有关详细信息,请参阅下面的各种值定义。 |
值格式
类型名称 | value_type | value_arg 格式 | value 格式 | 描述 |
---|---|---|---|---|
VALUE_BYTE | 0x00 | (无;必须为0 ) | 优字节[1] | 带符号的一字节整数值 |
VALUE_SHORT | 0x02 | 大小 - 1 (0…1) | ubyte[大小] | 带符号的两字节整数值,符号扩展 |
VALUE_CHAR | 0x03 | 大小 - 1 (0…1) | ubyte[大小] | 无符号的两字节整数值,零扩展 |
VALUE_INT | 0x04 | 大小 - 1 (0…3) | ubyte[大小] | 带符号的四字节整数值,符号扩展 |
VALUE_LONG | 0x06 | 大小 - 1 (0…7) | ubyte[大小] | 有符号八字节整数值,符号扩展 |
VALUE_FLOAT | 0x10 | 大小 - 1 (0…3) | ubyte[大小] | 四字节位模式,向右扩展零,并解释为 IEEE754 32 位浮点值 |
VALUE_DOUBLE | 0x11 | 大小 - 1 (0…7) | ubyte[大小] | 八字节位模式,向右扩展零,并解释为 IEEE754 64 位浮点值 |
VALUE_METHOD_TYPE | 0x15 | 大小 - 1 (0…3) | ubyte[大小] | 无符号(零扩展)四字节整数值,解释为proto_ids 部分的索引并表示方法类型值 |
VALUE_METHOD_HANDLE | 0x16 | 大小 - 1 (0…3) | ubyte[大小] | 无符号(零扩展)四字节整数值,解释为method_handles 部分的索引并表示方法句柄值 |
VALUE_STRING | 0x17 | 大小 - 1 (0…3) | ubyte[大小] | 无符号(零扩展)四字节整数值,解释为string_ids 部分的索引并表示字符串值 |
值类型 | 0x18 | 大小 - 1 (0…3) | ubyte[大小] | 无符号(零扩展)四字节整数值,解释为type_ids 部分的索引并表示反射类型/类值 |
VALUE_FIELD | 0x19 | 大小 - 1 (0…3) | ubyte[大小] | 无符号(零扩展)四字节整数值,解释为field_ids 部分的索引并表示反射字段值 |
VALUE_METHOD | 0x1a | 大小 - 1 (0…3) | ubyte[大小] | 无符号(零扩展)四字节整数值,解释为method_ids 部分的索引并表示反射方法值 |
VALUE_ENUM | 0x1b | 大小 - 1 (0…3) | ubyte[大小] | 无符号(零扩展)四字节整数值,解释为field_ids 部分的索引并表示枚举类型常量的值 |
VALUE_ARRAY | 0x1c | (无;必须为0 ) | 编码数组 | 一个值数组,格式由下面的“ encoded_array 格式”指定。 value 的大小隐含在编码中。 |
VALUE_ANNOTATION | 0x1d | (无;必须为0 ) | 编码注释 | 子注释,格式由下面的“ encoded_annotation format”指定。 value 的大小隐含在编码中。 |
VALUE_NULL | 0x1e | (无;必须为0 ) | (没有任何) | null 参考值 |
VALUE_BOOLEAN | 0x1f | 布尔值 (0…1) | (没有任何) | 一位值; 0 为false , 1 为true 。该位在value_arg 中表示。 |
编码数组格式
姓名 | 格式 | 描述 |
---|---|---|
尺寸 | uleb128 | 数组中的元素数 |
价值观 | 编码值[大小] | 本节指定格式的一系列size encoded_value 值字节序列,按顺序连接。 |
编码注释格式
姓名 | 格式 | 描述 |
---|---|---|
type_idx | uleb128 | 注释的类型。这必须是类(不是数组或原始)类型。 |
尺寸 | uleb128 | 此注解中的名称-值映射数量 |
元素 | 注释元素[大小] | 注释的元素,直接在线表示(而不是偏移量)。元素必须按string_id 索引升序排序。 |
annotation_element 格式
姓名 | 格式 | 描述 |
---|---|---|
name_idx | uleb128 | 元素名称,表示为string_ids 部分的索引。该字符串必须符合上面定义的MemberName语法。 |
价值 | 编码值 | 元素值 |
字符串语法
.dex
文件中有几种最终引用字符串的项目。以下 BNF 样式定义指示这些字符串的可接受语法。
简单名称
SimpleName是其他事物名称语法的基础。 .dex
格式在这里允许相当大的自由度(比大多数常见的源语言要多得多)。简而言之,一个简单的名称由任何低 ASCII 字母字符或数字、一些特定的低 ASCII 符号和大多数非控制、空格或特殊字符的非 ASCII 代码点组成。从版本040
开始,该格式还允许使用空格字符(Unicode Zs
类别)。请注意,代理代码点(在U+d800
... U+dfff
范围内)本身不被视为有效的名称字符,但 Unicode 补充字符是有效的(由SimpleNameChar规则的最终替代方案表示),并且它们应在文件中表示为 MUTF-8 编码中的代理代码点对。
简单名称→ | ||
简单名称字符(简单名称字符)* | ||
简单名称字符→ | ||
'A' …… 'Z' | ||
| | 'a' ... 'z' | |
| | '0' …… '9' | |
| | ' ' | 从 DEX 版本 040 开始 |
| | '$' | |
| | '-' | |
| | '_' | |
| | U+00a0 | 从 DEX 版本 040 开始 |
| | U+00a1 … U+1fff | |
| | U+2000 … U+200a | 从 DEX 版本 040 开始 |
| | U+2010 … U+2027 | |
| | U+202f | 从 DEX 版本 040 开始 |
| | U+2030 … U+d7ff | |
| | U+e000 … U+ffef | |
| | U+10000 … U+10ffff |
成员名字
由 field_id_item 和 method_id_item 使用
MemberName是类成员的名称,成员是字段、方法和内部类。
会员名→ | |
简单名称 | |
| | '<' 简单名称'>' |
全类名
FullClassName是一个完全限定的类名,包括一个可选的包说明符,后跟一个必需的名称。
全类名→ | |
OptionalPackagePrefix SimpleName | |
可选包前缀→ | |
( SimpleName '/' )* |
类型描述符
由 type_id_item 使用
TypeDescriptor是任何类型的表示,包括基元、类、数组和void
。各种版本的含义见下文。
类型描述符→ | |
'V' | |
| | 字段类型描述符 |
字段类型描述符→ | |
NonArrayFieldTypeDescriptor | |
| | ( '[' * 1…255) NonArrayFieldTypeDescriptor |
NonArrayFieldTypeDescriptor → | |
'Z' | |
| | 'B' |
| | 'S' |
| | 'C' |
| | 'I' |
| | 'J' |
| | 'F' |
| | 'D' |
| | 'L' 全类名';' |
ShortyDescriptor
由 proto_id_item 使用
ShortyDescriptor是方法原型的简写形式,包括返回类型和参数类型,除了各种引用(类或数组)类型之间没有区别。相反,所有引用类型都由单个'L'
字符表示。
ShortyDescriptor → | |
ShortyReturnType ( ShortyFieldType )* | |
ShortyReturnType → | |
'V' | |
| | ShortyFieldType |
ShortyFieldType → | |
'Z' | |
| | 'B' |
| | 'S' |
| | 'C' |
| | 'I' |
| | 'J' |
| | 'F' |
| | 'D' |
| | 'L' |
类型描述符语义
这是TypeDescriptor的每个变体的含义。
句法 | 意义 |
---|---|
五 | void ;仅对返回类型有效 |
Z | boolean |
乙 | byte |
小号 | short |
C | char |
我 | int |
Ĵ | long |
F | float |
D | double |
L完全/合格/姓名; | 类fully.qualified.Name |
[描述符 | descriptor 数组,可递归用于数组数组,但超过 255 个维度是无效的。 |
项目和相关结构
本节包括可能出现在.dex
文件中的每个顶级项目的定义。
header_item
出现在标题部分
对齐:4字节
姓名 | 格式 | 描述 |
---|---|---|
魔法 | ubyte[8] = DEX_FILE_MAGIC | 魔法值。有关更多详细信息,请参阅上面“ DEX_FILE_MAGIC ”下的讨论。 |
校验和 | 单位 | 文件其余部分的 adler32 校验和(除magic 和此字段外的所有内容);用于检测文件损坏 |
签名 | 优字节[20] | 文件其余部分的 SHA-1 签名(散列)(除magic 、 checksum 和和此字段之外的所有内容);用于唯一标识文件 |
文件大小 | 单位 | 整个文件(包括标题)的大小,以字节为单位 |
header_size | uint = 0x70 | 标头(整个部分)的大小,以字节为单位。这允许至少有限数量的向后/向前兼容性,而不会使格式无效。 |
endian_tag | uint = ENDIAN_CONSTANT | 字节序标签。有关更多详细信息,请参阅上面“ ENDIAN_CONSTANT 和REVERSE_ENDIAN_CONSTANT ”下的讨论。 |
链接大小 | 单位 | 链接部分的大小,如果此文件不是静态链接的,则为0 |
链接关闭 | 单位 | 从文件开头到链接部分的偏移量,如果link_size == 0 0 偏移量,如果非零,应该是到link_data 部分的偏移量。本文档未指定所指向数据的格式;这个头域(和之前的)作为钩子留给运行时实现使用。 |
map_off | 单位 | 从文件开头到地图项的偏移量。偏移量必须是非零的,应该是data 段的偏移量,并且数据应该是下面“ map_list ”指定的格式。 |
string_ids_size | 单位 | 字符串标识符列表中的字符串计数 |
string_ids_off | 单位 | 从文件开头到字符串标识符列表的偏移量,如果string_ids_size == 0 0 诚然是一个奇怪的边缘情况)。偏移量(如果非零)应位于string_ids 部分的开头。 |
type_ids_size | 单位 | 类型标识符列表中的元素计数,最多 65535 |
type_ids_off | 单位 | 从文件开头到类型标识符列表的偏移量,如果type_ids_size == 0 0 诚然,这是一个奇怪的边缘情况)。偏移量(如果非零)应位于type_ids 部分的开头。 |
proto_ids_size | 单位 | 原型标识符列表中的元素计数,最多 65535 |
proto_ids_off | 单位 | 从文件开头到原型标识符列表的偏移量,如果proto_ids_size == 0 0 诚然是一个奇怪的边缘情况),则为 0。偏移量(如果非零)应位于proto_ids 部分的开头。 |
field_ids_size | 单位 | 字段标识符列表中的元素计数 |
field_ids_off | 单位 | 从文件开头到字段标识符列表的偏移量,如果field_ids_size == 0 0 偏移量(如果非零)应位于field_ids 部分的开头。 |
method_ids_size | 单位 | 方法标识符列表中的元素计数 |
method_ids_off | 单位 | 从文件开头到方法标识符列表的偏移量,如果method_ids_size == 0 0 偏移量(如果非零)应位于method_ids 部分的开头。 |
class_defs_size | 单位 | 类定义列表中的元素计数 |
class_defs_off | 单位 | 从文件开头到类定义列表的偏移量,如果class_defs_size == 0 0 诚然,这是一个奇怪的边缘情况)。偏移量(如果非零)应位于class_defs 部分的开头。 |
数据大小 | 单位 | data 部分的大小(以字节为单位)。必须是 sizeof(uint) 的偶数倍。 |
数据关闭 | 单位 | 从文件开头到data 段开头的偏移量。 |
地图列表
出现在数据部分
从 header_item 引用
对齐:4字节
这是按顺序列出的文件全部内容的列表。它包含与header_item
相关的一些冗余,但旨在成为一种用于迭代整个文件的简单形式。给定类型在映射中最多只能出现一次,但除了格式的其余部分隐含的限制(例如, header
部分必须首先出现,然后是string_ids
节等)。此外,映射条目必须按初始偏移量排序,并且不得重叠。
姓名 | 格式 | 描述 |
---|---|---|
尺寸 | 单位 | 列表的大小,以条目为单位 |
列表 | 地图项[大小] | 列表的元素 |
map_item 格式
姓名 | 格式 | 描述 |
---|---|---|
类型 | 超短 | 项目类型;见下表 |
没用过 | 超短 | (没用过) |
尺寸 | 单位 | 要在指定偏移量处找到的项目数的计数 |
抵消 | 单位 | 从文件开头到相关项目的偏移量 |
类型代码
物品种类 | 持续的 | 价值 | 项目大小(以字节为单位) |
---|---|---|---|
header_item | TYPE_HEADER_ITEM | 0x0000 | 0x70 |
string_id_item | TYPE_STRING_ID_ITEM | 0x0001 | 0x04 |
type_id_item | TYPE_TYPE_ID_ITEM | 0x0002 | 0x04 |
proto_id_item | TYPE_PROTO_ID_ITEM | 0x0003 | 0x0c |
field_id_item | TYPE_FIELD_ID_ITEM | 0x0004 | 0x08 |
method_id_item | TYPE_METHOD_ID_ITEM | 0x0005 | 0x08 |
class_def_item | TYPE_CLASS_DEF_ITEM | 0x0006 | 0x20 |
call_site_id_item | TYPE_CALL_SITE_ID_ITEM | 0x0007 | 0x04 |
method_handle_item | TYPE_METHOD_HANDLE_ITEM | 0x0008 | 0x08 |
地图列表 | TYPE_MAP_LIST | 0x1000 | 4 + (item.size * 12) |
类型列表 | TYPE_TYPE_LIST | 0x1001 | 4 + (item.size * 2) |
annotation_set_ref_list | TYPE_ANNOTATION_SET_REF_LIST | 0x1002 | 4 + (item.size * 4) |
annotation_set_item | TYPE_ANNOTATION_SET_ITEM | 0x1003 | 4 + (item.size * 4) |
类数据项 | TYPE_CLASS_DATA_ITEM | 0x2000 | 隐含的;必须解析 |
代码项 | TYPE_CODE_ITEM | 0x2001 | 隐含的;必须解析 |
字符串数据项 | TYPE_STRING_DATA_ITEM | 0x2002 | 隐含的;必须解析 |
debug_info_item | TYPE_DEBUG_INFO_ITEM | 0x2003 | 隐含的;必须解析 |
注释项目 | TYPE_ANNOTATION_ITEM | 0x2004 | 隐含的;必须解析 |
编码数组项 | TYPE_ENCODED_ARRAY_ITEM | 0x2005 | 隐含的;必须解析 |
annotations_directory_item | TYPE_ANNOTATIONS_DIRECTORY_ITEM | 0x2006 | 隐含的;必须解析 |
hiddenapi_class_data_item | TYPE_HIDDENAPI_CLASS_DATA_ITEM | 0xF000 | 隐含的;必须解析 |
string_id_item
出现在 string_ids 部分
对齐:4字节
姓名 | 格式 | 描述 |
---|---|---|
string_data_off | 单位 | 从文件开头到此项的字符串数据的偏移量。偏移量应位于data 段中的某个位置,数据应采用下面“ string_data_item ”指定的格式。偏移没有对齐要求。 |
字符串数据项
出现在数据部分
对齐方式:无(字节对齐)
姓名 | 格式 | 描述 |
---|---|---|
utf16_size | uleb128 | 此字符串的大小,以 UTF-16 代码单元表示(在许多系统中是“字符串长度”)。也就是说,这是字符串的解码长度。 (编码长度由0 字节的位置暗示。) |
数据 | 优字节[] | 一系列 MUTF-8 代码单元(又名八位字节,又名字节),后跟一个值为0 的字节。有关数据格式的详细信息和讨论,请参阅上面的“MUTF-8(修改的 UTF-8)编码”。注意:可以接受包含(编码形式)UTF-16 代理代码单元(即 |
type_id_item
出现在 type_ids 部分
对齐:4字节
姓名 | 格式 | 描述 |
---|---|---|
描述符_idx | 单位 | 此类型描述符字符串的string_ids 列表的索引。该字符串必须符合上面定义的TypeDescriptor的语法。 |
proto_id_item
出现在 proto_ids 部分
对齐:4字节
姓名 | 格式 | 描述 |
---|---|---|
矮个子_idx | 单位 | 此原型的短格式描述符字符串的string_ids 列表中的索引。该字符串必须符合上面定义的ShortyDescriptor的语法,并且必须对应于此项的返回类型和参数。 |
return_type_idx | 单位 | 此原型的返回类型的type_ids 列表的索引 |
参数_off | 单位 | 从文件开头到此原型的参数类型列表的偏移量,如果此原型没有参数,则为0 。这个偏移量,如果非零,应该在data 部分,并且那里的数据应该是下面"type_list" 指定的格式。此外,列表中不应引用void 类型。 |
field_id_item
出现在 field_ids 部分
对齐:4字节
姓名 | 格式 | 描述 |
---|---|---|
class_idx | 超短 | 该字段定义者的type_ids 列表的索引。这必须是类类型,而不是数组或原始类型。 |
type_idx | 超短 | 该字段类型的type_ids 列表的索引 |
name_idx | 单位 | 该字段名称的string_ids 列表的索引。该字符串必须符合上面定义的MemberName语法。 |
method_id_item
出现在 method_ids 部分
对齐:4字节
姓名 | 格式 | 描述 |
---|---|---|
class_idx | 超短 | 该方法定义者的type_ids 列表的索引。这必须是类或数组类型,而不是原始类型。 |
proto_idx | 超短 | 该方法原型的proto_ids 列表中的索引 |
name_idx | 单位 | 此方法名称的string_ids 列表的索引。该字符串必须符合上面定义的MemberName语法。 |
class_def_item
出现在 class_defs 部分
对齐:4字节
姓名 | 格式 | 描述 |
---|---|---|
class_idx | 单位 | 该类的type_ids 列表的索引。这必须是类类型,而不是数组或原始类型。 |
访问标志 | 单位 | 类的访问标志( public , final 等)。有关详细信息,请参阅“ access_flags 定义”。 |
超类_idx | 单位 | 索引到超类的type_ids 列表中,或者如果这个类没有超类(即它是一个根类,例如Object ),则为常量值NO_INDEX 。如果存在,这必须是类类型,而不是数组或原始类型。 |
接口关闭 | 单位 | 从文件开头到接口列表的偏移量,如果没有,则为0 。这个偏移量应该在data 部分,并且那里的数据应该是下面“ type_list ”指定的格式。列表的每个元素都必须是类类型(不是数组或原始类型),并且不能有任何重复。 |
source_file_idx | 单位 | string_ids 列表中包含该类(至少大部分)原始源的文件名的索引,或特殊值NO_INDEX 表示缺少此信息。任何给定方法的debug_info_item 都可能覆盖此源文件,但预期大多数类将仅来自一个源文件。 |
annotations_off | 单位 | 从文件开头到此类的注释结构的偏移量,如果此类上没有注释,则为0 。这个偏移量,如果非零,应该在data 部分,并且那里的数据应该是下面“ annotations_directory_item ”指定的格式,所有项目都引用这个类作为定义者。 |
class_data_off | 单位 | 从文件开头到此项的关联类数据的偏移量,如果没有此类的类数据,则为0 。 (可能是这种情况,例如,如果这个类是一个标记接口。)偏移量,如果非零,应该在data 部分,并且数据应该是下面“ class_data_item ”指定的格式,所有项目都将此类称为定义者。 |
静态值关闭 | 单位 | 从文件开头到static 字段初始值列表的偏移量,如果没有,则为0 (并且所有static 字段都将使用0 或null 进行初始化)。这个偏移量应该在data 部分,并且那里的数据应该是下面“ encoded_array_item ”指定的格式。数组的大小必须不大于该类声明的static 字段个数,且元素与static 字段的顺序与对应的field_list 中声明的顺序相同。每个数组元素的类型必须与其对应字段的声明类型匹配。如果数组中的元素比static 字段少,则剩余字段将使用适合类型的0 或null 进行初始化。 |
call_site_id_item
出现在 call_site_ids 部分
对齐:4字节
姓名 | 格式 | 描述 |
---|---|---|
call_site_off | 单位 | 从文件开始到调用站点定义的偏移量。偏移量应该在数据部分,并且那里的数据应该是下面“call_site_item”指定的格式。 |
call_site_item
出现在数据部分
对齐:无(字节对齐)
call_site_item 是一个 encoded_array_item,其元素对应于提供给引导链接器方法的参数。前三个参数是:
- 表示引导链接器方法 (VALUE_METHOD_HANDLE) 的方法句柄。
- 引导链接器应解析的方法名称 (VALUE_STRING)。
- A method type corresponding to the type of the method name to be resolved (VALUE_METHOD_TYPE).
Any additional arguments are constant values passed to the bootstrap linker method. These arguments are passed in order and without any type conversions.
The method handle representing the bootstrap linker method must have return type java.lang.invoke.CallSite
. The first three parameter types are:
-
java.lang.invoke.Lookup
-
java.lang.String
-
java.lang.invoke.MethodType
The parameter types of any additional arguments are determined from their constant values.
method_handle_item
appears in the method_handles section
alignment: 4 bytes
Name | Format | 描述 |
---|---|---|
method_handle_type | ushort | type of the method handle; see table below |
unused | ushort | (unused) |
field_or_method_id | ushort | Field or method id depending on whether the method handle type is an accessor or a method invoker |
unused | ushort | (unused) |
Method Handle Type Codes
Constant | 价值 | 描述 |
---|---|---|
METHOD_HANDLE_TYPE_STATIC_PUT | 0x00 | Method handle is a static field setter (accessor) |
METHOD_HANDLE_TYPE_STATIC_GET | 0x01 | Method handle is a static field getter (accessor) |
METHOD_HANDLE_TYPE_INSTANCE_PUT | 0x02 | Method handle is an instance field setter (accessor) |
METHOD_HANDLE_TYPE_INSTANCE_GET | 0x03 | Method handle is an instance field getter (accessor) |
METHOD_HANDLE_TYPE_INVOKE_STATIC | 0x04 | Method handle is a static method invoker |
METHOD_HANDLE_TYPE_INVOKE_INSTANCE | 0x05 | Method handle is an instance method invoker |
METHOD_HANDLE_TYPE_INVOKE_CONSTRUCTOR | 0x06 | Method handle is a constructor method invoker |
METHOD_HANDLE_TYPE_INVOKE_DIRECT | 0x07 | Method handle is a direct method invoker |
METHOD_HANDLE_TYPE_INVOKE_INTERFACE | 0x08 | Method handle is an interface method invoker |
class_data_item
referenced from class_def_item
appears in the data section
alignment: none (byte-aligned)
Name | Format | 描述 |
---|---|---|
static_fields_size | uleb128 | the number of static fields defined in this item |
instance_fields_size | uleb128 | the number of instance fields defined in this item |
direct_methods_size | uleb128 | the number of direct methods defined in this item |
virtual_methods_size | uleb128 | the number of virtual methods defined in this item |
static_fields | encoded_field[static_fields_size] | the defined static fields, represented as a sequence of encoded elements. The fields must be sorted by field_idx in increasing order. |
instance_fields | encoded_field[instance_fields_size] | the defined instance fields, represented as a sequence of encoded elements. The fields must be sorted by field_idx in increasing order. |
direct_methods | encoded_method[direct_methods_size] | the defined direct (any of static , private , or constructor) methods, represented as a sequence of encoded elements. The methods must be sorted by method_idx in increasing order. |
virtual_methods | encoded_method[virtual_methods_size] | the defined virtual (none of static , private , or constructor) methods, represented as a sequence of encoded elements. This list should not include inherited methods unless overridden by the class that this item represents. The methods must be sorted by method_idx in increasing order. The method_idx of a virtual method must not be the same as any direct method. |
Note: All elements' field_id
s and method_id
s must refer to the same defining class.
encoded_field format
Name | Format | 描述 |
---|---|---|
field_idx_diff | uleb128 | index into the field_ids list for the identity of this field (includes the name and descriptor), represented as a difference from the index of previous element in the list. The index of the first element in a list is represented directly. |
access_flags | uleb128 | access flags for the field ( public , final , etc.). See " access_flags Definitions" for details. |
encoded_method format
Name | Format | 描述 |
---|---|---|
method_idx_diff | uleb128 | index into the method_ids list for the identity of this method (includes the name and descriptor), represented as a difference from the index of previous element in the list. The index of the first element in a list is represented directly. |
access_flags | uleb128 | access flags for the method ( public , final , etc.). See " access_flags Definitions" for details. |
code_off | uleb128 | offset from the start of the file to the code structure for this method, or 0 if this method is either abstract or native . The offset should be to a location in the data section. The format of the data is specified by " code_item " below. |
type_list
referenced from class_def_item and proto_id_item
appears in the data section
alignment: 4 bytes
Name | Format | 描述 |
---|---|---|
size | uint | size of the list, in entries |
list | type_item[size] | elements of the list |
type_item format
Name | Format | 描述 |
---|---|---|
type_idx | ushort | index into the type_ids list |
code_item
referenced from encoded_method
appears in the data section
alignment: 4 bytes
Name | Format | 描述 |
---|---|---|
registers_size | ushort | the number of registers used by this code |
ins_size | ushort | the number of words of incoming arguments to the method that this code is for |
outs_size | ushort | the number of words of outgoing argument space required by this code for method invocation |
tries_size | ushort | the number of try_item s for this instance. If non-zero, then these appear as the tries array just after the insns in this instance. |
debug_info_off | uint | offset from the start of the file to the debug info (line numbers + local variable info) sequence for this code, or 0 if there simply is no information. The offset, if non-zero, should be to a location in the data section. The format of the data is specified by " debug_info_item " below. |
insns_size | uint | size of the instructions list, in 16-bit code units |
insns | ushort[insns_size] | actual array of bytecode. The format of code in an insns array is specified by the companion document Dalvik bytecode . Note that though this is defined as an array of ushort , there are some internal structures that prefer four-byte alignment. Also, if this happens to be in an endian-swapped file, then the swapping is only done on individual ushort s and not on the larger internal structures. |
padding | ushort (optional) = 0 | two bytes of padding to make tries four-byte aligned. This element is only present if tries_size is non-zero and insns_size is odd. |
tries | try_item[tries_size] (optional) | array indicating where in the code exceptions are caught and how to handle them. Elements of the array must be non-overlapping in range and in order from low to high address. This element is only present if tries_size is non-zero. |
handlers | encoded_catch_handler_list (optional) | bytes representing a list of lists of catch types and associated handler addresses. Each try_item has a byte-wise offset into this structure. This element is only present if tries_size is non-zero. |
try_item format
Name | Format | 描述 |
---|---|---|
start_addr | uint | start address of the block of code covered by this entry. The address is a count of 16-bit code units to the start of the first covered instruction. |
insn_count | ushort | number of 16-bit code units covered by this entry. The last code unit covered (inclusive) is start_addr + insn_count - 1 . |
handler_off | ushort | offset in bytes from the start of the associated encoded_catch_hander_list to the encoded_catch_handler for this entry. This must be an offset to the start of an encoded_catch_handler . |
encoded_catch_handler_list format
Name | Format | 描述 |
---|---|---|
size | uleb128 | size of this list, in entries |
list | encoded_catch_handler[handlers_size] | actual list of handler lists, represented directly (not as offsets), and concatenated sequentially |
encoded_catch_handler format
Name | Format | 描述 |
---|---|---|
size | sleb128 | number of catch types in this list. If non-positive, then this is the negative of the number of catch types, and the catches are followed by a catch-all handler. For example: A size of 0 means that there is a catch-all but no explicitly typed catches. A size of 2 means that there are two explicitly typed catches and no catch-all. And a size of -1 means that there is one typed catch along with a catch-all. |
handlers | encoded_type_addr_pair[abs(size)] | stream of abs(size) encoded items, one for each caught type, in the order that the types should be tested. |
catch_all_addr | uleb128 (optional) | bytecode address of the catch-all handler. This element is only present if size is non-positive. |
encoded_type_addr_pair format
Name | Format | 描述 |
---|---|---|
type_idx | uleb128 | index into the type_ids list for the type of the exception to catch |
addr | uleb128 | bytecode address of the associated exception handler |
debug_info_item
referenced from code_item
appears in the data section
alignment: none (byte-aligned)
Each debug_info_item
defines a DWARF3-inspired byte-coded state machine that, when interpreted, emits the positions table and (potentially) the local variable information for a code_item
. The sequence begins with a variable-length header (the length of which depends on the number of method parameters), is followed by the state machine bytecodes, and ends with an DBG_END_SEQUENCE
byte.
The state machine consists of five registers. The address
register represents the instruction offset in the associated insns_item
in 16-bit code units. The address
register starts at 0
at the beginning of each debug_info
sequence and must only monotonically increase. The line
register represents what source line number should be associated with the next positions table entry emitted by the state machine. It is initialized in the sequence header, and may change in positive or negative directions but must never be less than 1
. The source_file
register represents the source file that the line number entries refer to. It is initialized to the value of source_file_idx
in class_def_item
. The other two variables, prologue_end
and epilogue_begin
, are boolean flags (initialized to false
) that indicate whether the next position emitted should be considered a method prologue or epilogue. The state machine must also track the name and type of the last local variable live in each register for the DBG_RESTART_LOCAL
code.
The header is as follows:
Name | Format | 描述 |
---|---|---|
line_start | uleb128 | the initial value for the state machine's line register. Does not represent an actual positions entry. |
parameters_size | uleb128 | the number of parameter names that are encoded. There should be one per method parameter, excluding an instance method's this , if any. |
parameter_names | uleb128p1[parameters_size] | string index of the method parameter name. An encoded value of NO_INDEX indicates that no name is available for the associated parameter. The type descriptor and signature are implied from the method descriptor and signature. |
The byte code values are as follows:
Name | 价值 | Format | Arguments | 描述 |
---|---|---|---|---|
DBG_END_SEQUENCE | 0x00 | (none) | terminates a debug info sequence for a code_item | |
DBG_ADVANCE_PC | 0x01 | uleb128 addr_diff | addr_diff : amount to add to address register | advances the address register without emitting a positions entry |
DBG_ADVANCE_LINE | 0x02 | sleb128 line_diff | line_diff : amount to change line register by | advances the line register without emitting a positions entry |
DBG_START_LOCAL | 0x03 | uleb128 register_num uleb128p1 name_idx uleb128p1 type_idx | register_num : register that will contain localname_idx : string index of the nametype_idx : type index of the type | introduces a local variable at the current address. Either name_idx or type_idx may be NO_INDEX to indicate that that value is unknown. |
DBG_START_LOCAL_EXTENDED | 0x04 | uleb128 register_num uleb128p1 name_idx uleb128p1 type_idx uleb128p1 sig_idx | register_num : register that will contain localname_idx : string index of the nametype_idx : type index of the typesig_idx : string index of the type signature | introduces a local with a type signature at the current address. Any of name_idx , type_idx , or sig_idx may be NO_INDEX to indicate that that value is unknown. (If sig_idx is -1 , though, the same data could be represented more efficiently using the opcode DBG_START_LOCAL .) Note: See the discussion under " |
DBG_END_LOCAL | 0x05 | uleb128 register_num | register_num : register that contained local | marks a currently-live local variable as out of scope at the current address |
DBG_RESTART_LOCAL | 0x06 | uleb128 register_num | register_num : register to restart | re-introduces a local variable at the current address. The name and type are the same as the last local that was live in the specified register. |
DBG_SET_PROLOGUE_END | 0x07 | (none) | sets the prologue_end state machine register, indicating that the next position entry that is added should be considered the end of a method prologue (an appropriate place for a method breakpoint). The prologue_end register is cleared by any special ( >= 0x0a ) opcode. | |
DBG_SET_EPILOGUE_BEGIN | 0x08 | (none) | sets the epilogue_begin state machine register, indicating that the next position entry that is added should be considered the beginning of a method epilogue (an appropriate place to suspend execution before method exit). The epilogue_begin register is cleared by any special ( >= 0x0a ) opcode. | |
DBG_SET_FILE | 0x09 | uleb128p1 name_idx | name_idx : string index of source file name; NO_INDEX if unknown | indicates that all subsequent line number entries make reference to this source file name, instead of the default name specified in code_item |
Special Opcodes | 0x0a…0xff | (none) | advances the line and address registers, emits a position entry, and clears prologue_end and epilogue_begin . See below for description. |
Special opcodes
Opcodes with values between 0x0a
and 0xff
(inclusive) move both the line
and address
registers by a small amount and then emit a new position table entry. The formula for the increments are as follows:
DBG_FIRST_SPECIAL = 0x0a // the smallest special opcode DBG_LINE_BASE = -4 // the smallest line number increment DBG_LINE_RANGE = 15 // the number of line increments represented adjusted_opcode = opcode - DBG_FIRST_SPECIAL line += DBG_LINE_BASE + (adjusted_opcode % DBG_LINE_RANGE) address += (adjusted_opcode / DBG_LINE_RANGE)
annotations_directory_item
referenced from class_def_item
appears in the data section
alignment: 4 bytes
Name | Format | 描述 |
---|---|---|
class_annotations_off | uint | offset from the start of the file to the annotations made directly on the class, or 0 if the class has no direct annotations. The offset, if non-zero, should be to a location in the data section. The format of the data is specified by " annotation_set_item " below. |
fields_size | uint | count of fields annotated by this item |
annotated_methods_size | uint | count of methods annotated by this item |
annotated_parameters_size | uint | count of method parameter lists annotated by this item |
field_annotations | field_annotation[fields_size] (optional) | list of associated field annotations. The elements of the list must be sorted in increasing order, by field_idx . |
method_annotations | method_annotation[methods_size] (optional) | list of associated method annotations. The elements of the list must be sorted in increasing order, by method_idx . |
parameter_annotations | parameter_annotation[parameters_size] (optional) | list of associated method parameter annotations. The elements of the list must be sorted in increasing order, by method_idx . |
Note: All elements' field_id
s and method_id
s must refer to the same defining class.
field_annotation format
Name | Format | 描述 |
---|---|---|
field_idx | uint | index into the field_ids list for the identity of the field being annotated |
annotations_off | uint | offset from the start of the file to the list of annotations for the field. The offset should be to a location in the data section. The format of the data is specified by " annotation_set_item " below. |
method_annotation format
Name | Format | 描述 |
---|---|---|
method_idx | uint | index into the method_ids list for the identity of the method being annotated |
annotations_off | uint | offset from the start of the file to the list of annotations for the method. The offset should be to a location in the data section. The format of the data is specified by " annotation_set_item " below. |
parameter_annotation format
Name | Format | 描述 |
---|---|---|
method_idx | uint | index into the method_ids list for the identity of the method whose parameters are being annotated |
annotations_off | uint | offset from the start of the file to the list of annotations for the method parameters. The offset should be to a location in the data section. The format of the data is specified by " annotation_set_ref_list " below. |
annotation_set_ref_list
referenced from parameter_annotations_item
appears in the data section
alignment: 4 bytes
Name | Format | 描述 |
---|---|---|
size | uint | size of the list, in entries |
list | annotation_set_ref_item[size] | elements of the list |
annotation_set_ref_item format
Name | Format | 描述 |
---|---|---|
annotations_off | uint | offset from the start of the file to the referenced annotation set or 0 if there are no annotations for this element. The offset, if non-zero, should be to a location in the data section. The format of the data is specified by " annotation_set_item " below. |
annotation_set_item
referenced from annotations_directory_item, field_annotations_item, method_annotations_item, and annotation_set_ref_item
appears in the data section
alignment: 4 bytes
Name | Format | 描述 |
---|---|---|
size | uint | size of the set, in entries |
entries | annotation_off_item[size] | elements of the set. The elements must be sorted in increasing order, by type_idx . |
annotation_off_item format
Name | Format | 描述 |
---|---|---|
annotation_off | uint | offset from the start of the file to an annotation. The offset should be to a location in the data section, and the format of the data at that location is specified by " annotation_item " below. |
annotation_item
referenced from annotation_set_item
appears in the data section
alignment: none (byte-aligned)
Name | Format | 描述 |
---|---|---|
visibility | ubyte | intended visibility of this annotation (see below) |
annotation | encoded_annotation | encoded annotation contents, in the format described by " encoded_annotation format" under " encoded_value encoding" above. |
Visibility values
These are the options for the visibility
field in an annotation_item
:
Name | 价值 | 描述 |
---|---|---|
VISIBILITY_BUILD | 0x00 | intended only to be visible at build time (eg, during compilation of other code) |
VISIBILITY_RUNTIME | 0x01 | intended to visible at runtime |
VISIBILITY_SYSTEM | 0x02 | intended to visible at runtime, but only to the underlying system (and not to regular user code) |
encoded_array_item
referenced from class_def_item
appears in the data section
alignment: none (byte-aligned)
Name | Format | 描述 |
---|---|---|
value | encoded_array | bytes representing the encoded array value, in the format specified by " encoded_array Format" under " encoded_value Encoding" above. |
hiddenapi_class_data_item
This section contains data on restricted interfaces used by each class.
Note: The hidden API feature was introduced in Android 10.0 and is only applicable to the DEX files of classes in the boot class path. The list of flags described below may be extended in the future releases of Android. For more information, see restrictions on non-SDK interfaces .
Name | Format | 描述 |
---|---|---|
size | uint | total size of the section |
offsets | uint[] | array of offsets indexed by class_idx . A zero array entry at index class_idx means that either there is no data for this class_idx , or all hidden API flags are zero. Otherwise the array entry is non-zero and contains an offset from the beginning of the section to an array of hidden API flags for this class_idx . |
flags | uleb128[] | concatenated arrays of hidden API flags for each class. Possible flag values are described in the table below. Flags are encoded in the same order as fields and methods are encoded in class data. |
Restriction flag types:
Name | 价值 | 描述 |
---|---|---|
whitelist | 0 | Interfaces that can be freely used and are supported as part of the officially documented Android framework Package Index . |
greylist | 1 | Non-SDK interfaces that can be used regardless of the application's target API level . |
blacklist | 2 | Non-SDK interfaces that cannot be used regardless of the application's target API level . Accessing one of these interfaces causes a runtime error . |
greylist‑max‑o | 3 | Non-SDK interfaces that can be used for Android 8.x and below unless they are restricted. |
greylist‑max‑p | 4 | Non-SDK interfaces that can be used for Android 9.x unless they are restricted. |
greylist‑max‑q | 5 | Non-SDK interfaces that can be used for Android 10.x unless they are restricted. |
greylist‑max‑r | 6 | Non-SDK interfaces that can be used for Android 11.x unless they are restricted. |
System annotations
System annotations are used to represent various pieces of reflective information about classes (and methods and fields). This information is generally only accessed indirectly by client (non-system) code.
System annotations are represented in .dex
files as annotations with visibility set to VISIBILITY_SYSTEM
.
dalvik.annotation.AnnotationDefault
appears on methods in annotation interfaces
An AnnotationDefault
annotation is attached to each annotation interface which wishes to indicate default bindings.
Name | Format | 描述 |
---|---|---|
value | Annotation | the default bindings for this annotation, represented as an annotation of this type. The annotation need not include all names defined by the annotation; missing names simply do not have defaults. |
dalvik.annotation.EnclosingClass
appears on classes
An EnclosingClass
annotation is attached to each class which is either defined as a member of another class, per se, or is anonymous but not defined within a method body (eg, a synthetic inner class). Every class that has this annotation must also have an InnerClass
annotation. Additionally, a class must not have both an EnclosingClass
and an EnclosingMethod
annotation.
Name | Format | 描述 |
---|---|---|
value | Class | the class which most closely lexically scopes this class |
dalvik.annotation.EnclosingMethod
appears on classes
An EnclosingMethod
annotation is attached to each class which is defined inside a method body. Every class that has this annotation must also have an InnerClass
annotation. Additionally, a class must not have both an EnclosingClass
and an EnclosingMethod
annotation.
Name | Format | 描述 |
---|---|---|
value | Method | the method which most closely lexically scopes this class |
dalvik.annotation.InnerClass
appears on classes
An InnerClass
annotation is attached to each class which is defined in the lexical scope of another class's definition. Any class which has this annotation must also have either an EnclosingClass
annotation or an EnclosingMethod
annotation.
Name | Format | 描述 |
---|---|---|
name | String | the originally declared simple name of this class (not including any package prefix). If this class is anonymous, then the name is null . |
accessFlags | int | the originally declared access flags of the class (which may differ from the effective flags because of a mismatch between the execution models of the source language and target virtual machine) |
dalvik.annotation.MemberClasses
appears on classes
A MemberClasses
annotation is attached to each class which declares member classes. (A member class is a direct inner class that has a name.)
Name | Format | 描述 |
---|---|---|
value | Class[] | array of the member classes |
dalvik.annotation.MethodParameters
appears on methods
Note: This annotation was added after Android 7.1. Its presence on earlier Android releases will be ignored.
A MethodParameters
annotation is optional and can be used to provide parameter metadata such as parameter names and modifiers.
The annotation can be omitted from a method or constructor safely when the parameter metadata is not required at runtime. java.lang.reflect.Parameter.isNamePresent()
can be used to check whether metadata is present for a parameter, and the associated reflection methods such as java.lang.reflect.Parameter.getName()
will fall back to default behavior at runtime if the information is not present.
When including parameter metadata, compilers must include information for generated classes such as enums, since the parameter metadata includes whether or not a parameter is synthetic or mandated.
A MethodParameters
annotation describes only individual method parameters. Therefore, compilers may omit the annotation entirely for constructors and methods that have no parameters, for the sake of code-size and runtime efficiency.
The arrays documented below must be the same size as for the method_id_item
dex structure associated with the method, otherwise a java.lang.reflect.MalformedParametersException
will be thrown at runtime.
That is: method_id_item.proto_idx
-> proto_id_item.parameters_off
-> type_list.size
must be the same as names().length
and accessFlags().length
.
Because MethodParameters
describes all formal method parameters, even those not explicitly or implicitly declared in source code, the size of the arrays may differ from the Signature or other metadata information that is based only on explicit parameters declared in source code. MethodParameters
will also not include any information about type annotation receiver parameters that do not exist in the actual method signature.
Name | Format | 描述 |
---|---|---|
names | String[] | The names of formal parameters for the associated method. The array must not be null but must be empty if there are no formal parameters. A value in the array must be null if the formal parameter with that index has no name. If parameter name strings are empty or contain '.', ';', '[' or '/' then a java.lang.reflect.MalformedParametersException will be thrown at runtime. |
accessFlags | int[] | The access flags of the formal parameters for the associated method. The array must not be null but must be empty if there are no formal parameters. The value is a bit mask with the following values:
java.lang.reflect.MalformedParametersException will be thrown at runtime. |
dalvik.annotation.Signature
appears on classes, fields, and methods
A Signature
annotation is attached to each class, field, or method which is defined in terms of a more complicated type than is representable by a type_id_item
. The .dex
format does not define the format for signatures; it is merely meant to be able to represent whatever signatures a source language requires for successful implementation of that language's semantics. As such, signatures are not generally parsed (or verified) by virtual machine implementations. The signatures simply get handed off to higher-level APIs and tools (such as debuggers). Any use of a signature, therefore, should be written so as not to make any assumptions about only receiving valid signatures, explicitly guarding itself against the possibility of coming across a syntactically invalid signature.
Because signature strings tend to have a lot of duplicated content, a Signature
annotation is defined as an array of strings, where duplicated elements naturally refer to the same underlying data, and the signature is taken to be the concatenation of all the strings in the array. There are no rules about how to pull apart a signature into separate strings; that is entirely up to the tools that generate .dex
files.
Name | Format | 描述 |
---|---|---|
value | String[] | the signature of this class or member, as an array of strings that is to be concatenated together |
dalvik.annotation.Throws
appears on methods
A Throws
annotation is attached to each method which is declared to throw one or more exception types.
Name | Format | 描述 |
---|---|---|
value | Class[] | the array of exception types thrown |