Format exécutable Dalvik

Ce document décrit la mise en page et le contenu des fichiers .dex, qui sont utilisés pour contenir un ensemble de définitions de classe et leurs données complémentaires associées.

Guide des types

Nom Description
octet Entier signé de 8 bits
ubyte Entier non signé de 8 bits
court Entier signé de 16 bits, little-endian
ushort Entier non signé 16 bits, little-endian
int Entier signé de 32 bits, little-endian
uint Entier non signé de 32 bits, little-endian
long Entier signé de 64 bits, little-endian
ulong Entier non signé de 64 bits, little-endian
sleb128 LEB128 signé, longueur variable (voir ci-dessous)
uleb128 LEB128 non signé, longueur variable (voir ci-dessous)
uleb128p1 LEB128 non signé plus 1, longueur variable (voir ci-dessous)

LEB128

LEB128 ("Little-Endian Base 128") est un encodage de longueur variable pour les quantités entières signées ou non signées arbitraires. Le format a été emprunté à la spécification DWARF3. Dans un fichier .dex, LEB128 n'est utilisé que pour encoder des quantités de 32 bits.

Chaque valeur encodée LEB128 se compose d'un à cinq octets, qui représentent ensemble une seule valeur de 32 bits. Le bit le plus significatif de chaque octet est défini, à l'exception de l'octet final de la séquence, dont le bit le plus significatif est effacé. Les sept bits restants de chaque octet sont une charge utile, avec les sept bits les moins significatifs de la quantité dans le premier octet, les sept suivants dans le deuxième octet, et ainsi de suite. Dans le cas d'un LEB128 signé (sleb128), le bit de charge utile le plus significatif du dernier octet de la séquence est étendu au signe pour produire la valeur finale. Dans le cas non signé (uleb128), tous les bits qui ne sont pas explicitement représentés sont interprétés comme 0.

Diagramme bit à bit d'une valeur LEB128 de deux octets
Premier octet Deuxième octet
1 bit6 bit5 bit4 bit3 bit2 bit1 bit0 0 bit13 bit12 bit11 bit10 bit9 bit8 bit7

La variante uleb128p1 est utilisée pour représenter une valeur signée, où la représentation est celle de la valeur plus un encodée en tant que uleb128. Cela permet d'encoder -1 (ou la valeur non signée 0xffffffff) sur un seul octet, mais pas les autres nombres négatifs. C'est utile dans les cas où le nombre représenté doit être non négatif ou égal à -1 (ou 0xffffffff), et où aucune autre valeur négative n'est autorisée (ou lorsque de grandes valeurs non signées ne sont pas susceptibles d'être nécessaires).

Voici quelques exemples de formats :

Séquence encodée En tant que sleb128 En tant que uleb128 En tant que uleb128p1
0000-1
01110
7f-1127126
80 7f-1281625616255

Disposition du fichier

Nom Format Description
en-tête header_item l'en-tête ;
string_ids string_id_item[] Liste d'identifiants de chaînes. Il s'agit d'identifiants pour toutes les chaînes utilisées par ce fichier, soit pour la dénomination interne (par exemple, les descripteurs de type), soit en tant qu'objets constants auxquels le code fait référence. Cette liste doit être triée par contenu de chaîne, à l'aide des valeurs de point de code UTF-16 (et non d'une manière sensible aux paramètres régionaux). Elle ne doit pas contenir d'entrées en double.
type_ids type_id_item[] Liste des identifiants de type. Il s'agit d'identifiants pour tous les types (classes, tableaux ou types primitifs) auxquels ce fichier fait référence, qu'ils soient définis ou non dans le fichier. Cette liste doit être triée par index string_id et ne doit contenir aucune entrée en double.
proto_ids proto_id_item[] Liste des identifiants de prototype de méthode. Il s'agit des identifiants de tous les prototypes auxquels ce fichier fait référence. Cette liste doit être triée par ordre décroissant de type de retour (par index type_id), puis par liste d'arguments (ordre lexicographique, arguments individuels triés par index type_id). La liste ne doit pas contenir d'entrées en double.
field_ids field_id_item[] liste des identifiants de champ. Il s'agit des identifiants de tous les champs auxquels ce fichier fait référence, qu'ils soient définis ou non dans le fichier. Cette liste doit être triée, où le type de définition (par index type_id) est l'ordre principal, le nom du champ (par index string_id) est l'ordre intermédiaire et le type (par index type_id) est l'ordre secondaire. La liste ne doit pas contenir d'entrées en double.
method_ids method_id_item[] liste des identifiants de méthode. Il s'agit d'identifiants pour toutes les méthodes auxquelles ce fichier fait référence, qu'elles soient définies ou non dans le fichier. Cette liste doit être triée, où le type de définition (par index type_id) est l'ordre principal, le nom de la méthode (par index string_id) est l'ordre intermédiaire et le prototype de la méthode (par index proto_id) est l'ordre secondaire. La liste ne doit pas contenir d'entrées en double.
class_defs class_def_item[] Liste des définitions de classe. Les classes doivent être ordonnées de sorte que la superclasse et les interfaces implémentées d'une classe donnée apparaissent dans la liste avant la classe référente. De plus, il n'est pas valide qu'une définition pour la classe du même nom apparaisse plusieurs fois dans la liste.
call_site_ids call_site_id_item[] Liste des identifiants de site d'appel. Il s'agit des identifiants de tous les sites d'appel auxquels ce fichier fait référence, qu'ils soient définis ou non dans le fichier. Cette liste doit être triée par ordre croissant de call_site_off.
method_handles method_handle_item[] liste des handles de méthode. Liste de tous les gestionnaires de méthodes auxquels ce fichier fait référence, qu'ils soient définis ou non dans le fichier. Cette liste n'est pas triée et peut contenir des doublons qui correspondent logiquement à différentes instances de gestionnaire de méthode.
de données ubyte[] zone de données, qui contient toutes les données d'assistance pour les tableaux listés ci-dessus. Différents éléments ont des exigences d'alignement différentes, et des octets de remplissage sont insérés avant chaque élément si nécessaire pour obtenir un alignement correct.
link_data ubyte[] les données utilisées dans les fichiers liés de manière statique. Le format des données de cette section n'est pas spécifié dans ce document. Cette section est vide dans les fichiers non associés, et les implémentations d'exécution peuvent l'utiliser comme elles le souhaitent.

Format du conteneur

La version 41 introduit un nouveau format de conteneur pour les données DEX afin de gagner de l'espace. Ce format de conteneur permet de combiner plusieurs fichiers DEX logiques en un seul fichier physique. Le nouveau format est principalement une simple concaténation des fichiers de l'ancien format, avec quelques différences :

  • file_size correspond à la taille du fichier logique, et non du fichier physique. Il peut être utilisé pour parcourir tous les fichiers logiques du conteneur.
  • Les fichiers dex logiques peuvent faire référence à des données ultérieures dans le conteneur (mais pas antérieures). Cela permet aux fichiers dex de partager des données, telles que des chaînes, entre eux.
  • Tous les décalages sont relatifs au fichier physique. Aucun décalage n'est relatif à l'en-tête. Cela permet de partager des sections avec des décalages entre des fichiers logiques.
  • L'en-tête ajoute deux nouveaux champs pour décrire les limites du conteneur. Il s'agit d'un contrôle de cohérence supplémentaire qui facilite le portage du code vers le nouveau format.
  • Les champs data_size et data_off ne sont plus utilisés. Les données peuvent être réparties sur plusieurs fichiers logiques et ne doivent pas nécessairement être contiguës.

Définitions de bitfield, de chaîne et de constante

DEX_FILE_MAGIC

Intégré dans header_item

La chaîne/le tableau constant DEX_FILE_MAGIC correspond à la liste des octets qui doivent figurer au début d'un fichier .dex pour qu'il soit reconnu comme tel. La valeur contient intentionnellement un caractère de nouvelle ligne ("\n" ou 0x0a) et un octet nul ("\0" ou 0x00) pour faciliter la détection de certaines formes de corruption. La valeur encode également un numéro de version du format sous la forme de trois chiffres décimaux, qui devrait augmenter de manière monotone au fil du temps à mesure que le format évolue.

ubyte[8] DEX_FILE_MAGIC = { 0x64 0x65 0x78 0x0a 0x30 0x33 0x39 0x00 }
                        = "dex\n039\0"

Remarque : La prise en charge de la version 041 du format a été ajoutée dans la version 16 d'Android, qui est compatible avec le format de conteneur.

Remarque : La prise en charge de la version 040 du format a été ajoutée dans la version Android 10.0, qui a étendu l'ensemble des caractères autorisés dans SimpleNames.

