Formato eseguibile Dalvik

Questo documento descrive il layout e i contenuti dei file .dex, che vengono utilizzati per contenere un insieme di definizioni di classi e i relativi dati aggiuntivi associati.

Guida ai tipi

Nome Descrizione
byte Numero intero a 8 bit firmato
ubyte Intero senza segno a 8 bit
video breve Intero a 16 bit con segno, little-endian
ushort Intero senza segno a 16 bit, little-endian
int Intero a 32 bit con segno, little-endian
uint Intero non firmato a 32 bit, little-endian
lunghi Numero intero a 64 bit con segno, little-endian
ulong Intero senza segno a 64 bit, little-endian
sleb128 LEB128 firmato, di lunghezza variabile (vedi di seguito)
uleb128 LEB128 non firmato, di lunghezza variabile (vedi di seguito)
uleb128p1 LEB128 non firmato più 1, di lunghezza variabile (vedi di seguito)

LEB128

LEB128 ("Little-Endian Base 128") è una codifica a lunghezza variabile per quantità intere con segno o senza segno arbitrarie. Il formato è stato mutuato dalla specifica DWARF3. In un file .dex, LEB128 viene utilizzato solo per codificare quantità a 32 bit.

Ogni valore con codifica LEB128 è composto da uno a cinque byte, che insieme rappresentano un singolo valore a 32 bit. Per ogni byte è impostato il bit più significativo, ad eccezione del byte finale nella sequenza, che ha il suo bit più significativo chiaro. I rimanenti sette bit di ogni byte sono il payload, con i sette bit meno significativi della quantità nel primo byte, i sette successivi nel secondo byte e così via. Nel caso di un LEB128 con segno (sleb128), il bit del payload più significativo del byte finale della sequenza viene esteso con segno per produrre il valore finale. Nel caso senza segno (uleb128), tutti i bit non rappresentati esplicitamente sono interpretati come 0.

Diagramma a livello di bit di un valore LEB128 di due byte
Primo byte Secondo byte
1 bit6 bit5 bit4 bit3 bit2 bit1 bit0 0 bit13 bit12 bit11 bit10 bit9 bit8 bit7

La variante uleb128p1 viene utilizzata per rappresentare un valore con segno, dove la rappresentazione è del valore più uno codificato come uleb128. In questo modo, la codifica di -1 (in alternativa, il valore non firmato 0xffffffff) - ma nessun altro numero negativo - è un singolo byte ed è utile esattamente nei casi in cui il numero rappresentato deve essere positivo o -1 (o 0xffffffff) e dove non sono consentiti altri valori negativi (o dove è improbabile che siano necessari valori non firmati di grandi dimensioni).

Ecco alcuni esempi di formati:

Sequenza codificata Come sleb128 Come uleb128 Come uleb128p1
0000-1
01110
7f-1127126
80 7f-1281625616255

Layout del file

