本文檔描述了.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)。
- 與要解析的方法名稱的類型(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
姓名 | 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 | Value | 描述 |
---|---|---|
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)
姓名 | 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
姓名 | 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
姓名 | 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
姓名 | Format | 描述 |
---|---|---|
size | uint | size of the list, in entries |
list | type_item[size] | elements of the list |
type_item format
姓名 | Format | 描述 |
---|---|---|
type_idx | ushort | index into the type_ids list |
code_item
referenced from encoded_method
appears in the data section
alignment: 4 bytes
姓名 | 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
姓名 | 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
姓名 | 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
姓名 | 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
姓名 | 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:
姓名 | 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:
姓名 | Value | 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
姓名 | 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
姓名 | 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
姓名 | 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
姓名 | 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
姓名 | Format | 描述 |
---|---|---|
size | uint | size of the list, in entries |
list | annotation_set_ref_item[size] | elements of the list |
annotation_set_ref_item format
姓名 | 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
姓名 | 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
姓名 | 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)
姓名 | 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
:
姓名 | Value | 描述 |
---|---|---|
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)
姓名 | 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 .
姓名 | 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:
姓名 | Value | 描述 |
---|---|---|
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.
姓名 | 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.
姓名 | 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.
姓名 | 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.
姓名 | 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.)
姓名 | 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.
姓名 | 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.
姓名 | 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.
姓名 | Format | 描述 |
---|---|---|
value | Class[] | the array of exception types thrown |