Remarque : La prise en charge de la version 039 du format a été ajoutée dans la version Android 9.0, qui a introduit deux nouveaux bytecodes, const-method-handle et const-method-type. (Chacun d'eux est décrit dans le tableau Résumé de l'ensemble de bytecode.) Dans Android 10, la version 039 étend le format de fichier DEX pour inclure des informations d'API masquées qui ne s'appliquent qu'aux fichiers DEX sur le chemin de classe de démarrage.

Remarque : La prise en charge de la version 038 du format a été ajoutée dans la version Android 8.0. La version 038 a ajouté de nouveaux codes d'octet (invoke-polymorphic et invoke-custom) et des données pour les gestionnaires de méthodes.

Remarque : La prise en charge de la version 037 du format a été ajoutée dans la version 7.0 d'Android. Avant la version 037, la plupart des versions d'Android utilisaient la version 035 du format. La seule différence entre les versions 035 et 037 est l'ajout de méthodes par défaut et l'ajustement de invoke.

Remarque : Au moins deux versions antérieures du format ont été utilisées dans des versions logicielles publiques largement disponibles. Par exemple, la version 009 a été utilisée pour les versions M3 de la plate-forme Android (novembre-décembre 2007) et la version 013 pour les versions M5 de la plate-forme Android (février-mars 2008). À plusieurs égards, ces versions antérieures du format diffèrent considérablement de la version décrite dans ce document.

ENDIAN_CONSTANT et REVERSE_ENDIAN_CONSTANT

Intégré dans header_item

La constante ENDIAN_CONSTANT est utilisée pour indiquer l'endianness du fichier dans lequel elle se trouve. Bien que le format standard .dex soit little-endian, les implémentations peuvent choisir d'effectuer un échange d'octets. Si une implémentation rencontre un en-tête dont endian_tag est REVERSE_ENDIAN_CONSTANT au lieu de ENDIAN_CONSTANT, elle saura que le fichier a été inversé par octets par rapport à la forme attendue.

uint ENDIAN_CONSTANT = 0x12345678;
uint REVERSE_ENDIAN_CONSTANT = 0x78563412;

NO_INDEX

Intégré dans class_def_item et debug_info_item

La constante NO_INDEX est utilisée pour indiquer qu'une valeur d'index est absente.

Remarque : Cette valeur n'est pas définie sur 0, car il s'agit généralement d'un index valide.

La valeur choisie pour NO_INDEX est représentable sous la forme d'un seul octet dans l'encodage uleb128p1.

uint NO_INDEX = 0xffffffff;    // == -1 if treated as a signed int

Définitions des indicateurs d'accès

Intégré dans class_def_item, encoded_field, encoded_method et InnerClass

Les champs de bits de ces indicateurs sont utilisés pour indiquer l'accessibilité et les propriétés générales des classes et des membres de classe.

Nom Valeur Pour les classes (et les annotations InnerClass) Pour les champs Pour les méthodes
ACC_PUBLIC 0x1 public : visible partout public : visible partout public : visible partout
ACC_PRIVATE 0x2 * private : visible uniquement par la classe de définition private : visible uniquement pour la classe de définition private : visible uniquement pour la classe de définition
ACC_PROTECTED 0x4 * protected : visible pour le package et les sous-classes protected : visible pour le package et les sous-classes protected : visible pour le package et les sous-classes
ACC_STATIC 0x8 * static : n'est pas construit avec une référence this externe static : portée globale à la classe de définition static : n'accepte pas d'argument this
ACC_FINAL 0x10 final : non sous-classable final : immuable après la construction final : non modifiable
ACC_SYNCHRONIZED 0x20     synchronized : le verrou associé est automatiquement acquis lors de l'appel à cette méthode.

Remarque : Cette valeur ne peut être définie que si ACC_NATIVE est également défini.

ACC_VOLATILE 0x40   volatile : règles d'accès spécial pour assurer la sécurité des threads  
ACC_BRIDGE 0x40     méthode pont, ajoutée automatiquement par le compilateur en tant que pont de type sécurisé
ACC_TRANSIENT 0x80   transient : ne pas enregistrer par sérialisation par défaut  
ACC_VARARGS 0x80     Le dernier argument doit être traité comme un argument "rest" par le compilateur.
ACC_NATIVE 0x100     native : implémenté dans le code natif
ACC_INTERFACE 0x200 interface : classe abstraite à implémentation multiple    
ACC_ABSTRACT 0x400 abstract : non directement instanciable   abstract : non implémenté par cette classe
ACC_STRICT 0x800     strictfp : règles strictes pour l'arithmétique à virgule flottante
ACC_SYNTHETIC 0x1000 non directement définies dans le code source. non directement définies dans le code source. non directement définies dans le code source.
ACC_ANNOTATION 0x2000 déclarée comme classe d'annotation    
ACC_ENUM 0x4000 déclaré comme type énuméré déclarée comme valeur énumérée  
(non utilisé) 0x8000      
ACC_CONSTRUCTOR 0x10000     méthode constructeur (initialiseur de classe ou d'instance)
ACC_DECLARED_
SYNCHRONIZED
0x20000     a déclaré synchronized.

Remarque : Cela n'a aucun effet sur l'exécution (autre que dans la réflexion de cet indicateur, en soi).

* Autorisé uniquement pour les annotations InnerClass et jamais pour les class_def_item.

Encodage UTF-8 modifié

Pour faciliter la prise en charge des anciens formats, le format .dex encode ses données de chaîne dans un format UTF-8 modifié, qui est devenu une norme de facto et que nous appellerons MUTF-8. Cette forme est identique à la forme UTF-8 standard, à quelques exceptions près :

  • Seuls les encodages sur un, deux et trois octets sont utilisés.
  • Les points de code compris dans la plage U+10000 … U+10ffff sont encodés sous forme de paire de substitution, dont chacun est représenté par une valeur encodée sur trois octets.
  • Le point de code U+0000 est encodé sur deux octets.
  • Un simple octet nul (valeur 0) indique la fin d'une chaîne, conformément à l'interprétation standard du langage C.

Les deux premiers éléments ci-dessus peuvent être résumés comme suit : MUTF-8 est un format d'encodage pour UTF-16, au lieu d'être un format d'encodage plus direct pour les caractères Unicode.

Les deux derniers éléments ci-dessus permettent à la fois d'inclure le point de code U+0000 dans une chaîne et de le manipuler comme une chaîne de style C terminée par un caractère nul.

Toutefois, l'encodage spécial de U+0000 signifie que, contrairement à l'UTF-8 normal, le résultat de l'appel de la fonction C standard strcmp() sur une paire de chaînes MUTF-8 n'indique pas toujours le résultat correctement signé de la comparaison de chaînes inégales. Lorsque l'ordre (et pas seulement l'égalité) est important, le moyen le plus simple de comparer les chaînes MUTF-8 consiste à les décoder caractère par caractère et à comparer les valeurs décodées. (Toutefois, des implémentations plus astucieuses sont également possibles.)

Pour en savoir plus sur l'encodage des caractères, veuillez consulter The Unicode Standard. MUTF-8 est en fait plus proche de l'encodage CESU-8 (relativement moins connu) que d'UTF-8 en soi.

Encodage de la valeur encodée

Intégré dans annotation_element et encoded_array_item

Un encoded_value est un élément encodé de données structurées hiérarchiquement (presque) arbitraires. L'encodage est conçu pour être à la fois compact et facile à analyser.

Nom Format Description
(value_arg << 5) | value_type ubyte octet indiquant le type de value immédiatement suivant, avec un argument de clarification facultatif dans les trois bits de poids fort. Vous trouverez ci-dessous les différentes définitions de value. Dans la plupart des cas, value_arg code la longueur du value immédiatement suivant en octets, sous la forme (size - 1), par exemple : 0 signifie que la valeur nécessite un octet, et 7 signifie qu'elle en nécessite huit. Toutefois, il existe des exceptions, comme indiqué ci-dessous.
value ubyte[] Octets représentant la valeur, de longueur variable et interprétés différemment pour différents octets value_type, mais toujours en little-endian. Pour en savoir plus, consultez les différentes définitions de valeurs ci-dessous.

Formats de valeurs