Nome Formato Descrizione
intestazione header_item l'intestazione
string_ids string_id_item[] Elenco di identificatori di stringa. Si tratta di identificatori per tutte le stringhe utilizzate da questo file, sia per la denominazione interna (ad es. descrittori di tipo) sia come oggetti costanti a cui fa riferimento il codice. Questo elenco deve essere ordinato in base ai contenuti delle stringhe, utilizzando i valori dei punti di codice UTF-16 (non in modo sensibile alla lingua) e non deve contenere voci duplicate.
type_ids type_id_item[] Elenco di identificatori di tipo. Si tratta di identificatori per tutti i tipi (classi, آرایه o tipi primitivi) a cui fa riferimento questo file, definiti o meno nel file. Questo elenco deve essere ordinato in base all'indice string_id e non deve contenere voci duplicate.
proto_ids proto_id_item[] Elenco di identificatori di prototipi di metodi. Si tratta di identificatori per tutti i prototipi a cui fa riferimento questo file. Questo elenco deve essere ordinato in ordine di importanza per il tipo di ritorno (in base all'indice type_id) e poi per elenco di argomenti (ordine lessicografico, singoli argomenti ordinati in base all'indice type_id). L'elenco non deve contenere voci duplicate.
field_ids field_id_item[] elenco di identificatori di campo. Si tratta di identificatori per tutti i campi a cui fa riferimento questo file, indipendentemente dal fatto che siano definiti o meno nel file. Questo elenco deve essere ordinato, dove il tipo di definizione (in base all'indice type_id) è l'ordine principale, il nome del campo (in base all'indice string_id) è l'ordine intermedio e il tipo (in base all'indice type_id) è l'ordine secondario. L'elenco non deve contenere voci duplicate.
method_ids method_id_item[] Elenco di identificatori dei metodi. Si tratta di identificatori per tutti i metodi a cui fa riferimento questo file, indipendentemente dal fatto che siano definiti o meno nel file. Questo elenco deve essere ordinato, dove il tipo di definizione (in base all'indice type_id) è l'ordine principale, il nome del metodo (in base all'indice string_id) è l'ordine intermedio e il prototipo del metodo (in base all'indice proto_id) è l'ordine secondario. L'elenco non deve contenere voci duplicate.
class_defs class_def_item[] Elenco delle definizioni di classi. Le classi devono essere ordinate in modo che la superclasse e le interfacce implementate di una determinata classe vengano visualizzate nell'elenco prima della classe di riferimento. Inoltre, non è valida una definizione per un corso con lo stesso nome che appare più di una volta nell'elenco.
call_site_ids call_site_id_item[] elenco di identificatori dei siti di chiamata. Si tratta di identificatori per tutti i siti di chiamata a cui fa riferimento questo file, indipendentemente dal fatto che siano definiti o meno nel file. Questo elenco deve essere ordinato in ordine crescente di call_site_off.
method_handles method_handle_item[] Elenco dei handle dei metodi. Un elenco di tutti i handle dei metodi a cui fa riferimento questo file, indipendentemente dal fatto che siano definiti o meno nel file. Questo elenco non è ordinato e potrebbe contenere duplicati che corrisponderanno logicamente a istanze di handle dei metodi diverse.
di dati ubyte[] area di dati, contenente tutti i dati di supporto per le tabelle elencate sopra. Gli elementi diversi hanno requisiti di allineamento diversi e, se necessario, vengono inseriti byte di spaziatura prima di ogni elemento per ottenere un allineamento corretto.
link_data ubyte[] dati utilizzati nei file collegati in modo statico. Il formato dei dati in questa sezione non è specificato da questo documento. Questa sezione è vuota nei file scollegati e le implementazioni di runtime possono utilizzarla come meglio credono.

Formato del contenitore

La versione 41 introduce un nuovo formato contenitore per i dati DEX allo scopo di risparmiare spazio. Questo formato contenitore consente di combinare più file DEX logici in un unico file fisico. Il nuovo formato è per lo più una semplice concatenazione di file nel formato precedente, con alcune differenze:

  • file_size indica le dimensioni del file logico, non del file fisico. Può essere utilizzato per eseguire l'iterazione su tutti i file logici del contenitore.
  • I file dex logici possono fare riferimento a qualsiasi dato successivo nel contenitore (ma non a quelli precedenti). In questo modo, i file dex possono condividere dati, ad esempio stringhe, tra loro.
  • Tutti gli offset sono relativi al file fisico. Nessun offset è relativo all'intestazione. In questo modo, le sezioni con gli offset possono essere condivise tra i file logici.
  • L'intestazione aggiunge due nuovi campi per descrivere i limiti del contenitore. Si tratta di un controllo di coerenza aggiuntivo che semplifica il porting del codice al nuovo formato.
  • data_size e data_off non sono più utilizzati. I dati possono essere distribuiti su più file logici e non devono essere contigui.

Definizioni di campi di bit, stringhe e costanti

DEX_FILE_MAGIC

Incorporato in header_item

L'array/stringa costante DEX_FILE_MAGIC è l'elenco di byte che deve apparire all'inizio di un file .dex perché venga riconosciuto come tale. Il valore contiene intenzionalmente un a capo ("\n" o 0x0a) e un byte nullo ("\0" o 0x00) per contribuire al rilevamento di determinate forme di corruzione. Il valore codifica anche un numero di versione del formato sotto forma di tre cifre decimali, che dovrebbe aumentare in modo monotonico nel tempo con l'evoluzione del formato.

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

Nota: il supporto della versione 040 del formato è stato aggiunto nella release di Android 10.0, che ha esteso l'insieme di caratteri consentiti in SimpleNames.

Nota: il supporto della versione 039 del formato è stato aggiunto nella release di Android 9.0, che ha introdotto due nuovi bytecode, const-method-handle e const-method-type. Questi sono descritti nella tabella Riepilogo dell'insieme di bytecode. In Android 10, la versione 039 estende il formato del file DEX per includere informazioni sull'API nascoste applicabili solo ai file DEX nel percorso della classe di avvio.

Nota: il supporto della versione 038 del formato è stato aggiunto nella release di Android 8.0. La versione 038 ha aggiunto nuovi bytecode (invoke-polymorphic e invoke-custom) e dati per gli handle dei metodi.

Nota: il supporto della versione 037 del formato è stato aggiunto nella release di Android 7.0. Prima della versione 037, la maggior parte delle versioni di Android ha utilizzato la versione 035 del formato. L'unica differenza tra le versioni 035 e 037 è l' aggiunta di metodi predefiniti e la regolazione del invoke.

Nota:almeno un paio di versioni precedenti del formato sono state utilizzate nelle release software pubbliche ampiamente disponibili. Ad esempio, la versione 009 è stata utilizzata per le release M3 della piattaforma Android (novembre-dicembre 2007) e la versione 013 per le release M5 della piattaforma Android (febbraio-marzo 2008). Per diversi aspetti, queste versioni precedenti del formato differiscono notevolmente dalla versione descritta in questo documento.

ENDIAN_CONSTANT e REVERSE_ENDIAN_CONSTANT

Incorporato in header_item

La costante ENDIAN_CONSTANT viene utilizzata per indicare il endianness del file in cui si trova. Sebbene il formato.dex standard sia little-endian, le implementazioni possono scegliere di eseguire lo scambio di byte. Se un'implementazione trova un header il cui endian_tag è REVERSE_ENDIAN_CONSTANT invece di ENDIAN_CONSTANT, saprà che il file è stato sottoposto a byte-swapping rispetto al formato previsto.

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

NO_INDEX

Incorporato in class_def_item e debug_info_item

La costante NO_INDEX viene utilizzata per indicare che un valore dell'indice è assente.

Nota: questo valore non è definito come 0, perché in genere è un indice valido.

Il valore scelto per NO_INDEX è rappresentabile come un singolo byte nella codifica uleb128p1.

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

Definizioni di access_flags

Incorporato in class_def_item, encoded_field, encoded_method e InnerClass

I campi di bit di questi flag vengono utilizzati per indicare l'accessibilità e le proprietà complessive di classi e membri di classe.

Nome Valore Per i corsi (e le annotazioni InnerClass) Per i campi Per i metodi
ACC_PUBLIC 0x1 public: visibile ovunque public: visibile ovunque public: visibile ovunque
ACC_PRIVATE 0x2 * private: visibile solo alla classe di definizione private: visibile solo alla classe di definizione private: visibile solo alla classe di definizione
ACC_PROTECTED 0x4 * protected: visibile al pacchetto e alle sottoclassi protected: visibile al pacchetto e alle sottoclassi protected: visibile al pacchetto e alle sottoclassi
ACC_STATIC 0x8 * static: non è costruito con un riferimento this esterno static: globale per la classe di definizione static: non accetta un argomento this
ACC_FINAL 0x10 final: non può essere sottoclassificato final: immutabile dopo la creazione final: non sostituibile
ACC_SYNCHRONIZED 0x20     synchronized: blocco associato acquisito automaticamente intorno alla chiamata a questo metodo.

Nota:questa impostazione è valida solo se è impostato anche ACC_NATIVE.

ACC_VOLATILE 0x40   volatile: regole di accesso speciale per contribuire alla sicurezza del thread  
ACC_BRIDGE 0x40     metodo bridge, aggiunto automaticamente dal compilatore come bridge sicuro per i tipi
ACC_TRANSIENT 0x80   transient: non deve essere salvato per la serializzazione predefinita  
ACC_VARARGS 0x80     L'ultimo argomento deve essere considerato un argomento "rimanente" dal compilatore
ACC_NATIVE 0x100     native: implementato in codice nativo
ACC_INTERFACE 0x200 interface: classe astratta implementabile più volte    
ACC_ABSTRACT 0x400 abstract: non può essere istanziato direttamente   abstract: non implementato da questa classe
ACC_STRICT 0x800     strictfp: regole rigorose per l'aritmetica a virgola mobile
ACC_SYNTHETIC 0x1000 non definito direttamente nel codice sorgente non definito direttamente nel codice sorgente non definito direttamente nel codice sorgente
ACC_ANNOTATION 0x2000 dichiarato come classe di annotazione    
ACC_ENUM 0x4000 dichiarato come tipo enumerato dichiarato come valore enumerato  
(non utilizzato) 0x8000      
ACC_CONSTRUCTOR 0x10000     metodo costruttore (inizializzatore di classe o istanza)
ACC_DECLARED_
SYNCHRONIZED
0x20000     dichiarato synchronized.

Nota:questo non influisce sull'esecuzione (tranne che per la riflessione di questo flag).

* Consentito solo per le annotazioni InnerClass e non deve mai essere attivo in un class_def_item.

Codifica UTF-8 modificata

Per semplificare il supporto della versione precedente, il formato .dex codifica i dati di stringa in un formato UTF-8 modificato standard de facto, di seguito denominato MUTF-8. Questo formato è identico all'UTF-8 standard, tranne che per quanto segue:

  • Vengono utilizzate solo le codifiche di uno, due e tre byte.
  • I punti di codice nell'intervallo U+10000U+10ffff vengono codificati come coppia di surrogati, ciascuno rappresentato come valore codificato di tre byte.
  • Il punto di codice U+0000 è codificato in formato a due byte.
  • Un byte nullo normale (valore 0) indica la fine di una stringa, come nell'interpretazione standard del linguaggio C.

I primi due punti sopra riportati possono essere riassunti come segue: MUTF-8 è un formato di codifica per UTF-16, anziché un formato di codifica più diretto per i caratteri Unicode.

Gli ultimi due elementi sopra riportati consentono contemporaneamente di includere il punto di codice U+0000 in una stringa e di manipolarlo come stringa terminata da nullo in stile C.

Tuttavia, la codifica speciale di U+0000 significa che, a differenza del normale UTF-8, il risultato dell'chiamata della funzione C standard strcmp() su una coppia di stringhe MUTF-8 non sempre indica il risultato correttamente firmato del confronto di stringhe non uguali. Quando l'ordinamento (non solo l'uguaglianza) è un problema, il modo più semplice per confrontare le stringhe UTF-8 è decodificarle carattere per carattere e confrontare i valori decodificati. Tuttavia, sono possibili anche implementazioni più intelligenti.

Per ulteriori informazioni sulla codifica dei caratteri, consulta lo standard Unicode. MUTF-8 è in realtà più simile alla codifica (relativamente meno nota) CESU-8 rispetto a UTF-8 per se.

Codifica di encoded_value

Incorporato in annotation_element e encoded_array_item

Un encoded_value è un frammento codificato di dati (quasi) arbitrari strutturati in modo gerarchico. La codifica deve essere compatta e facile da analizzare.

Nome Formato Descrizione
(value_arg << 5) | value_type ubyte byte che indica il tipo di value immediatamente successivo insieme a un argomento facoltativo di chiarimento nei tre bit di ordine superiore. Di seguito sono riportate le varie definizioni di value. Nella maggior parte dei casi, value_arg codifica la lunghezza del value immediatamente successivo in byte, come (size - 1), ad esempio 0 indica che il valore richiede un byte e 7 indica che richiede otto byte. Tuttavia, esistono delle eccezioni, come indicato di seguito.
valore ubyte[] byte che rappresentano il valore, di lunghezza variabile e interpretati diversamente per byte value_type diversi, anche se sempre in little-endian. Per maggiori dettagli, consulta le varie definizioni di valore riportate di seguito.

Formati dei valori

Nome tipo value_type Formato value_arg Formato value Descrizione
VALUE_BYTE 0x00 (nessuno; deve essere 0) ubyte[1] valore intero con segno di un byte
VALUE_SHORT 0x02 size - 1 (0…1) ubyte[size] valore intero a due byte con segno, con estensione del segno
VALUE_CHAR 0x03 size - 1 (0…1) ubyte[size] Valore intero senza segno di due byte, esteso a zero
VALUE_INT 0x04 size - 1 (0…3) ubyte[size] valore intero a quattro byte con segno, con estensione del segno
VALUE_LONG 0x06 size - 1 (0…7) ubyte[size] valore intero a 8 byte con segno, con estensione del segno
VALUE_FLOAT 0x10 size - 1 (0…3) ubyte[size] pattern di bit di quattro byte, esteso a zero a destra e interpretato come valore in virgola mobile a 32 bit IEEE754
VALUE_DOUBLE 0x11 size - 1 (0…7) ubyte[size] pattern di bit di otto byte, esteso a zero a destra e interpretato come valore in virgola mobile a 64 bit IEEE754
VALUE_METHOD_TYPE 0x15 size - 1 (0…3) ubyte[size] Valore intero a quattro byte non firmato (con estensione a zero), interpretato come indice della sezione proto_ids e che rappresenta un valore di tipo di metodo
VALUE_METHOD_HANDLE 0x16 size - 1 (0…3) ubyte[size] Valore intero a quattro byte non firmato (con estensione a zero), interpretato come indice della sezione method_handles e che rappresenta un valore handle metodo
VALUE_STRING 0x17 size - 1 (0…3) ubyte[size] Valore intero a quattro byte non firmato (con estensione a zero), interpretato come indice della sezione string_ids e che rappresenta un valore di stringa
VALUE_TYPE 0x18 size - 1 (0…3) ubyte[size] Valore intero a quattro byte non firmato (con estensione a zero), interpretato come indice della sezione type_ids e che rappresenta un valore di tipo/classe riflettente
VALUE_FIELD 0x19 size - 1 (0…3) ubyte[size] Valore intero a quattro byte non firmato (con estensione a zero), interpretato come indice della sezione field_ids e che rappresenta un valore di campo riflettente
VALUE_METHOD 0x1a size - 1 (0…3) ubyte[size] Valore intero a quattro byte non firmato (con estensione a zero), interpretato come indice della sezione method_ids e che rappresenta un valore del metodo riflessivo
VALUE_ENUM 0x1b size - 1 (0…3) ubyte[size] Valore intero a quattro byte non firmato (con estensione a zero), interpretato come indice della sezione field_ids e che rappresenta il valore di una costante di tipo enumerato
ARRAY_VALORI 0x1c (nessuno; deve essere 0) array_codificato un array di valori nel formato specificato da "Formato encoded_array" di seguito. Le dimensioni dell'value sono implicite nella codifica.
VALUE_ANNOTATION 0x1d (nessuno; deve essere 0) encoded_annotation una sottoannotazione, nel formato specificato da "Formato encoded_annotation" di seguito. Le dimensioni dell'value sono implicite nella codifica.
VALUE_NULL 0x1e (nessuno; deve essere 0) (none) Valore di riferimento null
VALUE_BOOLEAN 0x1f booleano (0…1) (none) Valore di un bit: 0 per false e 1 per true. Il bit è rappresentato in value_arg.

Formato dell'array codificato

Nome Formato Descrizione
dimensioni uleb128 numero di elementi nell'array
valori encoded_value[size] una serie di sequenze di byte size encoded_value nel formato specificato da questa sezione, concatenate in sequenza.

Formato dell'annotazione codificata

Nome Formato Descrizione
type_idx uleb128 del tipo di annotazione. Deve essere un tipo di classe (non array o primitivo).
dimensioni uleb128 numero di mappature nome-valore in questa annotazione
elementi annotation_element[size] elementi dell'annotazione, rappresentati direttamente in linea (non come offset). Gli elementi devono essere ordinati in ordine crescente in base all'indice string_id.

formato dell'elemento annotation_element

Nome Formato Descrizione
name_idx uleb128 elemento, rappresentato come indice della sezione string_ids. La stringa deve essere conforme alla sintassi di MemberName, definita sopra.
valore valore_codificato valore dell'elemento

Sintassi delle stringhe

In un file .dex esistono diversi tipi di elementi che fanno tutti riferimento a una stringa. Le seguenti definizioni in stile BNF indicano la sintassi accettabile per queste stringhe.

NomeSemplice

Un SimpleName è la base per la sintassi dei nomi di altre cose. Il formato .dex consente una certa libertà in questo senso (molto più delle lingue di origine più comuni). In breve, un nome semplice è costituito da qualsiasi carattere alfabetico o cifra ASCII basso, da alcuni simboli ASCII bassi specifici e dalla maggior parte dei punti di codice non ASCII che non sono caratteri di controllo, spazi o speciali. A partire dalla versione 040 il formato consente inoltre i caratteri di spaziatura (categoria Unicode Zs). Tieni presente che i punti di codice surrogato (nell'intervallo U+d800U+dfff) non sono considerati caratteri di nome validi, in quanto tali, ma i caratteri supplementari Unicode sono validi (rappresentati dall'alternativa finale della regola per SimpleNameChar) e devono essere rappresentati in un file come coppie di punti di codice surrogato nella codifica MUTF-8.

SimpleName
SimpleNameChar (SimpleNameChar)*
SimpleNameChar
'A''Z'
| 'a''z'
| '0''9'
| ' ' a partire dalla versione DEX 040
| '$'
| '-'
| '_'
| U+00a0 a partire dalla versione DEX 040
| U+00a1U+1fff
| U+2000U+200a a partire dalla versione DEX 040
| U+2010U+2027
| U+202f a partire dalla versione DEX 040
| U+2030U+d7ff
| U+e000U+ffef
| U+10000U+10ffff

MemberName

utilizzato da field_id_item e method_id_item

Un MemberName è il nome di un membro di una classe, ovvero campi, metodi e classi interne.

MemberName
SimpleName
| '<' NomeSemplice '>'

FullClassName

Un FullClassName è un nome di classe completo, che include un specificatore del pacchetto facoltativo seguito da un nome obbligatorio.

FullClassName
OptionalPackagePrefix SimpleName
OptionalPackagePrefix
(SimpleName '/')*

TypeDescriptor

Utilizzato da type_id_item

Un TypeDescriptor è la rappresentazione di qualsiasi tipo, inclusi elementi primitivi, classi, array e void. Di seguito è riportato il significato delle varie versioni.

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

ShortyDescriptor

Utilizzato da proto_id_item

Un ShortyDescriptor è la rappresentazione in forma breve di un prototipo di metodo, inclusi i tipi di ritorno e parametro, tranne per il fatto che non viene fatta alcuna distinzione tra i vari tipi di riferimento (classe o array). Invece, tutti i tipi di riferimento sono rappresentati da un singolo carattere 'L'.

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

Semantica di TypeDescriptor

Questo è il significato di ciascuna delle varianti di TypeDescriptor.

Sintassi Significato
V void; valido solo per i tipi di reso
Z boolean
B byte
S short
C char
I int
J long
F float
D double
Lnome/completo/; il corso fully.qualified.Name
[descriptor array di descriptor, utilizzabile in modo ricorsivo per array di array, anche se non è valido avere più di 255 dimensioni.

Elementi e strutture correlate

Questa sezione include le definizioni di ciascuno degli elementi di primo livello che possono comparire in un file .dex.

header_item

Viene visualizzato nella sezione dell'intestazione

Allineamento: 4 byte

Nome Formato Descrizione
magia ubyte[8] = DEX_FILE_MAGIC valore magico. Per ulteriori dettagli, consulta la sezione "DEX_FILE_MAGIC" sopra.
checksum uint checksum adler32 del resto del file (tutto tranne magic e questo campo); utilizzato per rilevare la corruzione del file
firma ubyte[20] Firma (hash) SHA-1 del resto del file (tutto tranne magic, checksum e questo campo); utilizzata per identificare in modo univoco i file
file_size uint

dimensioni dell'intero file (inclusa l'intestazione), in byte (v40 o precedenti)

distanza in byte dall'inizio di questa intestazione all'intestazione successiva o alla fine dell'intero file (il contenitore). (v41 o successive)

header_size uint

dimensioni dell'intestazione (l'intera sezione), in byte. Ciò consente almeno una compatibilità limitata con le versioni precedenti/successive senza invalidare il formato.

Deve essere pari a 0x70 (112) byte (v40 o precedenti)

Deve essere pari a 0x78 (120) byte (v41 o successive)

endian_tag uint = ENDIAN_CONSTANT tag endianness. Per ulteriori dettagli, consulta la sezione "ENDIAN_CONSTANT e REVERSE_ENDIAN_CONSTANT" qui sopra.
link_size uint dimensioni della sezione del link o 0 se il file non è collegato staticamente
link_off uint offset dall'inizio del file alla sezione del link oppure 0 se link_size == 0. L'offset, se diverso da zero, deve fare riferimento a un offset nella sezione link_data. Il formato dei dati a cui si fa riferimento non è specificato in questo documento. Questo campo dell'intestazione (e quello precedente) vengono lasciati come hook per l'utilizzo da parte delle implementazioni di runtime.
map_off uint offset dall'inizio del file all'elemento mappa. L'offset, che deve essere diverso da zero, deve essere un offset nella sezione data e i dati devono essere nel formato specificato da "map_list" di seguito.
string_ids_size uint conteggio delle stringhe nell'elenco degli identificatori di stringa
string_ids_off uint offset dall'inizio del file all'elenco degli identificatori di stringa oppure 0 se string_ids_size == 0 (un caso limite strano). L'offset, se diverso da zero, deve essere all'inizio della sezione string_ids.
type_ids_size uint numero di elementi nell'elenco degli identificatori di tipo, massimo 65535
type_ids_off uint offset dall'inizio del file all'elenco degli identificatori di tipo oppure 0 se type_ids_size == 0 (ovviamente un caso limite strano). L'offset, se diverso da zero, deve essere all'inizio della sezione type_ids.
proto_ids_size uint numero di elementi nell'elenco degli identificatori del prototipo, massimo 65535
proto_ids_off uint offset dall'inizio del file all'elenco degli identificatori del prototipo oppure 0 se proto_ids_size == 0 (un caso limite strano). L'offset, se diverso da zero, deve essere all'inizio della sezione proto_ids.
field_ids_size uint conteggio degli elementi nell'elenco degli identificatori di campo
field_ids_off uint offset dall'inizio del file all'elenco degli identificatori di campo oppure 0 se field_ids_size == 0. L'offset, se diverso da zero, deve essere all'inizio della sezione field_ids.
method_ids_size uint conteggio degli elementi nell'elenco degli identificatori di metodi
method_ids_off uint offset dall'inizio del file all'elenco degli identificatori dei metodi oppure 0 se method_ids_size == 0. L'offset, se diverso da zero, deve essere all'inizio della sezione method_ids.
class_defs_size uint conteggio degli elementi nell'elenco delle definizioni di classe
class_defs_off uint offset dall'inizio del file all'elenco delle definizioni di classe oppure 0 se class_defs_size == 0 (ovviamente un caso limite strano). L'offset, se diverso da zero, deve essere all'inizio della sezione class_defs.
data_size uint

Dimensioni della sezione data in byte. Deve essere un multiplo pari di sizeof(uint). (v40 o versioni precedenti)

Non utilizzato (v41 o versioni successive)

data_off uint

offset dall'inizio del file all'inizio della sezione data (v40 o precedenti)

Non utilizzato (v41 o versioni successive)

container_size uint

Questo campo non esiste. Si può presumere che sia uguale a file_size. (v40 o versioni precedenti)

la dimensione dell'intero file (incluse altre intestazioni dex e i relativi dati). (v41 o successive)

header_offset uint

Questo campo non esiste. Si può presumere che sia uguale a 0. (v40 o versioni precedenti)

dall'inizio del file all'inizio di questa intestazione. (v41 o successive)

map_list

Viene visualizzato nella sezione Dati

Riferimento da header_item

Allineamento: 4 byte

Si tratta di un elenco in ordine di tutti i contenuti di un file. Contiene alcune ridondanze rispetto a header_item, ma è pensato per essere un modulo facile da utilizzare per eseguire l'iterazione su un intero file. Un determinato tipo deve apparire al massimo una volta in una mappa, ma non esistono limitazioni sui tipi di ordini che possono essere visualizzati, ad eccezione delle limitazioni implicite nel resto del formato (ad es. deve apparire prima una sezione header, seguita da una sezione string_ids e così via). Inoltre, le voci della mappa devono essere ordinate in base all'offset iniziale e non devono sovrapporsi.

Nome Formato Descrizione
dimensioni uint dimensioni dell'elenco, in voci
lista map_item[size] elementi dell'elenco

formato map_item

Nome Formato Descrizione
digita ushort tipo di articoli; vedi la tabella di seguito
unused ushort (non utilizzato)
dimensioni uint conteggio del numero di elementi da trovare nell'offset indicato
offset uint l'offset dall'inizio del file agli elementi in questione

Digita i codici

Tipo di elemento Costante Valore Dimensioni elemento in byte
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

Viene visualizzato nella sezione string_ids

Allineamento: 4 byte

Nome Formato Descrizione
string_data_off uint dall'inizio del file ai dati di stringa per questo elemento. L'offset deve fare riferimento a una posizione nella sezione data e i dati devono essere nel formato specificato da "string_data_item" di seguito. Non è richiesto alcun allineamento per l'offset.

string_data_item

Viene visualizzato nella sezione Dati

Allineamento: nessuno (allineato a byte)

Nome Formato Descrizione
utf16_size uleb128 la dimensione di questa stringa, in unità di codice UTF-16 (ovvero la "lunghezza della stringa" in molti sistemi). ovvero la lunghezza decodificata della stringa. La lunghezza codificata è implicita dalla posizione del byte 0.
di dati ubyte[] una serie di unità di codice MUTF-8 (noti anche come ottetti o byte) followed by a byte of value 0. Consulta la sezione "Codifica MUTF-8 (UTF-8 modificato)" sopra per informazioni dettagliate e discussioni sul formato dei dati.

Nota: è accettabile avere una stringa che includa (la forma codificata di) unità di codice surrogate UTF-16 (ovvero U+d800U+dfff) isolate o fuori sequenza rispetto alla consueta codifica di Unicode in UTF-16. Spetta agli utilizzi di livello superiore delle stringhe rifiutare queste codifiche non valide, se opportuno.

type_id_item

Viene visualizzato nella sezione type_ids

Allineamento: 4 byte

Nome Formato Descrizione
descriptor_idx uint nell'elenco string_ids per la stringa del descrittore di questo tipo. La stringa deve essere conforme alla sintassi di TypeDescriptor, definita sopra.

proto_id_item

Viene visualizzato nella sezione proto_ids

Allineamento: 4 byte

Nome Formato Descrizione
shorty_idx uint indice nell'elenco string_ids per la stringa del descrittore in forma breve di questo prototipo. La stringa deve essere conforme alla sintassi di ShortyDescriptor, definita sopra, e deve corrispondere al tipo di ritorno e ai parametri di questo elemento.
return_type_idx uint indice nell'elenco type_ids per il tipo di ritorno di questo prototipo
parameters_off uint offset dall'inizio del file all'elenco dei tipi di parametri per questo prototipo oppure 0 se questo prototipo non ha parametri. Questo offset, se diverso da zero, deve trovarsi nella sezione data e i dati devono essere nel formato specificato da "type_list" di seguito. Inoltre, nell'elenco non deve essere presente alcun riferimento al tipo void.

field_id_item

Viene visualizzato nella sezione field_ids

Allineamento: 4 byte

Nome Formato Descrizione
class_idx ushort nell'elenco type_ids per il definitore di questo campo. Deve essere un tipo di classe e non un array o un tipo primitivo.
type_idx ushort indice nell'elenco type_ids per il tipo di questo campo
name_idx uint nell'elenco string_ids per il nome di questo campo. La stringa deve essere conforme alla sintassi di MemberName, definita sopra.

method_id_item

Viene visualizzato nella sezione method_ids

Allineamento: 4 byte

Nome Formato Descrizione
class_idx ushort indice nell'elenco type_ids per il definitore di questo metodo. Deve essere un tipo di classe o array e non un tipo primitivo.
proto_idx ushort indice nell'elenco proto_ids per il prototipo di questo metodo
name_idx uint nell'elenco string_ids per il nome di questo metodo. La stringa deve essere conforme alla sintassi di MemberName, definita sopra.

class_def_item

Viene visualizzato nella sezione class_defs

Allineamento: 4 byte

Nome Formato Descrizione
class_idx uint nell'elenco type_ids per questo corso. Deve essere un tipo di classe e non un array o un tipo primitivo.
access_flags uint flag di accesso per il corso (public, final ecc.). Per maggiori dettagli, consulta "access_flags Definizioni".
superclass_idx uint indice nell'elenco type_ids per la superclasse o il valore costante NO_INDEX se questa classe non ha superclasse (ovvero è una classe di primo livello come Object). Se presente, deve essere un tipo di classe e non un array o un tipo primitivo.
interfaces_off uint offset dall'inizio del file all'elenco delle interfacce o 0 se non ce ne sono. Questo offset deve essere nella sezione data e i dati devono essere nel formato specificato da "type_list" di seguito. Ciascun elemento dell'elenco deve essere un tipo di classe (non un array o un tipo primitivo) e non devono esserci duplicati.
source_file_idx uint l'indice nell'elenco string_ids per il nome del file contenente l'origine originale per (almeno la maggior parte di) questa classe, o il valore speciale NO_INDEX per rappresentare l'assenza di queste informazioni. Il debug_info_item di un determinato metodo può sostituire questo file di origine, ma si prevede che la maggior parte delle classi provenga da un solo file di origine.
annotations_off uint offset dall'inizio del file alla struttura delle annotazioni per questo corso oppure 0 se non sono presenti annotazioni per questo corso. Questo offset, se diverso da zero, deve trovarsi nella sezione data e i dati al suo interno devono essere nel formato specificato da "annotations_directory_item" di seguito, con tutti gli elementi che fanno riferimento a questa classe come definitore.
class_data_off uint offset dall'inizio del file ai dati del corso associati per questo elemento oppure 0 se non sono presenti dati del corso per questo corso. ad esempio se questa classe è un'interfaccia di indicatore. L'offset, se diverso da zero, deve trovarsi nella sezione data e i dati al suo interno devono essere nel formato specificato da "class_data_item" di seguito, con tutti gli elementi che fanno riferimento a questa classe come definitore.
static_values_off uint offset dall'inizio del file all'elenco dei valori iniziali per i campi static oppure 0 se non sono presenti (e tutti i campi static devono essere inizializzati con 0 o null). Questo offset deve trovarsi nella sezione data e i dati al suo interno devono essere nel formato specificato da "encoded_array_item" di seguito. La dimensione dell'array non deve essere superiore al numero di campi static dichiarati da questa classe e gli elementi devono corrispondere ai campi static nello stesso ordine dichiarato in field_list corrispondente. Il tipo di ogni elemento dell'array deve corrispondere al tipo dichiarato del campo corrispondente. Se nell'array sono presenti meno elementi rispetto ai campi static, i campi rimanenti vengono inizializzati con un 0 o un null appropriato per il tipo.

call_site_id_item

Viene visualizzato nella sezione call_site_ids

Allineamento: 4 byte

Nome Formato Descrizione
call_site_off uint offset dall'inizio del file per chiamare la definizione del sito. L'offset deve essere nella sezione dei dati e i dati devono essere nel formato specificato da "call_site_item" di seguito.

call_site_item

Viene visualizzato nella sezione Dati

Allineamento: nessuno (allineato a byte)

call_site_item è un elemento encoded_array_item i cui elementi corrispondono agli argomenti forniti a un metodo di linker di bootstrap. I primi tre argomenti sono:

  1. Un handle metodo che rappresenta il metodo del linker di bootstrap (VALUE_METHOD_HANDLE).
  2. Un nome di metodo che il linker di bootstrap deve risolvere (VALUE_STRING).
  3. Un tipo di metodo corrispondente al tipo del nome del metodo da risolvere (VALUE_METHOD_TYPE).

Eventuali argomenti aggiuntivi sono valori costanti passati al metodo del linker di bootstrap. Questi argomenti vengono passati in ordine e senza conversioni di tipo.

L'handle del metodo che rappresenta il metodo del linker di bootstrap deve avere il tipo di ritorno java.lang.invoke.CallSite. I primi tre tipi di parametri sono:

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

I tipi di parametro di eventuali argomenti aggiuntivi vengono determinati dai relativi valori costanti.

method_handle_item

Viene visualizzato nella sezione method_handles

Allineamento: 4 byte

Nome Formato Descrizione
method_handle_type ushort tipo di handle del metodo; vedi la tabella di seguito
unused ushort (non utilizzato)
field_or_method_id ushort ID campo o metodo a seconda che il tipo di handle del metodo sia un accessor o un invocatore di metodo
unused ushort (non utilizzato)

Codici tipo di handle metodo

Costante Valore Descrizione
METHOD_HANDLE_TYPE_STATIC_PUT 0x00 L'handle del metodo è un settatore di campo statico (accessore)
METHOD_HANDLE_TYPE_STATIC_GET 0x01 L'handle del metodo è un getter (accessore) di campo statico
METHOD_HANDLE_TYPE_INSTANCE_PUT 0x02 L'handle del metodo è un settatore del campo dell'istanza (accessore)
METHOD_HANDLE_TYPE_INSTANCE_GET 0x03 L'handle del metodo è un getter (accessore) del campo dell'istanza
METHOD_HANDLE_TYPE_INVOKE_STATIC 0x04 L'handle del metodo è un invocatore di metodo statico
METHOD_HANDLE_TYPE_INVOKE_INSTANCE 0x05 L'handle del metodo è un invocatore del metodo dell'istanza
METHOD_HANDLE_TYPE_INVOKE_CONSTRUCTOR 0x06 L'handle del metodo è un invocatore del metodo del costruttore
METHOD_HANDLE_TYPE_INVOKE_DIRECT 0x07 L'handle del metodo è un invocatore di metodo diretto
METHOD_HANDLE_TYPE_INVOKE_INTERFACE 0x08 L'handle del metodo è un invocatore del metodo dell'interfaccia

class_data_item

Riferimento da class_def_item

Viene visualizzato nella sezione Dati

Allineamento: nessuno (allineato a byte)

Nome Formato Descrizione
static_fields_size uleb128 il numero di campi statici definiti in questo elemento
instance_fields_size uleb128 il numero di campi istanza definiti in questo elemento
direct_methods_size uleb128 il numero di metodi diretti definiti in questo elemento
virtual_methods_size uleb128 il numero di metodi virtuali definiti in questo elemento
static_fields encoded_field[static_fields_size] I campi statici definiti, rappresentati come una sequenza di elementi codificati. I campi devono essere ordinati per field_idx in ordine crescente.
instance_fields encoded_field[instance_fields_size] I campi istanza definiti, rappresentati come una sequenza di elementi codificati. I campi devono essere ordinati per field_idx in ordine crescente.
direct_methods encoded_method[direct_methods_size] i metodi diretti (qualsiasi static, private o metodi del costruttore) definiti, rappresentati come una sequenza di elementi codificati. I metodi devono essere ordinati per method_idx in ordine crescente.
virtual_methods encoded_method[virtual_methods_size] I metodi virtuali (diversi da static, private o costruttore) definiti, rappresentati come una sequenza di elementi codificati. Questo elenco non deve includere metodi ereditati, a meno che non vengano sostituiti dalla classe rappresentata da questo elemento. I metodi devono essere ordinati per method_idx in ordine crescente. Il method_idx di un metodo virtuale non deve essere uguale a quello di qualsiasi metodo diretto.

Nota:tutte le istanze field_id e method_id degli elementi devono fare riferimento alla stessa classe di definizione.

Formato del campo encoded_field

Nome Formato Descrizione
field_idx_diff uleb128 indice nell'elenco field_ids per l'identità di questo campo (include il nome e il descrittore), rappresentato come differenza dall'indice dell'elemento precedente nell'elenco. L'indice del primo elemento di un elenco è rappresentato direttamente.
access_flags uleb128 flag di accesso per il campo (public, final ecc.). Per maggiori dettagli, consulta "access_flags Definizioni".

Formato di encoded_method

Nome Formato Descrizione
method_idx_diff uleb128 indice nell'elenco method_ids per l'identità di questo metodo (include il nome e il descrittore), rappresentato come differenza dall'indice dell'elemento precedente nell'elenco. L'indice del primo elemento di un elenco è rappresentato direttamente.
access_flags uleb128 flag di accesso per il metodo (public, final, ecc.). Per maggiori dettagli, consulta "access_flags Definizioni".
code_off uleb128 offset dall'inizio del file alla struttura di codice per questo metodo oppure 0 se questo metodo è abstract o native. L'offset deve fare riferimento a una posizione nella sezione data. Il formato dei dati è specificato da "code_item" di seguito.

type_list

A cui si fa riferimento da class_def_item e proto_id_item

Viene visualizzato nella sezione Dati

Allineamento: 4 byte

Nome Formato Descrizione
dimensioni uint dimensioni dell'elenco, in voci
lista type_item[size] elementi dell'elenco

Formato type_item

Nome Formato Descrizione
type_idx ushort indice nell'elenco type_ids

code_item

Riferimento da encoded_method

Viene visualizzato nella sezione Dati

Allineamento: 4 byte

Nome Formato Descrizione
registers_size ushort il numero di registri utilizzati da questo codice
ins_size ushort il numero di parole degli argomenti in entrata per il metodo a cui è destinato questo codice
outs_size ushort il numero di parole di spazio per gli argomenti in uscita richiesto da questo codice per l'invocazione del metodo
tries_size ushort il numero di try_item per questa istanza. Se diverso da zero, vengono visualizzati come array tries subito dopo il insns in questa istanza.
debug_info_off uint offset dall'inizio del file alla sequenza di informazioni di debug (numeri di riga + informazioni sulle variabili locali) per questo codice oppure 0 se non sono presenti informazioni. L'offset, se diverso da zero, deve essere associato a una posizione nella sezione data. Il formato dei dati è specificato da "debug_info_item" di seguito.
insns_size uint dimensioni dell'elenco di istruzioni, in unità di codice a 16 bit
insns ushort[insns_size] array effettivo di bytecode. Il formato del codice in un array insns è specificato dal documento aggiuntivo Bytecode Dalvik. Tieni presente che, anche se è definito come un array di ushort, esistono alcune strutture interne che preferiscono l'allineamento a quattro byte. Inoltre, se si tratta di un file con ordine di byte invertito, lo scambio viene eseguito solo sulle singole istanze ushort e non sulle strutture interne più grandi.
padding ushort (facoltativo) = 0 due byte di spaziatura per allineare tries a quattro byte. Questo elemento è presente solo se tries_size è diverso da zero e insns_size è dispari.
tentativi try_item[tries_size] (facoltativo) array che indica dove nel codice vengono rilevate le eccezioni e come gestirle. Gli elementi dell'array non devono sovrapporsi nell'intervallo e devono essere in ordine dall'indirizzo più basso a quello più alto. Questo elemento è presente solo se tries_size è diverso da zero.
gestori encoded_catch_handler_list (facoltativo) byte che rappresentano un elenco di elenchi di tipi di errori e indirizzi di gestori associati. Ogni try_item ha un offset in byte in questa struttura. Questo elemento è presente solo se tries_size è diverso da zero.

Formato di try_item

Nome Formato Descrizione
start_addr uint indirizzo iniziale del blocco di codice coperto da questa voce. L'indirizzo è un conteggio di unità di codice di 16 bit fino all'inizio della prima istruzione coperta.
insn_count ushort numero di unità di codice a 16 bit coperte da questa voce. L'ultima unità di codice coperta (inclusa) è start_addr + insn_count - 1.
handler_off ushort offset in byte dall'inizio del encoded_catch_hander_list al encoded_catch_handler per questa voce. Deve essere un offset rispetto all'inizio di un encoded_catch_handler.

formato encoded_catch_handler_list

Nome Formato Descrizione
dimensioni uleb128 dimensione di questo elenco, in voci
lista encoded_catch_handler[handlers_size] elenco effettivo degli elenchi di gestori, rappresentato direttamente (non come offset) e concatenato in sequenza

Formato di encoded_catch_handler

Nome Formato Descrizione
dimensioni sleb128 numero di tipi di catture in questo elenco. Se non è positivo, è uguale al numero negativo di tipi di eccezioni e queste sono seguite da un gestore generico. Ad esempio, un size di 0 indica che esiste una regola generica, ma non sono presenti regole con tipi espliciti. Un size di 2 indica che sono presenti due catture esplicitamente digitate e nessuna generica. Un size di -1 indica che esiste una regola di cattura digitata insieme a una regola generica.
gestori encoded_type_addr_pair[abs(size)] uno stream di elementi codificati abs(size), uno per ogni tipo rilevato, nell'ordine in cui devono essere testati i tipi.
catch_all_addr uleb128 (facoltativo) Indirizzo bytecode dell'handler catch-all. Questo elemento è presente solo se size non è positivo.

Formato della coppia di indirizzi di tipo codificati

Nome Formato Descrizione
type_idx uleb128 indice dell'elenco type_ids per il tipo di eccezione da gestire
addr uleb128 Indirizzo bytecode del gestore delle eccezioni associato

debug_info_item

Riferimento da code_item

Viene visualizzato nella sezione Dati

Allineamento: nessuno (allineato a byte)

Ogni debug_info_item definisce una macchina a stati con codifica in byte ispirata a DWARF3 che, quando viene interpretata, emette la tabella delle posizioni e (potenzialmente) le informazioni sulle variabili locali per un code_item. La sequenza inizia con un header di lunghezza variabile (la cui lunghezza dipende dal numero di parametri del metodo), seguita dai bytecode della macchina a stati e termina con un byte DBG_END_SEQUENCE.

La macchina a stati è composta da cinque registri. Il registrante address rappresenta l'offset dell'istruzione nel insns_item associato in unità di codice a 16 bit. Il registro address inizia da 0 all'inizio di ogni sequenza debug_info e deve aumentare solo in modo monotono. Il registro line rappresenta il numero di riga di origine che deve essere associato alla voce della tabella delle posizioni successive emessa dalla macchina a stati. Viene inizializzato nell'intestazione della sequenza e può cambiare in direzione positiva o negativa, ma non deve mai essere inferiore a 1. Il registro source_file rappresenta il file di origine a cui fanno riferimento le voci del numero di riga. Viene inizializzato con il valore di source_file_idx in class_def_item. Le altre due variabili, prologue_end e epilogue_begin, sono flag booleani (inizializzati a false) che indicano se la posizione successiva emessa deve essere considerata un prologo o un epilogo del metodo. La macchina a stati deve anche monitorare il nome e il tipo dell'ultima variabile locale attiva in ogni registro per il codice DBG_RESTART_LOCAL.

L'intestazione è la seguente:

Nome Formato Descrizione
line_start uleb128 il valore iniziale per il registro line della macchina a stati. Non rappresenta una voce di posizioni effettiva.
parameters_size uleb128 il numero di nomi di parametri codificati. Deve essercene uno per parametro di metodo, escluso this di un metodo di istanza, se presente.
parameter_names uleb128p1[parameters_size] indice di stringa del nome del parametro del metodo. Un valore codificato di NO_INDEX indica che non è disponibile alcun nome per il parametro associato. Il descrittore di tipo e la firma sono impliciti nel descrittore e nella firma del metodo.

I valori del codice a byte sono i seguenti:

Nome Valore Formato Argomenti Descrizione
DBG_END_SEQUENCE 0x00 (none) termina una sequenza di informazioni di debug per un code_item
DBG_ADVANCE_PC 0x01 uleb128 addr_diff addr_diff: importo da aggiungere al registro degli indirizzi avanza il registro degli indirizzi senza emettere una voce di posizione
DBG_ADVANCE_LINE 0x02 sleb128 line_diff line_diff: importo per cui modificare il registro riga avanza il registro riga senza emettere una voce di posizione
DBG_START_LOCAL 0x03 uleb128 register_num
uleb128p1 name_idx
uleb128p1 type_idx
register_num: registro che conterrà la variabile locale
name_idx: indice di stringa del nome
type_idx: indice di tipo del tipo
introduce una variabile locale nell'indirizzo corrente. Puoi scegliere tra name_idx o type_idx per indicare che il valore è sconosciuto.NO_INDEX
DBG_START_LOCAL_EXTENDED 0x04 uleb128 register_num
uleb128p1 name_idx
uleb128p1 type_idx
uleb128p1 sig_idx
register_num: registro che conterrà local
name_idx: indice di stringa del nome
type_idx: indice di tipo del tipo
sig_idx: indice di stringa della firma del tipo
introduce un locale con una firma di tipo nell'indirizzo corrente. Qualsiasi valore tra name_idx, type_idx o sig_idx può essere NO_INDEX per indicare che il valore è sconosciuto. Tuttavia, se sig_idx è -1, gli stessi dati potrebbero essere rappresentati in modo più efficiente utilizzando l'opcode DBG_START_LOCAL.

Nota: consulta la sezione "dalvik.annotation.Signature" di seguito per i limiti relativi alla gestione delle firme.

DBG_END_LOCAL 0x05 uleb128 register_num register_num: registro contenente il valore locale contrassegnare una variabile locale attualmente attiva come non nell'ambito all'indirizzo corrente
DBG_RESTART_LOCAL 0x06 uleb128 register_num register_num: registrazione per il riavvio re-introduces a local variable at the current address. Il nome e il tipo sono gli stessi dell'ultimo locale attivo nel registro specificato.
DBG_SET_PROLOGUE_END 0x07 (none) imposta il registro della macchina a stati prologue_end, indicando che la voce di posizione successiva aggiunta deve essere considerata la fine del prologo di un metodo (un punto appropriato per un breakpoint del metodo). Il registro prologue_end viene cleared da qualsiasi codice operativo speciale (>= 0x0a).
DBG_SET_EPILOGUE_BEGIN 0x08 (none) imposta il registro della macchina a stati epilogue_begin, indicando che la voce di posizione successiva aggiunta deve essere considerata l'inizio dell'epilogo di un metodo (un punto appropriato per sospendere l'esecuzione prima dell'uscita dal metodo). Il registro epilogue_begin viene cancellato da qualsiasi opcode (>= 0x0a) speciale.
DBG_SET_FILE 0x09 uleb128p1 name_idx name_idx: indice di stringa del nome del file di origine; NO_INDEX se sconosciuto indica che tutte le voci del numero di riga successive fanno riferimento a questo nome del file di origine, anziché al nome predefinito specificato in code_item
Opcode speciali 0x0a…0xff (none) avanza i registri line e address, emette una voce di posizione e azzera prologue_end e epilogue_begin. Vedi di seguito per una descrizione.

Opcode speciali

Gli opcode con valori compresi tra 0x0a e 0xff (inclusi) spostano entrambi i registri line e address di una piccola quantità e poi emettono una nuova voce della tabella delle posizioni. La formula per gli incrementi è la seguente:

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

Riferimento da class_def_item

Viene visualizzato nella sezione Dati

Allineamento: 4 byte

Nome Formato Descrizione
class_annotations_off uint offset dall'inizio del file alle annotazioni apportate direttamente al corso oppure 0 se il corso non contiene annotazioni dirette. L'offset, se diverso da zero, deve fare riferimento a una posizione nella sezione data. Il formato dei dati è specificato da "annotation_set_item" di seguito.
fields_size uint Conteggio dei campi annotati da questo elemento
annotated_methods_size uint conteggio dei metodi annotati da questo elemento
annotated_parameters_size uint conteggio degli elenchi di parametri dei metodi annotati da questo elemento
field_annotations field_annotation[fields_size] (facoltativo) elenco delle annotazioni dei campi associate. Gli elementi dell'elenco devono essere ordinati in ordine crescente in base a field_idx.
method_annotations method_annotation[methods_size] (facoltativo) elenco di annotazioni dei metodi associati. Gli elementi dell'elenco devono essere ordinati in ordine crescente in base a method_idx.
annotationi_parametro annotatione_parametro[dimensione_parametri] (facoltativo) elenco di annotazioni dei parametri del metodo associati. Gli elementi dell'elenco devono essere ordinati in ordine crescente in base a method_idx.

Nota:tutte le istanze field_id e method_id degli elementi devono fare riferimento alla stessa classe di definizione.

Formato di annotazione_campo

Nome Formato Descrizione
field_idx uint indice nell'elenco field_ids per l'identità del campo da annotare
annotations_off uint dall'inizio del file all'elenco di annotazioni per il campo. L'offset deve fare riferimento a una posizione nella sezione data. Il formato dei dati è specificato da "annotation_set_item" di seguito.

formato dell'annotazione del metodo

Nome Formato Descrizione
method_idx uint indice nell'elenco method_ids per l'identità del metodo da annotare
annotations_off uint dall'inizio del file all'elenco di annotazioni per il metodo. L'offset deve fare riferimento a una posizione nella sezione data. Il formato dei dati è specificato da "annotation_set_item" di seguito.

formato dell'annotazione del parametro

Nome Formato Descrizione
method_idx uint indice nell'elenco method_ids per l'identità del metodo di cui vengono annotati i parametri
annotations_off uint offset dall'inizio del file all'elenco di annotazioni per i parametri del metodo. L'offset deve fare riferimento a una posizione nella sezione data. Il formato dei dati è specificato da "annotation_set_ref_list" di seguito.

annotation_set_ref_list

Riferimenti da parameter_annotations_item

Viene visualizzato nella sezione Dati

Allineamento: 4 byte

Nome Formato Descrizione
dimensioni uint dimensioni dell'elenco, in voci
lista annotation_set_ref_item[size] elementi dell'elenco

formato annotation_set_ref_item

Nome Formato Descrizione
annotations_off uint offset dall'inizio del file all'insieme di annotazioni a cui si fa riferimento oppure 0 se non sono presenti annotazioni per questo elemento. L'offset, se diverso da zero, deve fare riferimento a una posizione nella sezione data. Il formato dei dati è specificato da "annotation_set_item" di seguito.

annotation_set_item

A cui viene fatto riferimento da annotations_directory_item, field_annotations_item, method_annotations_item e annotation_set_ref_item

Viene visualizzato nella sezione Dati

Allineamento: 4 byte

Nome Formato Descrizione
dimensioni uint dimensioni dell'insieme, in voci
voci annotation_off_item[size] elementi dell'insieme. Gli elementi devono essere ordinati in ordine crescente, per type_idx.

formato annotation_off_item

Nome Formato Descrizione
annotation_off uint offset dall'inizio del file a un'annotazione. L'offset deve fare riferimento a una posizione nella sezione data e il formato dei dati in quella posizione è specificato da "annotation_item" di seguito.

annotation_item

Riferimento da annotation_set_item

Viene visualizzato nella sezione Dati

Allineamento: nessuno (allineato a byte)

Nome Formato Descrizione
visibilità ubyte la visibilità prevista di questa annotazione (vedi di seguito)
annotazione encoded_annotation Contenuti delle annotazioni codificati, nel formato descritto da "Formato encoded_annotation" in "Codifica encoded_value" sopra.

Valori di visibilità

Di seguito sono riportate le opzioni per il campo visibility in un annotation_item:

Nome Valore Descrizione
VISIBILITY_BUILD 0x00 destinati a essere visibili solo in fase di compilazione (ad es. durante la compilazione di altro codice)
VISIBILITY_RUNTIME 0x01 deve essere visibile in fase di esecuzione
VISIBILITY_SYSTEM 0x02 destinati a essere visibili in fase di runtime, ma solo al sistema di base (e non al codice utente normale)

encoded_array_item

Riferimento da class_def_item

Viene visualizzato nella sezione Dati

Allineamento: nessuno (allineato a byte)

Nome Formato Descrizione
valore array_codificato byte che rappresentano il valore dell'array codificato, nel formato specificato da "encoded_array Formato" in "encoded_value Codifica" sopra.

hiddenapi_class_data_item

Questa sezione contiene dati sulle interfacce con limitazioni utilizzate da ogni classe.

Nota: la funzionalità dell'API nascosta è stata introdotta in Android 10.0 ed è applicabile solo ai file DEX delle classi nel percorso della classe di avvio. L'elenco dei flag descritto di seguito potrebbe essere esteso nelle release future di Android. Per ulteriori informazioni, consulta le limitazioni relative alle interfacce non SDK.

Nome Formato Descrizione
dimensioni uint dimensione totale della sezione
offset uint[] array di offset indicizzati da class_idx. Una voce dell'array pari a zero all'indice class_idx indica che non esistono dati per questo class_idx o che tutti i flag dell'API nascosti sono pari a zero. In caso contrario, la voce dell'array è diversa da zero e contiene un offset dall'inizio della sezione a un array di flag API nascosti per questo class_idx.
flags uleb128[] Array concatenati di flag API nascosti per ogni classe. I possibili valori del flag sono descritti nella tabella seguente. I flag vengono codificati nello stesso ordine in cui i campi e i metodi vengono codificati nei dati di classe.

Tipi di flag di restrizione:

Nome Valore Descrizione
lista consentita 0 Interfacce che possono essere utilizzate liberamente e sono supportate nell'Indice dei pacchetti del framework Android documentato ufficialmente.
greylist 1 Interfacce non SDK che possono essere utilizzate indipendentemente dal livello API target dell'applicazione.
Inserisci nella blacklist 2 Interfacce non SDK che non possono essere utilizzate indipendentemente dal livello API target dell'applicazione. L'accesso a una di queste interfacce causa un errore di runtime.
greylist‑max‑o 3 Interfacce non SDK che possono essere utilizzate per Android 8.x e versioni precedenti a meno che non siano limitate.
greylist‑max‑p 4 Interfacce non SDK che possono essere utilizzate per Android 9.x a meno che non siano limitate.
greylist‑max‑q 5 Interfacce non SDK che possono essere utilizzate per Android 10.x a meno che non siano limitate.
greylist‑max‑r 6 Interfacce non SDK che possono essere utilizzate per Android 11.x a meno che non siano limitate.

Annotazioni di sistema

Le annotazioni di sistema vengono utilizzate per rappresentare vari elementi di informazioni riflessive sulle classi (e sui metodi e sui campi). Generalmente, a queste informazioni viene eseguito accesso solo indirettamente dal codice client (non di sistema).

Le annotazioni di sistema sono rappresentate nei file .dex come annotazioni con visibilità impostata su VISIBILITY_SYSTEM.

dalvik.annotation.AnnotationDefault

Viene visualizzato nei metodi delle interfacce di annotazione

A ogni interfaccia di annotazione che vuole indicare le associazioni predefinite è associata un'annotazione AnnotationDefault.

Nome Formato Descrizione
valore Annotazione le associazioni predefinite per questa annotazione, rappresentate come un'annotazione di questo tipo. L'annotazione non deve includere tutti i nomi definiti dall'annotazione; i nomi mancanti non hanno valori predefiniti.

dalvik.annotation.EnclosingClass

Compare nei corsi

Un'annotazione EnclosingClass è collegata a ogni classe definita come membro di un'altra classe di per sé o che è anonima, ma non definita all'interno del corpo di un metodo (ad es. una classe interna sintetica). Ogni classe con questa annotazione deve avere anche un'annotazione InnerClass. Inoltre, un corso non deve avere contemporaneamente un'annotazione EnclosingClass e un'annotazione EnclosingMethod.

Nome Formato Descrizione
valore Classe la classe che ha l'ambito lessicale più simile a questo

dalvik.annotation.EnclosingMethod

Compare nei corsi

A ogni classe viene associata un'annotazione EnclosingMethod, che viene definita all'interno del corpo di un metodo. Ogni classe con questa annotazione deve avere anche un'annotazione InnerClass. Inoltre, un corso non deve avere sia un'annotazione EnclosingClass che un'annotazione EnclosingMethod.

Nome Formato Descrizione
valore Metodo il metodo che definisce l'ambito lessicale di questa classe

dalvik.annotation.InnerClass

Compare nei corsi

A ogni classe è associata un'annotazione InnerClass, che è definita nell'ambito lessicale della definizione di un'altra classe. Qualsiasi classe con questa annotazione deve avere anche un'annotazione EnclosingClass o EnclosingMethod.

Nome Formato Descrizione
nome Stringa Il nome semplice dichiarato originariamente di questa classe (senza alcun prefisso del pacchetto). Se il corso è anonimo, il nome è null.
accessFlags int i flag di accesso dichiarati originariamente della classe (che possono essere diversi dai flag effettivi a causa di una mancata corrispondenza tra i modelli di esecuzione del linguaggio di origine e della macchina virtuale di destinazione)

dalvik.annotation.MemberClasses

Compare su

A ogni classe è associata un'annotazione MemberClasses che dichiara le classi di membri. Una classe membro è una classe interna diretta con un nome.

Nome Formato Descrizione
valore Class[] array delle classi di membri

dalvik.annotation.MethodParameters

Compare su

Nota:questa annotazione è stata aggiunta dopo Android 7.1. La sua presenza nelle release precedenti di Android verrà ignorata.

Un'annotazione MethodParameters è facoltativa e può essere utilizzata per fornire i metadati dei parametri, come i nomi e i modificatori dei parametri.

L'annotazione può essere omessa da un metodo o un costruttore in sicurezza quando i metadati del parametro non sono richiesti in fase di esecuzione. java.lang.reflect.Parameter.isNamePresent() può essere utilizzato per verificare se sono presenti metadati per un parametro e i metodi di riflessione associati, come java.lang.reflect.Parameter.getName(), torneranno al comportamento predefinito in fase di esecuzione se le informazioni non sono presenti.

Quando includono i metadati dei parametri, i compilatori devono includere informazioni per le classi generate, come gli enum, poiché i metadati dei parametri indicano se un parametro è sintetico o obbligatorio.

Un'annotazione MethodParameters descrive solo i singoli parametri del metodo. Pertanto, i compilatori potrebbero omettere del tutto l'annotazione per i costruttori e i metodi senza parametri, in nome delle dimensioni del codice e dell'efficienza di runtime.

Gli array descritti di seguito devono avere le stesse dimensioni della struttura dex method_id_item associata al metodo, altrimenti verrà generato un java.lang.reflect.MalformedParametersException in fase di runtime.

In altre parole: method_id_item.proto_idx -> proto_id_item.parameters_off -> type_list.size deve essere uguale a names().length e accessFlags().length.

Poiché MethodParameters descrive tutti i parametri metodi formali, anche quelli non dichiarati esplicitamente o implicitamente nel codice sorgente, le dimensioni degli array possono essere diverse dalla firma o da altre informazioni sui metadati che si basano solo su parametri espliciti dichiarati nel codice sorgente. MethodParameters non includerà inoltre informazioni sui parametri di ricezione dell'annotazione del tipo che non esistono nella firma del metodo effettiva.

Nome Formato Descrizione
nomi Stringa[] I nomi dei parametri formali per il metodo associato. L'array non deve essere nullo, ma deve essere vuoto se non sono presenti parametri formali. Un valore nell'array deve essere null se il parametro formale con quell'indice non ha nome.
Se le stringhe dei nomi dei parametri sono vuote o contengono ".", ";', "[" o "/", verrà generato un java.lang.reflect.MalformedParametersException al runtime.
accessFlags int[] I flag di accesso dei parametri formali per il metodo associato. L'array non deve essere nullo, ma deve essere vuoto se non sono presenti parametri formali.
Il valore è una maschera di bit con i seguenti valori:
  • 0x0010 : finale, il parametro è stato dichiarato finale
  • 0x1000 : sintetico, il parametro è stato introdotto dal compilatore
  • 0x8000 : obbligatorio, il parametro è sintetico, ma implicito anche dalla specifica della lingua
Se alcuni bit sono impostati al di fuori di questo insieme, verrà generato un java.lang.reflect.MalformedParametersException in fase di esecuzione.

dalvik.annotation.Signature

Viene visualizzato in classi, campi e metodi

A ogni classe, campo o metodo definito in termini di un tipo più complicato di quanto sia rappresentabile da un type_id_item è associata un'annotazione Signature. Il formato .dex non definisce il formato delle firme; deve semplicemente essere in grado di rappresentare le firme richieste da un linguaggio di origine per l'implementazione corretta della semantica di quel linguaggio. Di conseguenza, le firme non vengono generalmente analizzate (o verificate) dalle implementazioni delle macchine virtuali. Le firme vengono semplicemente trasferite ad API e strumenti di livello superiore (come i debugger). Pertanto, qualsiasi utilizzo di una firma deve essere scritto in modo da non fare supposizioni sulla ricezione di firme valide, proteggendosi esplicitamente dalla possibilità di trovare una firma sintatticamente non valida.

Poiché le stringhe di firma tendono ad avere molti contenuti duplicati, un'annotazione Signature è definita come un array di stringhe, in cui gli elementi duplicati fanno naturalmente riferimento agli stessi dati sottostanti e la firma è considerata la concatenazione di tutte le stringhe nell'array. Non esistono regole su come suddividere una firma in stringhe separate; questo dipende interamente dagli strumenti che generano i file .dex.

Nome Formato Descrizione
valore Stringa[] la firma di questa classe o di questo membro, come array di stringhe da concatenare

dalvik.annotation.Throws

Compare su

A ogni metodo dichiarato per generare uno o più tipi di eccezioni è associata un'annotazione Throws.

Nome Formato Descrizione
valore Class[] l'array di tipi di eccezioni lanciate