Nom du type value_type Format value_arg Format value Description
VALUE_BYTE 0x00 (aucune ; doit être 0) ubyte[1] valeur entière signée d'un octet
VALUE_SHORT 0x02 Taille : 1 (0…1) ubyte[size] Valeur entière signée de deux octets, avec extension du signe
VALUE_CHAR 0x03 Taille : 1 (0…1) ubyte[size] Valeur entière non signée de deux octets, étendue à zéro
VALUE_INT 0x04 Taille : 1 (0…3) ubyte[size] valeur entière signée de quatre octets, avec extension du signe
VALUE_LONG 0x06 Taille : 1 (0…7) ubyte[size] Valeur entière signée de huit octets, avec extension du signe
VALUE_FLOAT 0x10 Taille : 1 (0…3) ubyte[size] Modèle de bits de quatre octets, étendu à zéro à droite et interprété comme une valeur à virgule flottante IEEE754 32 bits
VALUE_DOUBLE 0x11 Taille : 1 (0…7) ubyte[size] un modèle de bits de huit octets, étendu à zéro à droite et interprété comme une valeur à virgule flottante IEEE754 de 64 bits.
VALUE_METHOD_TYPE 0x15 Taille : 1 (0…3) ubyte[size] Valeur entière non signée (étendue à zéro) de quatre octets, interprétée comme un index dans la section proto_ids et représentant une valeur de type de méthode
VALUE_METHOD_HANDLE 0x16 Taille : 1 (0…3) ubyte[size] Valeur entière non signée (étendue à zéro) de quatre octets, interprétée comme un index dans la section method_handles et représentant une valeur de handle de méthode
VALUE_STRING 0x17 Taille : 1 (0…3) ubyte[size] Valeur entière non signée (étendue à zéro) de quatre octets, interprétée comme un index dans la section string_ids et représentant une valeur de chaîne
VALUE_TYPE 0x18 Taille : 1 (0…3) ubyte[size] Valeur entière non signée (étendue à zéro) de quatre octets, interprétée comme un index dans la section type_ids et représentant une valeur de type/classe réflexive
VALUE_FIELD 0x19 Taille : 1 (0…3) ubyte[size] Valeur entière non signée (étendue à zéro) de quatre octets, interprétée comme un index dans la section field_ids et représentant une valeur de champ réfléchissante
VALUE_METHOD 0x1a Taille : 1 (0…3) ubyte[size] Valeur entière non signée (étendue à zéro) de quatre octets, interprétée comme un index dans la section method_ids et représentant une valeur de méthode réflexive
VALUE_ENUM 0x1b Taille : 1 (0…3) ubyte[size] Valeur entière non signée (étendue à zéro) de quatre octets, interprétée comme un index dans la section field_ids et représentant la valeur d'une constante de type énuméré
VALUE_ARRAY 0x1c (aucune ; doit être 0) encoded_array un tableau de valeurs, au format spécifié par "Format encoded_array" ci-dessous. La taille de value est implicite dans l'encodage.
VALUE_ANNOTATION 0x1d (aucune ; doit être 0) encoded_annotation une sous-annotation, au format spécifié par "encoded_annotation format" ci-dessous. La taille de value est implicite dans l'encodage.
VALUE_NULL 0x1e (aucune ; doit être 0) (aucun) Valeur de référence null
VALUE_BOOLEAN 0x1f booléen (0…1) (aucun) Valeur d'un bit : 0 pour false et 1 pour true. Le bit est représenté dans value_arg.

Format encoded_array

Nom Format Description
taille uleb128 nombre d'éléments du tableau
values encoded_value[size] une série de séquences d'octets size encoded_value au format spécifié dans cette section, concaténées de manière séquentielle.

Format encoded_annotation

Nom Format Description
type_idx uleb128 Type de l'annotation. Il doit s'agir d'un type de classe (et non d'un type de tableau ou primitif).
taille uleb128 Nombre de mappages nom-valeur dans cette annotation
éléments annotation_element[size] éléments de l'annotation, représentés directement en ligne (et non sous forme de décalages). Les éléments doivent être triés par ordre croissant selon l'index string_id.

Format de annotation_element

Nom Format Description
name_idx uleb128 Nom de l'élément, représenté sous la forme d'un index dans la section string_ids. La chaîne doit être conforme à la syntaxe de MemberName, définie ci-dessus.
value encoded_value valeur de l'élément

Syntaxe des chaînes

Un fichier .dex contient plusieurs types d'éléments qui font référence à une chaîne. Les définitions de style BNF suivantes indiquent la syntaxe acceptable pour ces chaînes.

SimpleName

Un SimpleName constitue la base de la syntaxe des noms d'autres éléments. Le format .dex offre une grande marge de manœuvre (bien plus que la plupart des langues sources courantes). En bref, un nom simple se compose de n'importe quel caractère alphabétique ou chiffre ASCII en minuscules, de quelques symboles ASCII en minuscules spécifiques et de la plupart des points de code non ASCII qui ne sont pas des caractères de contrôle, des espaces ou des caractères spéciaux. À partir de la version 040, le format autorise également les caractères d'espacement (catégorie Unicode Zs). Notez que les points de code de substitution (dans la plage U+d800 … U+dfff) ne sont pas considérés comme des caractères de nom valides en soi, mais que les caractères Unicode supplémentaires sont valides (ils sont représentés par l'alternative finale de la règle pour SimpleNameChar) et doivent être représentés dans un fichier sous forme de paires de points de code de substitution dans l'encodage MUTF-8.

SimpleName →
SimpleNameChar (SimpleNameChar)*
SimpleNameChar →
'A' … 'Z'
| 'a' … 'z'
| '0' … '9'
| ' ' depuis la version 040 de DEX
| '$'
| '-'
| '_'
| U+00a0 depuis la version 040 de DEX
| U+00a1 … U+1fff
| U+2000 … U+200a depuis la version 040 de DEX
| U+2010 … U+2027
| U+202f depuis la version 040 de DEX
| U+2030 … U+d7ff
| U+e000 … U+ffef
| U+10000 … U+10ffff

MemberName

utilisé par field_id_item et method_id_item

Un MemberName est le nom d'un membre d'une classe, les membres étant des champs, des méthodes et des classes internes.

MemberName →
SimpleName
| '<' SimpleName '>'

FullClassName

Un FullClassName est un nom de classe complet, y compris un spécificateur de package facultatif suivi d'un nom obligatoire.

FullClassName →
OptionalPackagePrefix SimpleName
OptionalPackagePrefix →
(SimpleName '/')*

TypeDescriptor

Utilisé par type_id_item

Un TypeDescriptor est la représentation de n'importe quel type, y compris les primitives, les classes, les tableaux et void. Vous trouverez ci-dessous la signification des différentes versions.

TypeDescriptor →
'V'
| FieldTypeDescriptor
FieldTypeDescriptor →
NonArrayFieldTypeDescriptor
| ('[' * 1…255) NonArrayFieldTypeDescriptor
NonArrayFieldTypeDescriptor
'Z'
| 'B'
| 'S'
| 'C'
| 'I'
| 'J'
| 'F'
| 'D'
| 'L' FullClassName ';'

ShortyDescriptor

Utilisé par proto_id_item

Un ShortyDescriptor est la représentation abrégée d'un prototype de méthode, y compris les types de retour et de paramètre, à l'exception du fait qu'il n'y a pas de distinction entre les différents types de référence (classe ou tableau). Au lieu de cela, tous les types de référence sont représentés par un seul caractère 'L'.

ShortyDescriptor →
ShortyReturnType (ShortyFieldType)*
ShortyReturnType →
'V'
| ShortyFieldType
ShortyFieldType
'Z'
| 'B'
| 'S'
| 'C'
| 'I'
| 'J'
| 'F'
| 'D'
| 'L'

Sémantique de TypeDescriptor

Voici la signification de chacune des variantes de TypeDescriptor.

Syntaxe Signification
V void ; valide uniquement pour les types de retour
Z boolean
B byte
S short
C char
I int
J long
F float
D double
Lfully/qualified/Name; la classe fully.qualified.Name
[descriptor Tableau de descriptor, utilisable de manière récursive pour les tableaux de tableaux, bien qu'il ne soit pas valide d'avoir plus de 255 dimensions.

Éléments et structures associées

Cette section inclut des définitions pour chacun des éléments de premier niveau qui peuvent apparaître dans un fichier .dex.

header_item

Apparaît dans la section d'en-tête

Alignement : 4 octets

Nom Format Description
magique ubyte[8] = DEX_FILE_MAGIC valeur magique. Pour en savoir plus, consultez la section "DEX_FILE_MAGIC" ci-dessus.
somme de contrôle uint Somme de contrôle Adler32 du reste du fichier (tout sauf magic et ce champ). Elle permet de détecter la corruption du fichier.
signature ubyte[20] Signature SHA-1 (hachage) du reste du fichier (tout sauf magic, checksum et ce champ) ; utilisée pour identifier de manière unique les fichiers
file_size uint

Taille de l'intégralité du fichier (y compris l'en-tête), en octets (v40 ou version antérieure)

Distance en octets entre le début de cet en-tête et l'en-tête suivant ou la fin du fichier entier (le conteneur). (v41 ou version ultérieure)

header_size uint

Taille de l'en-tête (toute cette section), en octets. Cela permet au moins une compatibilité limitée en amont/en aval sans invalider le format.

doit être de 0x70 (112) octets (v40 ou version antérieure)

doit être de 0x78 (120) octets (v41 ou version ultérieure)

endian_tag uint = ENDIAN_CONSTANT tag endianness. Pour en savoir plus, consultez la section "ENDIAN_CONSTANT et REVERSE_ENDIAN_CONSTANT" ci-dessus.
link_size uint Taille de la section de lien ou 0 si ce fichier n'est pas lié statiquement
link_off uint Décalage depuis le début du fichier jusqu'à la section de liens, ou 0 si link_size == 0. Si le décalage n'est pas nul, il doit correspondre à un décalage dans la section link_data. Le format des données pointées n'est pas spécifié dans ce document. Ce champ d'en-tête (et le précédent) sont laissés en tant que hooks pour être utilisés par les implémentations d'exécution.
map_off uint Décalage depuis le début du fichier jusqu'à l'élément de carte. Le décalage, qui doit être non nul, doit être un décalage dans la section data, et les données doivent être au format spécifié par "map_list" ci-dessous.
string_ids_size uint Nombre de chaînes dans la liste des identifiants de chaîne
string_ids_off uint décalage du début du fichier à la liste des identifiants de chaîne, ou 0 si string_ids_size == 0 (cas limite étrange, il faut l'admettre). Si le décalage n'est pas nul, il doit être défini au début de la section string_ids.
type_ids_size uint Nombre d'éléments dans la liste des identifiants de type (65 535 au maximum)
type_ids_off uint décalage du début du fichier à la liste des identifiants de type, ou 0 si type_ids_size == 0 (cas limite étrange, il faut l'admettre). Si le décalage n'est pas nul, il doit être défini au début de la section type_ids.
proto_ids_size uint Nombre d'éléments dans la liste des identifiants de prototype (65 535 au maximum)
proto_ids_off uint décalage du début du fichier à la liste des identifiants de prototype, ou 0 si proto_ids_size == 0 (cas limite étrange, il faut l'admettre). Si le décalage n'est pas nul, il doit être défini au début de la section proto_ids.
field_ids_size uint Nombre d'éléments dans la liste des identifiants de champ
field_ids_off uint Décalage par rapport au début du fichier jusqu'à la liste des identifiants de champ, ou 0 si field_ids_size == 0. Si le décalage n'est pas nul, il doit être défini au début de la section field_ids.
method_ids_size uint Nombre d'éléments dans la liste des identifiants de méthode
method_ids_off uint Décalage du début du fichier à la liste des identifiants de méthode, ou 0 si method_ids_size == 0. Si le décalage n'est pas nul, il doit être défini au début de la section method_ids.
class_defs_size uint Nombre d'éléments dans la liste des définitions de classe
class_defs_off uint décalage du début du fichier à la liste des définitions de classe, ou 0 si class_defs_size == 0 (cas limite étrange, il faut l'admettre). Si le décalage n'est pas nul, il doit être défini au début de la section class_defs.
data_size uint

Taille de la section data en octets. Doit être un multiple pair de sizeof(uint). (v40 ou version antérieure)

Non utilisé (v41 ou version ultérieure)

data_off uint

Décalage entre le début du fichier et le début de la section data (v40 ou version antérieure)

Non utilisé (v41 ou version ultérieure)

container_size uint

Ce champ n'existe pas. Elle peut être considérée comme égale à file_size. (v40 ou version antérieure)

Taille de l'intégralité du fichier (y compris les autres en-têtes dex et leurs données). (v41 ou version ultérieure)

header_offset uint

Ce champ n'existe pas. Elle peut être considérée comme égale à 0. (v40 ou version antérieure)

Décalage entre le début du fichier et le début de cet en-tête. (v41 ou version ultérieure)

map_list

Apparaît dans la section "Données"

Référencé à partir de header_item

Alignement : 4 octets

Il s'agit d'une liste de l'intégralité du contenu d'un fichier, dans l'ordre. Il contient une certaine redondance par rapport à header_item, mais est conçu pour être un formulaire facile à utiliser pour parcourir un fichier entier. Un type donné ne doit apparaître qu'une seule fois dans une carte, mais il n'y a aucune restriction sur l'ordre dans lequel les types peuvent apparaître, à l'exception des restrictions impliquées par le reste du format (par exemple, une section header doit apparaître en premier, suivie d'une section string_ids, etc.). De plus, les entrées de la carte doivent être ordonnées par décalage initial et ne doivent pas se chevaucher.

Nom Format Description
taille uint Taille de la liste, en entrées
liste map_item[size] éléments de la liste

Format map_item

Nom Format Description
type ushort Type des articles (voir le tableau ci-dessous)
unused ushort (non utilisé)
taille uint Nombre d'éléments à trouver au décalage indiqué
compensés en carbone uint Décalage depuis le début du fichier jusqu'aux éléments en question

Codes de type

Type d'article Constante Valeur Taille de l'élément en octets
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
map_list TYPE_MAP_LIST 0x1000 4 + (item.size * 12)
type_list 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)
class_data_item TYPE_CLASS_DATA_ITEM 0x2000 implicit; must parse
code_item TYPE_CODE_ITEM 0x2001 implicit; must parse
string_data_item TYPE_STRING_DATA_ITEM 0x2002 implicit; must parse
debug_info_item TYPE_DEBUG_INFO_ITEM 0x2003 implicit; must parse
annotation_item TYPE_ANNOTATION_ITEM 0x2004 implicit; must parse
encoded_array_item TYPE_ENCODED_ARRAY_ITEM 0x2005 implicit; must parse
annotations_directory_item TYPE_ANNOTATIONS_DIRECTORY_ITEM 0x2006 implicit; must parse
hiddenapi_class_data_item TYPE_HIDDENAPI_CLASS_DATA_ITEM 0xF000 implicit; must parse

string_id_item

Apparaît dans la section string_ids

Alignement : 4 octets

Nom Format Description
string_data_off uint Décalage entre le début du fichier et les données de chaîne pour cet élément. Le décalage doit correspondre à un emplacement dans la section data, et les données doivent être au format spécifié par "string_data_item" ci-dessous. Aucune exigence d'alignement n'est requise pour le décalage.

string_data_item

Apparaît dans la section "Données"

Alignement : aucun (alignement sur les octets)

Nom Format Description
utf16_size uleb128 Taille de cette chaîne, en unités de code UTF-16 (qui correspond à la "longueur de la chaîne" dans de nombreux systèmes). Autrement dit, il s'agit de la longueur décodée de la chaîne. (La longueur encodée est implicite en fonction de la position de l'octet 0.)
de données ubyte[] une série d'unités de code MUTF-8 (également appelées octets ou bytes) suivie d'un octet de valeur 0. Pour en savoir plus sur le format des données, consultez la section "Encodage MUTF-8 (UTF-8 modifié)" ci-dessus.

Remarque : Il est acceptable d'avoir une chaîne qui inclut (la forme encodée de) des unités de code de substitution UTF-16 (c'est-à-dire U+d800 … U+dfff), soit de manière isolée, soit dans le désordre par rapport à l'encodage habituel d'Unicode en UTF-16. Il appartient aux utilisations de niveau supérieur des chaînes de refuser ces encodages non valides, le cas échéant.

type_id_item

Apparaît dans la section "type_ids"

Alignement : 4 octets

Nom Format Description
descriptor_idx uint index dans la liste string_ids pour la chaîne de descripteur de ce type. La chaîne doit être conforme à la syntaxe de TypeDescriptor, définie ci-dessus.

proto_id_item

Apparaît dans la section proto_ids

Alignement : 4 octets

Nom Format Description
shorty_idx uint Index dans la liste string_ids pour la chaîne de description courte de ce prototype. La chaîne doit respecter la syntaxe de ShortyDescriptor, définie ci-dessus, et doit correspondre au type renvoyé et aux paramètres de cet élément.
return_type_idx uint index dans la liste type_ids pour le type renvoyé de ce prototype
parameters_off uint Décalage depuis le début du fichier jusqu'à la liste des types de paramètres pour ce prototype, ou 0 si ce prototype ne comporte aucun paramètre. Si ce décalage est non nul, il doit figurer dans la section data, et les données doivent être au format spécifié par "type_list" ci-dessous. De plus, la liste ne doit pas faire référence au type void.

field_id_item

Apparaît dans la section "field_ids"

Alignement : 4 octets

Nom Format Description
class_idx ushort index dans la liste type_ids pour le définisseur de ce champ. Il doit s'agir d'un type de classe, et non d'un type primitif ou d'un tableau.
type_idx ushort Index dans la liste type_ids pour le type de ce champ
name_idx uint Index dans la liste string_ids pour le nom de ce champ. La chaîne doit être conforme à la syntaxe de MemberName, définie ci-dessus.

method_id_item

Apparaît dans la section "method_ids"

Alignement : 4 octets

Nom Format Description
class_idx ushort Index dans la liste type_ids pour le définisseur de cette méthode. Il doit s'agir d'un type de classe ou de tableau, et non d'un type primitif.
proto_idx ushort Index dans la liste proto_ids pour le prototype de cette méthode
name_idx uint index dans la liste string_ids pour le nom de cette méthode. La chaîne doit être conforme à la syntaxe de MemberName, définie ci-dessus.

class_def_item

Apparaît dans la section "class_defs"

Alignement : 4 octets

Nom Format Description
class_idx uint index dans la liste type_ids pour cette classe. Il doit s'agir d'un type de classe, et non d'un type primitif ou d'un tableau.
access_flags uint Indicateurs d'accès pour la classe (public, final, etc.). Pour en savoir plus, consultez "Définitions de access_flags".
superclass_idx uint index dans la liste type_ids pour la super-classe, ou la valeur constante NO_INDEX si cette classe n'a pas de super-classe (c'est-à-dire qu'il s'agit d'une classe racine telle que Object). Si elle est présente, il doit s'agir d'un type de classe, et non d'un tableau ou d'un type primitif.
interfaces_off uint Décalage du début du fichier par rapport à la liste des interfaces, ou 0 s'il n'y en a pas. Ce décalage doit figurer dans la section data, et les données doivent être au format spécifié par "type_list" ci-dessous. Chacun des éléments de la liste doit être un type de classe (et non un tableau ni un type primitif), et il ne doit pas y avoir de doublons.
source_file_idx uint index dans la liste string_ids pour le nom du fichier contenant la source d'origine (au moins la plupart) de cette classe, ou la valeur spéciale NO_INDEX pour représenter l'absence de cette information. Le debug_info_item d'une méthode donnée peut remplacer ce fichier source, mais la plupart des classes ne devraient provenir que d'un seul fichier source.
annotations_off uint Décalage du début du fichier à la structure des annotations pour cette classe, ou 0 s'il n'y a pas d'annotations sur cette classe. Si ce décalage est non nul, il doit figurer dans la section data. Les données doivent y être au format spécifié par "annotations_directory_item" ci-dessous, avec tous les éléments faisant référence à cette classe en tant que définisseur.
class_data_off uint Décalage depuis le début du fichier jusqu'aux données de classe associées à cet élément, ou 0 s'il n'y a pas de données de classe pour cette classe. (Cela peut être le cas, par exemple, si cette classe est une interface de marqueur.) Si le décalage est non nul, il doit figurer dans la section data. Les données doivent y être au format spécifié par "class_data_item" ci-dessous, avec tous les éléments faisant référence à cette classe comme définisseur.
static_values_off uint Décalage par rapport au début du fichier vers la liste des valeurs initiales pour les champs static, ou 0 s'il n'y en a pas (et que tous les champs static doivent être initialisés avec 0 ou null). Ce décalage doit se trouver dans la section data, et les données doivent y être au format spécifié par "encoded_array_item" ci-dessous. La taille du tableau ne doit pas dépasser le nombre de champs static déclarés par cette classe, et les éléments correspondent aux champs static dans le même ordre que celui déclaré dans le field_list correspondant. Le type de chaque élément de tableau doit correspondre au type déclaré de son champ correspondant. S'il y a moins d'éléments dans le tableau que de champs static, les champs restants sont initialisés avec un 0 ou un null approprié au type.

call_site_id_item

Apparaît dans la section "call_site_ids"

Alignement : 4 octets

Nom Format Description
call_site_off uint Décalage par rapport au début du fichier pour appeler la définition du site. Le décalage doit figurer dans la section de données, et les données doivent être au format spécifié par "call_site_item" ci-dessous.

call_site_item

Apparaît dans la section "Données"

Alignement : aucun (alignement sur les octets)

call_site_item est un encoded_array_item dont les éléments correspondent aux arguments fournis à une méthode de l'éditeur de liens bootstrap. Les trois premiers arguments sont les suivants :

  1. Handle de méthode représentant la méthode de liaison du bootstrap (VALUE_METHOD_HANDLE).
  2. Nom de méthode que le bootstrap linker doit résoudre (VALUE_STRING).
  3. Type de méthode correspondant au type du nom de méthode à résoudre (VALUE_METHOD_TYPE).

Tous les arguments supplémentaires sont des valeurs constantes transmises à la méthode de l'éditeur de liens de bootstrap. Ces arguments sont transmis dans l'ordre et sans aucune conversion de type.

Le handle de méthode représentant la méthode de l'éditeur de liens d'amorçage doit avoir le type de retour java.lang.invoke.CallSite. Voici les trois premiers types de paramètres :

  1. java.lang.invoke.Lookup
  2. java.lang.String
  3. java.lang.invoke.MethodType

Les types de paramètres des arguments supplémentaires sont déterminés à partir de leurs valeurs constantes.

method_handle_item

Apparaît dans la section "method_handles"

Alignement : 4 octets

Nom Format Description
method_handle_type ushort type du handle de méthode (voir le tableau ci-dessous)
unused ushort (non utilisé)
field_or_method_id ushort ID de champ ou de méthode selon que le type de handle de méthode est un accesseur ou un appelant de méthode
unused ushort (non utilisé)

Codes de type de handle de méthode

Constante Valeur Description
METHOD_HANDLE_TYPE_STATIC_PUT 0x00 Le handle de méthode est un setter (accesseur) de champ statique.
METHOD_HANDLE_TYPE_STATIC_GET 0x01 Le handle de méthode est un getter (accesseur) de champ statique.
METHOD_HANDLE_TYPE_INSTANCE_PUT 0x02 Le handle de méthode est un setter (accesseur) de champ d'instance.
METHOD_HANDLE_TYPE_INSTANCE_GET 0x03 Le handle de méthode est un getter (accesseur) de champ d'instance.
METHOD_HANDLE_TYPE_INVOKE_STATIC 0x04 Le handle de méthode est un appelant de méthode statique.
METHOD_HANDLE_TYPE_INVOKE_INSTANCE 0x05 Le handle de méthode est un appelant de méthode d'instance
METHOD_HANDLE_TYPE_INVOKE_CONSTRUCTOR 0x06 Un handle de méthode est un appelant de méthode de constructeur.
METHOD_HANDLE_TYPE_INVOKE_DIRECT 0x07 Le handle de méthode est un appelant de méthode directe
METHOD_HANDLE_TYPE_INVOKE_INTERFACE 0x08 Un handle de méthode est un appelant de méthode d'interface.

class_data_item

Référencé depuis class_def_item

Apparaît dans la section "Données"

Alignement : aucun (alignement sur les octets)

Nom Format Description
static_fields_size uleb128 Nombre de champs statiques définis dans cet élément
instance_fields_size uleb128 le nombre de champs d'instance définis dans cet élément ;
direct_methods_size uleb128 le nombre de méthodes directes définies dans cet élément ;
virtual_methods_size uleb128 nombre de méthodes virtuelles définies dans cet élément
static_fields encoded_field[static_fields_size] les champs statiques définis, représentés sous la forme d'une séquence d'éléments encodés. Les champs doivent être triés par field_idx dans l'ordre croissant.
instance_fields encoded_field[instance_fields_size] les champs d'instance définis, représentés sous la forme d'une séquence d'éléments encodés. Les champs doivent être triés par field_idx dans l'ordre croissant.
direct_methods encoded_method[direct_methods_size] les méthodes directes définies (static, private ou constructeur), représentées sous la forme d'une séquence d'éléments encodés. Les méthodes doivent être triées par method_idx dans l'ordre croissant.
virtual_methods encoded_method[virtual_methods_size] les méthodes virtuelles définies (aucune des méthodes static, private ou constructeur), représentées sous la forme d'une séquence d'éléments encodés. Cette liste ne doit pas inclure les méthodes héritées, sauf si elles sont remplacées par la classe que cet élément représente. Les méthodes doivent être triées par method_idx dans l'ordre croissant. Le method_idx d'une méthode virtuelle ne doit pas être identique à celui d'une méthode directe.

Remarque : Toutes les instances field_id et method_id des éléments doivent faire référence à la même classe de définition.

Format de encoded_field

Nom Format Description
field_idx_diff uleb128 Index dans la liste field_ids pour l'identité de ce champ (y compris le nom et le descripteur), représenté comme une différence par rapport à l'index de l'élément précédent de la liste. L'index du premier élément d'une liste est représenté directement.
access_flags uleb128 Indicateurs d'accès au champ (public, final, etc.). Pour en savoir plus, consultez "Définitions de access_flags".

Format de encoded_method

Nom Format Description
method_idx_diff uleb128 Index dans la liste method_ids pour l'identité de cette méthode (y compris le nom et le descripteur), représenté comme une différence par rapport à l'index de l'élément précédent de la liste. L'index du premier élément d'une liste est représenté directement.
access_flags uleb128 Indicateurs d'accès pour la méthode (public, final, etc.). Pour en savoir plus, consultez "Définitions de access_flags".
code_off uleb128 Décalage du début du fichier à la structure du code pour cette méthode, ou 0 si cette méthode est abstract ou native. Le décalage doit être défini sur un emplacement de la section data. Le format des données est spécifié par "code_item" ci-dessous.

type_list

Référencé à partir de class_def_item et proto_id_item

Apparaît dans la section "Données"

Alignement : 4 octets

Nom Format Description
taille uint Taille de la liste, en entrées
liste type_item[size] éléments de la liste

Format type_item

Nom Format Description
type_idx ushort index dans la liste type_ids

code_item

Référencé à partir de encoded_method

Apparaît dans la section "Données"

Alignement : 4 octets

Nom Format Description
registers_size ushort le nombre de registres utilisés par ce code ;
ins_size ushort Nombre de mots des arguments entrants de la méthode à laquelle ce code est destiné.
outs_size ushort Nombre de mots de l'espace d'arguments sortants requis par ce code pour l'appel de méthode
tries_size ushort le nombre de try_item pour cette instance. Si la valeur est différente de zéro, ces valeurs apparaissent sous forme de tableau tries juste après insns dans cette instance.
debug_info_off uint Décalage du début du fichier à la séquence d'informations de débogage (numéros de ligne + informations sur les variables locales) pour ce code, ou 0 s'il n'y a tout simplement aucune information. Si le décalage n'est pas nul, il doit correspondre à un emplacement dans la section data. Le format des données est spécifié par "debug_info_item" ci-dessous.
insns_size uint Taille de la liste d'instructions, en unités de code de 16 bits
insns ushort[insns_size] tableau réel de bytecode. Le format du code dans un tableau insns est spécifié dans le document associé Bytecode Dalvik. Notez que, bien que cela soit défini comme un tableau de ushort, certaines structures internes préfèrent l'alignement sur quatre octets. De plus, si cela se produit dans un fichier dont l'endianness a été inversée, l'inversion n'est effectuée que sur les instances ushort individuelles et non sur les structures internes plus grandes.
padding ushort (facultatif) = 0 deux octets de marge intérieure pour que tries soit aligné sur quatre octets. Cet élément n'est présent que si tries_size est différent de zéro et si insns_size est impair.
essaie try_item[tries_size] (facultatif) Tableau indiquant où les exceptions sont détectées dans le code et comment les gérer. Les éléments du tableau ne doivent pas se chevaucher en termes de plage et doivent être classés par ordre croissant d'adresses. Cet élément n'est présent que si tries_size est différent de zéro.
gestionnaires encoded_catch_handler_list (facultatif) Octets représentant une liste de listes de types de capture et d'adresses de gestionnaires associés. Chaque try_item possède un décalage en octets dans cette structure. Cet élément n'est présent que si tries_size est différent de zéro.

Format try_item

Nom Format Description
start_addr uint Adresse de début du bloc de code couvert par cette entrée. L'adresse correspond à un nombre d'unités de code de 16 bits jusqu'au début de la première instruction couverte.
insn_count ushort Nombre d'unités de code de 16 bits couvertes par cette entrée. La dernière unité de code couverte (incluse) est start_addr + insn_count - 1.
handler_off ushort Décalage en octets entre le début du encoded_catch_hander_list associé et le encoded_catch_handler pour cette entrée. Il doit s'agir d'un décalage par rapport au début d'un encoded_catch_handler.

Format de encoded_catch_handler_list

Nom Format Description
taille uleb128 Taille de cette liste, en nombre d'entrées
liste encoded_catch_handler[handlers_size] Liste réelle des listes de gestionnaires, représentée directement (et non sous forme de décalages) et concaténée séquentiellement

Format de encoded_catch_handler

Nom Format Description
taille sleb128 Nombre de types de capture dans cette liste. Si la valeur n'est pas positive, il s'agit de l'opposé du nombre de types de capture, et les captures sont suivies d'un gestionnaire général. Par exemple, une valeur size de 0 signifie qu'il existe une clause catch-all, mais pas de clauses catch explicitement typées. Une valeur 2 de 2 signifie qu'il existe deux captures de type explicite et aucune capture générique.size Un size de -1 signifie qu'il existe une capture typée ainsi qu'une capture générique.
gestionnaires encoded_type_addr_pair[abs(size)] Flux d'éléments encodés abs(size), un pour chaque type détecté, dans l'ordre dans lequel les types doivent être testés.
catch_all_addr uleb128 (facultatif) Adresse du bytecode du gestionnaire catch-all. Cet élément n'est présent que si size est non positif.

Format de encoded_type_addr_pair

Nom Format Description
type_idx uleb128 index dans la liste type_ids pour le type d'exception à intercepter.
addr uleb128 Adresse du code octet du gestionnaire d'exceptions associé

debug_info_item

Référencé à partir de code_item

Apparaît dans la section "Données"

Alignement : aucun (alignement sur les octets)

Chaque debug_info_item définit une machine à états codée en octets inspirée de DWARF3 qui, une fois interprétée, émet la table des positions et (potentiellement) les informations sur les variables locales pour un code_item. La séquence commence par un en-tête de longueur variable (dont la longueur dépend du nombre de paramètres de méthode), est suivie des bytecodes de la machine à états et se termine par un octet DBG_END_SEQUENCE.

La machine à états se compose de cinq registres. Le registre address représente le décalage d'instruction dans le insns_item associé en unités de code 16 bits. Le registre address commence à 0 au début de chaque séquence debug_info et ne doit augmenter que de manière monotone. Le registre line représente le numéro de ligne source qui doit être associé à la prochaine entrée de table des positions émise par la machine à états. Il est initialisé dans l'en-tête de séquence et peut changer dans le sens positif ou négatif, mais ne doit jamais être inférieur à 1. Le registre source_file représente le fichier source auquel font référence les entrées de numéro de ligne. Elle est initialisée sur la valeur de source_file_idx dans class_def_item. Les deux autres variables, prologue_end et epilogue_begin, sont des indicateurs booléens (initialisés sur false) qui indiquent si la prochaine position émise doit être considérée comme un prologue ou un épilogue de méthode. La machine à états doit également suivre le nom et le type de la dernière variable locale en direct dans chaque registre pour le code DBG_RESTART_LOCAL.

L'en-tête est le suivant :

Nom Format Description
line_start uleb128 Valeur initiale du registre line de la machine à états. Ne représente pas une entrée de position réelle.
parameters_size uleb128 Nombre de noms de paramètres encodés. Il doit y en avoir un par paramètre de méthode, à l'exclusion de this d'une méthode d'instance, le cas échéant.
parameter_names uleb128p1[parameters_size] Index de chaîne du nom du paramètre de méthode. Une valeur encodée de NO_INDEX indique qu'aucun nom n'est disponible pour le paramètre associé. Le descripteur et la signature de type sont implicites à partir du descripteur et de la signature de méthode.

Les valeurs de code d'octet sont les suivantes :

Nom Valeur Format Arguments Description
DBG_END_SEQUENCE 0x00 (aucun) met fin à une séquence d'informations de débogage pour un code_item.
DBG_ADVANCE_PC 0x01 uleb128 addr_diff addr_diff : montant à ajouter au registre d'adresses fait progresser le registre d'adresses sans émettre d'entrée de position.
DBG_ADVANCE_LINE 0x02 sleb128 line_diff line_diff : montant de la modification du registre des lignes avance le registre de ligne sans émettre d'entrée de position.
DBG_START_LOCAL 0x03 uleb128 register_num
uleb128p1 name_idx
uleb128p1 type_idx
register_num : registre qui contiendra local
name_idx : index de chaîne du nom
type_idx : index de type du type
introduit une variable locale à l'adresse actuelle. name_idx ou type_idx peuvent être NO_INDEX pour indiquer que cette valeur est inconnue.
DBG_START_LOCAL_EXTENDED 0x04 uleb128 register_num
uleb128p1 name_idx
uleb128p1 type_idx
uleb128p1 sig_idx
register_num : registre qui contiendra local
name_idx : index de chaîne du nom
type_idx : index de type du type
sig_idx : index de chaîne de la signature de type
introduit un local avec une signature de type à l'adresse actuelle. Les valeurs name_idx, type_idx ou sig_idx peuvent être NO_INDEX pour indiquer que la valeur est inconnue. (Si sig_idx est -1, les mêmes données peuvent être représentées plus efficacement à l'aide du code d'opération DBG_START_LOCAL.)

Remarque : Pour connaître les mises en garde concernant la gestion des signatures, consultez la discussion sous "dalvik.annotation.Signature" ci-dessous.

DBG_END_LOCAL 0x05 uleb128 register_num register_num : registre contenant des informations locales. marque une variable locale actuellement active comme hors champ d'application à l'adresse actuelle.
DBG_RESTART_LOCAL 0x06 uleb128 register_num register_num : s'inscrire pour redémarrer réintroduit une variable locale à l'adresse actuelle. Le nom et le type sont identiques à ceux de la dernière variable locale active dans le registre spécifié.
DBG_SET_PROLOGUE_END 0x07 (aucun) définit le registre de la machine à états prologue_end, en indiquant que la prochaine entrée de position ajoutée doit être considérée comme la fin d'un prologue de méthode (un emplacement approprié pour un point d'arrêt de méthode). Le registre prologue_end est effacé par n'importe quel opcode spécial (>= 0x0a).
DBG_SET_EPILOGUE_BEGIN 0x08 (aucun) définit le registre de la machine à états epilogue_begin, indiquant que la prochaine entrée de position ajoutée doit être considérée comme le début d'un épilogue de méthode (un emplacement approprié pour suspendre l'exécution avant la sortie de la méthode). Le registre epilogue_begin est effacé par n'importe quel opcode spécial (>= 0x0a).
DBG_SET_FILE 0x09 uleb128p1 name_idx name_idx : index de chaîne du nom de fichier source ; NO_INDEX si inconnu indique que toutes les entrées de numéro de ligne suivantes font référence à ce nom de fichier source, au lieu du nom par défaut spécifié dans code_item.
Codes d'opération spéciaux 0x0a…0xff (aucun) fait progresser les registres line et address, émet une entrée de position et efface prologue_end et epilogue_begin. Voir la description ci-dessous.

Codes d'opération spéciaux

Les codes d'opération dont les valeurs sont comprises entre 0x0a et 0xff (inclus) déplacent légèrement les registres line et address, puis émettent une nouvelle entrée dans la table des positions. La formule pour les incréments est la suivante :

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

Référencé depuis class_def_item

Apparaît dans la section "Données"

Alignement : 4 octets

Nom Format Description
class_annotations_off uint décalage par rapport au début du fichier pour les annotations effectuées directement sur la classe, ou 0 si la classe ne comporte aucune annotation directe. Si le décalage n'est pas nul, il doit correspondre à un emplacement dans la section data. Le format des données est spécifié par "annotation_set_item" ci-dessous.
fields_size uint Nombre de champs annotés par cet élément
annotated_methods_size uint Nombre de méthodes annotées par cet élément
annotated_parameters_size uint Nombre de listes de paramètres de méthode annotées par cet élément
field_annotations field_annotation[fields_size] (facultatif) Liste des annotations de champ associées. Les éléments de la liste doivent être triés par ordre croissant, par field_idx.
method_annotations method_annotation[methods_size] (facultatif) Liste des annotations de méthode associées. Les éléments de la liste doivent être triés par ordre croissant, par method_idx.
parameter_annotations parameter_annotation[parameters_size] (facultatif) Liste des annotations de paramètres de méthode associées. Les éléments de la liste doivent être triés par ordre croissant, par method_idx.

Remarque : Toutes les instances field_id et method_id des éléments doivent faire référence à la même classe de définition.

Format de field_annotation

Nom Format Description
field_idx uint index dans la liste field_ids pour l'identité du champ annoté.
annotations_off uint Décalage entre le début du fichier et la liste des annotations pour le champ. Le décalage doit être associé à un emplacement dans la section data. Le format des données est spécifié par "annotation_set_item" ci-dessous.

Format de method_annotation

Nom Format Description
method_idx uint Index dans la liste method_ids pour l'identité de la méthode annotée
annotations_off uint Décalage du début du fichier à la liste des annotations pour la méthode. Le décalage doit être défini sur un emplacement de la section data. Le format des données est spécifié par "annotation_set_item" ci-dessous.

Format de parameter_annotation

Nom Format Description
method_idx uint index dans la liste method_ids pour l'identité de la méthode dont les paramètres sont annotés
annotations_off uint Décalage entre le début du fichier et la liste des annotations pour les paramètres de la méthode. Le décalage doit être défini sur un emplacement de la section data. Le format des données est spécifié par "annotation_set_ref_list" ci-dessous.

annotation_set_ref_list

Référencé à partir de parameter_annotations_item

Apparaît dans la section "Données"

Alignement : 4 octets

Nom Format Description
taille uint Taille de la liste, en entrées
liste annotation_set_ref_item[size] éléments de la liste

Format annotation_set_ref_item

Nom Format Description
annotations_off uint Décalage par rapport au début du fichier jusqu'à l'ensemble d'annotations référencé ou 0 s'il n'y a pas d'annotations pour cet élément. Si le décalage n'est pas nul, il doit correspondre à un emplacement dans la section data. Le format des données est spécifié par "annotation_set_item" ci-dessous.

annotation_set_item

Référencé à partir de annotations_directory_item, field_annotations_item, method_annotations_item et annotation_set_ref_item

Apparaît dans la section "Données"

Alignement : 4 octets

Nom Format Description
taille uint Taille de l'ensemble, en entrées
participations annotation_off_item[size] éléments de l'ensemble. Les éléments doivent être triés par ordre croissant, par type_idx.

Format annotation_off_item

Nom Format Description
annotation_off uint décalage du début du fichier à une annotation. Le décalage doit correspondre à un emplacement dans la section data, et le format des données à cet emplacement est spécifié par "annotation_item" ci-dessous.

annotation_item

Référencé à partir de annotation_set_item

Apparaît dans la section "Données"

Alignement : aucun (alignement sur les octets)

Nom Format Description
visibilité ubyte Visibilité prévue de cette annotation (voir ci-dessous)
annotation encoded_annotation Contenu des annotations encodé, au format décrit par "encoded_annotation format" sous "encoded_value encoding" ci-dessus.

Valeurs de visibilité

Voici les options du champ visibility dans un annotation_item :

Nom Valeur Description
VISIBILITY_BUILD 0x00 ne sont censés être visibles qu'au moment de la compilation (par exemple, lors de la compilation d'un autre code).
VISIBILITY_RUNTIME 0x01 destinés à être visibles au moment de l'exécution
VISIBILITY_SYSTEM 0x02 destiné à être visible lors de l'exécution, mais uniquement par le système sous-jacent (et non par le code utilisateur normal)

encoded_array_item

Référencé depuis class_def_item

Apparaît dans la section "Données"

Alignement : aucun (alignement sur les octets)

Nom Format Description
value encoded_array octets représentant la valeur du tableau encodé, au format spécifié par "Format encoded_array" sous "Encodage encoded_value" ci-dessus.

hiddenapi_class_data_item

Cette section contient des données sur les interfaces restreintes utilisées par chaque classe.

Remarque : La fonctionnalité d'API masquée a été introduite dans Android 10.0 et ne s'applique qu'aux fichiers DEX des classes dans le chemin de classe de démarrage. La liste des indicateurs décrits ci-dessous pourra être étendue dans les futures versions d'Android. Pour en savoir plus, consultez les restrictions concernant les interfaces non SDK.

Nom Format Description
taille uint taille totale de la section
compensations uint[] Tableau de décalages indexé par class_idx. Une entrée de tableau nulle à l'index class_idx signifie qu'il n'y a pas de données pour ce class_idx ou que tous les indicateurs d'API masqués sont nuls. Sinon, l'entrée du tableau est non nulle et contient un décalage du début de la section vers un tableau d'indicateurs d'API masqués pour ce class_idx.
indicateurs uleb128[] Tableaux concaténés des indicateurs d'API masqués pour chaque classe. Les valeurs de signalement possibles sont décrites dans le tableau ci-dessous. Les indicateurs sont encodés dans le même ordre que les champs et les méthodes sont encodés dans les données de classe.

Types de signalements de restriction :

Nom Valeur Description
liste blanche 0 Interfaces pouvant être utilisées librement et prises en charge dans l'index des packages du framework Android officiellement documenté.
liste grise 1 Interfaces non SDK qui peuvent être utilisées quel que soit le niveau d'API cible de l'application.
ajouter à la liste noire 2 Interfaces non SDK qui ne peuvent pas être utilisées quel que soit le niveau d'API cible de l'application. L'accès à l'une de ces interfaces entraîne une erreur d'exécution.
greylist‑max‑o 3 Interfaces non SDK qui peuvent être utilisées pour Android 8.x et versions antérieures, sauf si elles sont restreintes.
greylist‑max‑p 4 Interfaces non SDK qui peuvent être utilisées pour Android 9.x, sauf si elles sont restreintes.
greylist‑max‑q 5 Interfaces non SDK qui peuvent être utilisées pour Android 10.x, sauf si elles sont restreintes.
greylist‑max‑r 6 Interfaces non SDK qui peuvent être utilisées pour Android 11.x, sauf si elles sont restreintes.

Annotations système

Les annotations système sont utilisées pour représenter diverses informations réflexives sur les classes (ainsi que les méthodes et les champs). Ces informations ne sont généralement accessibles qu'indirectement par le code client (non système).

Les annotations système sont représentées dans les fichiers .dex en tant qu'annotations dont la visibilité est définie sur VISIBILITY_SYSTEM.

dalvik.annotation.AnnotationDefault

Apparaît sur les méthodes dans les interfaces d'annotation

Une annotation AnnotationDefault est associée à chaque interface d'annotation qui souhaite indiquer des liaisons par défaut.

Nom Format Description
value Annotation Liaisons par défaut pour cette annotation, représentées sous la forme d'une annotation de ce type. L'annotation n'a pas besoin d'inclure tous les noms définis par l'annotation. Les noms manquants n'ont tout simplement pas de valeurs par défaut.

dalvik.annotation.EnclosingClass

S'affiche dans les cours

Une annotation EnclosingClass est associée à chaque classe qui est définie en tant que membre d'une autre classe, en soi, ou qui est anonyme, mais pas définie dans le corps d'une méthode (par exemple, une classe interne synthétique). Chaque classe comportant cette annotation doit également comporter une annotation InnerClass. De plus, une classe ne doit pas comporter à la fois une annotation EnclosingClass et une annotation EnclosingMethod.

Nom Format Description
value Classe la classe qui englobe le plus étroitement cette classe au niveau lexical.

dalvik.annotation.EnclosingMethod

S'affiche dans les cours

Une annotation EnclosingMethod est associée à chaque classe définie dans le corps d'une méthode. Chaque classe comportant cette annotation doit également comporter une annotation InnerClass. De plus, une classe ne doit pas comporter à la fois une annotation EnclosingClass et une annotation EnclosingMethod.

Nom Format Description
value Méthode la méthode qui délimite le plus précisément cette classe au niveau lexical.

dalvik.annotation.InnerClass

S'affiche dans les cours

Une annotation InnerClass est associée à chaque classe définie dans le champ d'application lexical de la définition d'une autre classe. Toute classe comportant cette annotation doit également comporter soit une annotation EnclosingClass, soit une annotation EnclosingMethod.

Nom Format Description
nom Chaîne Nom simple initialement déclaré de cette classe (sans préfixe de package). Si cette classe est anonyme, le nom est null.
accessFlags int les indicateurs d'accès initialement déclarés de la classe (qui peuvent différer des indicateurs effectifs en raison d'une incompatibilité entre les modèles d'exécution du langage source et de la machine virtuelle cible)

dalvik.annotation.MemberClasses

S'affiche dans les cours

Une annotation MemberClasses est associée à chaque classe qui déclare les classes membres. (Une classe membre est une classe interne directe qui possède un nom.)

Nom Format Description
value Classe[] Tableau des classes de membres

dalvik.annotation.MethodParameters

Apparaît sur les méthodes

Remarque : Cette annotation a été ajoutée après Android 7.1. Sa présence sur les versions antérieures d'Android sera ignorée.

Une annotation MethodParameters est facultative et peut être utilisée pour fournir des métadonnées de paramètre telles que les noms et les modificateurs de paramètre.

L'annotation peut être omise d'une méthode ou d'un constructeur sans risque lorsque les métadonnées de paramètre ne sont pas requises au moment de l'exécution. java.lang.reflect.Parameter.isNamePresent() peut être utilisé pour vérifier si des métadonnées sont présentes pour un paramètre. Les méthodes de réflexion associées, telles que java.lang.reflect.Parameter.getName(), reviendront au comportement par défaut au moment de l'exécution si les informations ne sont pas présentes.

Lorsque vous incluez des métadonnées de paramètres, les compilateurs doivent inclure des informations pour les classes générées telles que les énumérations, car les métadonnées de paramètres indiquent si un paramètre est synthétique ou obligatoire.

Une annotation MethodParameters ne décrit que les paramètres de méthode individuels. Par conséquent, les compilateurs peuvent omettre complètement l'annotation pour les constructeurs et les méthodes sans paramètre, dans un souci de taille du code et d'efficacité de l'exécution.

Les tableaux documentés ci-dessous doivent avoir la même taille que pour la structure dex method_id_item associée à la méthode. Dans le cas contraire, une java.lang.reflect.MalformedParametersException sera générée au moment de l'exécution.

Autrement dit, method_id_item.proto_idx -> proto_id_item.parameters_off -> type_list.size doit être identique à names().length et accessFlags().length.

Étant donné que MethodParameters décrit tous les paramètres de méthode formels, même ceux qui ne sont pas explicitement ou implicitement déclarés dans le code source, la taille des tableaux peut différer des informations de signature ou d'autres métadonnées qui ne sont basées que sur les paramètres explicites déclarés dans le code source. MethodParameters n'inclura pas non plus d'informations sur les paramètres de récepteur d'annotation de type qui n'existent pas dans la signature de méthode réelle.

Nom Format Description
noms String[] Noms des paramètres formels de la méthode associée. Le tableau ne doit pas être nul, mais doit être vide s'il n'y a pas de paramètres formels. Une valeur du tableau doit être nulle si le paramètre formel avec cet index n'a pas de nom.
Si les chaînes de nom de paramètre sont vides ou contiennent ".", ";", "[" ou "/", une java.lang.reflect.MalformedParametersException sera générée lors de l'exécution.
accessFlags int[] Indicateurs d'accès des paramètres formels de la méthode associée. Le tableau ne doit pas être nul, mais doit être vide s'il n'y a pas de paramètres formels.
La valeur est un masque de bits avec les valeurs suivantes :
  • 0x0010 : final, le paramètre a été déclaré final
  • 0x1000 : synthétique, le paramètre a été introduit par le compilateur
  • 0x8000 : obligatoire, le paramètre est synthétique, mais également implicite dans la spécification du langage
Si des bits sont définis en dehors de cet ensemble, une java.lang.reflect.MalformedParametersException sera générée au moment de l'exécution.

dalvik.annotation.Signature

Apparaît sur les classes, les champs et les méthodes

Une annotation Signature est associée à chaque classe, champ ou méthode définie en termes de type plus complexe que celui représentable par un type_id_item. Le format .dex ne définit pas le format des signatures. Il est simplement destiné à pouvoir représenter toutes les signatures dont une langue source a besoin pour implémenter correctement la sémantique de cette langue. Par conséquent, les signatures ne sont généralement pas analysées (ni vérifiées) par les implémentations de machines virtuelles. Les signatures sont simplement transmises à des API et des outils de niveau supérieur (tels que les débogueurs). Par conséquent, toute utilisation d'une signature doit être écrite de manière à ne faire aucune hypothèse sur la réception de signatures valides uniquement, en se protégeant explicitement contre la possibilité de rencontrer une signature syntaxiquement invalide.

Étant donné que les chaînes de signature ont tendance à contenir beaucoup de contenu en double, une annotation Signature est définie comme un tableau de chaînes, où les éléments en double font naturellement référence aux mêmes données sous-jacentes, et la signature est considérée comme la concaténation de toutes les chaînes du tableau. Il n'existe aucune règle concernant la manière de séparer une signature en chaînes distinctes. Cela dépend entièrement des outils qui génèrent les fichiers .dex.

Nom Format Description
value String[] Signature de cette classe ou de ce membre, sous la forme d'un tableau de chaînes à concaténer

dalvik.annotation.Throws

Apparaît sur les méthodes

Une annotation Throws est associée à chaque méthode déclarée pour générer un ou plusieurs types d'exception.

Nom Format Description
value Classe[] Tableau des types d'exception générés