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.

Guida ai tipi

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

LEB128

LEB128 ("Little-Endian Base 128") è una codifica a lunghezza variabile per quantità intere con segno o senza segno arbitrarie. Il formato è stato preso in prestito 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. Ogni byte ha il bit più significativo impostato, ad eccezione dell'ultimo byte della sequenza, che ha il bit più significativo disattivato. I sette bit rimanenti di ogni byte sono 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 firmato (sleb128), il bit di payload più significativo dell'ultimo byte della sequenza viene esteso con segno per produrre il valore finale. Nel caso di valori senza segno (uleb128), i bit non rappresentati esplicitamente vengono interpretati come 0.

Diagramma a livello di bit di un valore LEB128 a 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 senza segno 0xffffffff) — ma nessun altro numero negativo — è un singolo byte ed è utile esattamente nei casi in cui il numero rappresentato deve essere non negativo o -1 (o 0xffffffff), e in cui non sono consentiti altri valori negativi (o in cui è improbabile che siano necessari valori senza segno 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 stringhe. Si tratta di identificatori per tutte le stringhe utilizzate da questo file, per la denominazione interna (ad es. descrittori di tipo) o come oggetti costanti a cui fa riferimento il codice. Questo elenco deve essere ordinato in base al contenuto della stringa, utilizzando i valori dei punti di codice UTF-16 (non in modo sensibile alle impostazioni internazionali) e non deve contenere voci duplicate.
type_ids type_id_item[] elenco degli identificatori di tipo. Si tratta di identificatori per tutti i tipi (classi, array o tipi primitivi) a cui fa riferimento questo file, indipendentemente dal fatto che siano definiti nel file o meno. Questo elenco deve essere ordinato in base all'indice string_id e non deve contenere voci duplicate.
proto_ids proto_id_item[] elenco degli identificatori dei prototipi di metodi. Questi sono gli identificatori di tutti i prototipi a cui fa riferimento questo file. Questo elenco deve essere ordinato in base al tipo di ritorno (in base all'indice type_id) e poi in base all'elenco degli argomenti (ordine lessicografico, argomenti individuali ordinati in base all'indice type_id). L'elenco non deve contenere voci duplicate.
field_ids field_id_item[] elenco degli identificatori dei campi. 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 degli 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 è valido che una definizione per la classe con lo stesso nome appaia più di una volta nell'elenco.
call_site_ids call_site_id_item[] elenco degli identificatori del sito 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 degli handle dei metodi. Un elenco di tutti gli handle di metodi a cui fa riferimento questo file, definiti o meno nel file. Questo elenco non è ordinato e potrebbe contenere duplicati che corrispondono logicamente a diverse istanze di handle del metodo.
di dati ubyte[] area dati, contenente tutti i dati di supporto per le tabelle elencate sopra. I diversi elementi hanno requisiti di allineamento diversi e i byte di riempimento vengono inseriti prima di ogni elemento, se necessario, per ottenere un allineamento corretto.
link_data ubyte[] dati utilizzati nei file collegati staticamente. Il formato dei dati in questa sezione non è specificato in questo documento. Questa sezione è vuota nei file scollegati e le implementazioni del runtime possono utilizzarla come ritengono opportuno.

Formato del contenitore

La versione 41 introduce un nuovo formato contenitore per i dati DEX con l'obiettivo 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 è la dimensione del file logico, non di quello fisico. Può essere utilizzato per scorrere tutti i file logici nel contenitore.
  • I file dex logici possono fare riferimento a dati successivi nel contenitore (ma non precedenti). Ciò consente ai file dex di condividere dati, come le stringhe, tra loro.
  • Tutti gli offset sono relativi al file fisico. Nessun offset è relativo all'intestazione. In questo modo, le sezioni con offset possono essere condivise tra 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 nel nuovo formato.
  • data_size e data_off non vengono 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 devono essere presenti all'inizio di un file .dex affinché venga riconosciuto come tale. Il valore contiene intenzionalmente un carattere di nuova riga ("\n" o 0x0a) e un byte null ("\0" o 0x00) per facilitare il rilevamento di alcune forme di danneggiamento. Il valore codifica anche un numero di versione del formato come tre cifre decimali, che dovrebbe aumentare monotonicamente nel tempo man mano che il formato si evolve.

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

Nota:il supporto della versione 041 del formato è stato aggiunto nella release Android 16, che supporta il formato contenitore.

Nota: il supporto della versione 040 del formato è stato aggiunto nella release 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 del set di bytecode. In Android 10, la versione 039 estende il formato del file DEX per includere informazioni API nascoste applicabili solo ai file DEX nel percorso delle classi di avvio.

Nota: il supporto della versione 038 del formato è stato aggiunto nella release 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 utilizzava la versione 035 del formato. L'unica differenza tra le versioni 035 e 037 è l'aggiunta di metodi predefiniti e la modifica di invoke.

Nota:almeno un paio di versioni precedenti del formato sono state utilizzate in versioni 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 è stata utilizzata per le release M5 della piattaforma Android (febbraio-marzo 2008). Per diversi aspetti, queste versioni precedenti del formato differiscono in modo significativo dalla versione descritta in questo documento.

ENDIAN_CONSTANT e REVERSE_ENDIAN_CONSTANT

Incorporato in header_item

La costante ENDIAN_CONSTANT viene utilizzata per indicare l'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 rileva un'intestazione il cui endian_tag è REVERSE_ENDIAN_CONSTANT anziché ENDIAN_CONSTANT, saprà che il file è stato scambiato di byte 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 di indice è assente.

Nota: questo valore non è definito come 0, perché in realtà è 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 dei flag di accesso

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à generali di classi e membri delle classi.

Nome Valore Per le classi (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 alla classe di definizione static: non accetta un argomento this
ACC_FINAL 0x10 final: non può essere suddivisa in sottoclassi final: immutabile dopo la creazione final: non sostituibile
ACC_SYNCHRONIZED 0x20     synchronized: il blocco associato acquisito automaticamente intorno alla chiamata a questo metodo.

Nota: questa opzione è valida solo se è impostata anche ACC_NATIVE.

ACC_VOLATILE 0x40   volatile: regole di accesso speciali per garantire la sicurezza dei thread  
ACC_BRIDGE 0x40     metodo bridge, aggiunto automaticamente dal compilatore come bridge type-safe
ACC_TRANSIENT 0x80   transient: non deve essere salvato dalla serializzazione predefinita  
ACC_VARARGS 0x80     L'ultimo argomento deve essere considerato come un argomento "rest" dal compilatore
ACC_NATIVE 0x100     native: implementato nel codice nativo
ACC_INTERFACE 0x200 interface: classe astratta implementabile più volte    
ACC_ABSTRACT 0x400 abstract: non direttamente istanziabile   abstract: non implementato da questa classe
ACC_STRICT 0x800     strictfp: regole rigorose per l'aritmetica in 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 dichiarata 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:questa operazione non influisce sull'esecuzione (se non per il riflesso di questo flag, in sé).

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

Codifica UTF-8 modificata

Per facilitare il supporto legacy, il formato .dex codifica i dati stringa in una forma UTF-8 modificata di fatto standard, di seguito denominata MUTF-8. Questo formato è identico all'UTF-8 standard, tranne per:

  • Vengono utilizzate solo le codifiche a 1, 2 e 3 byte.
  • I punti di codice nell'intervallo U+10000U+10ffff sono codificati come una coppia surrogata, ognuno dei quali è rappresentato come un valore codificato di tre byte.
  • Il punto di codice U+0000 è codificato in formato a due byte.
  • Un byte null semplice (valore 0) indica la fine di una stringa, come nell'interpretazione standard del linguaggio C.

I primi due elementi 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 con terminazione null in stile C.

Tuttavia, la codifica speciale di U+0000 fa sì che, a differenza dell'UTF-8 normale, il risultato della chiamata della funzione C standard strcmp() su una coppia di stringhe MUTF-8 non sempre indichi il risultato firmato correttamente del confronto di stringhe non uguali. Quando l'ordinamento (non solo l'uguaglianza) è un problema, il modo più semplice per confrontare le stringhe MUTF-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 che a UTF-8 in sé.

codifica encoded_value

Incorporato in annotation_element e encoded_array_item

Un encoded_value è un insieme codificato di dati strutturati gerarchicamente (quasi) arbitrari. La codifica è pensata per essere compatta e semplice da analizzare.

Nome Formato Descrizione
(value_arg << 5) | value_type ubyte byte che indica il tipo di value immediatamente successivo insieme a un argomento di chiarimento facoltativo 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 di value immediatamente successivo in byte, come (size - 1), ad es. 0 significa che il valore richiede un byte, mentre 7 significa che ne richiede otto; tuttavia, esistono eccezioni come indicato di seguito.
valore ubyte[] byte che rappresentano il valore, di lunghezza variabile e interpretati in modo diverso per i diversi byte value_type, anche se sempre little-endian. Per ulteriori dettagli, consulta le varie definizioni dei valori riportate di seguito.

Formati dei valori

Digita nome value_type Formato value_arg Formato value Descrizione
VALUE_BYTE 0x00 (nessuno; deve essere 0) ubyte[1] valore intero con segno a un byte
VALUE_SHORT 0x02 size - 1 (0…1) ubyte[size] valore intero a due byte con segno, 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 taglia - 1 (0…3) ubyte[size] valore intero a quattro byte con segno, estensione del segno
VALUE_LONG 0x06 size - 1 (0…7) ubyte[size] valore intero con segno a otto byte, esteso con segno
VALUE_FLOAT 0x10 taglia - 1 (0…3) ubyte[size] pattern di bit a 4 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 a otto byte, esteso con zeri a destra e interpretato come valore in virgola mobile a 64 bit IEEE754
VALUE_METHOD_TYPE 0x15 taglia - 1 (0…3) ubyte[size] valore intero di quattro byte non firmato (con estensione zero), interpretato come indice nella sezione proto_ids e che rappresenta un valore di tipo di metodo
VALUE_METHOD_HANDLE 0x16 taglia - 1 (0…3) ubyte[size] valore intero a quattro byte non firmato (esteso a zero), interpretato come indice nella sezione method_handles e che rappresenta un valore di handle del metodo
VALUE_STRING 0x17 taglia - 1 (0…3) ubyte[size] valore intero di quattro byte non firmato (con estensione zero), interpretato come indice nella sezione string_ids e che rappresenta un valore stringa
VALUE_TYPE 0x18 taglia - 1 (0…3) ubyte[size] valore intero a quattro byte non firmato (con estensione a zero), interpretato come indice nella sezione type_ids e che rappresenta un valore di tipo/classe riflessivo
VALUE_FIELD 0x19 taglia - 1 (0…3) ubyte[size] valore intero di quattro byte non firmato (esteso a zero), interpretato come indice nella sezione field_ids e che rappresenta un valore di campo riflessivo
VALUE_METHOD 0x1a taglia - 1 (0…3) ubyte[size] valore intero di quattro byte non firmato (con estensione zero), interpretato come indice nella sezione method_ids e che rappresenta un valore del metodo di riflessione
VALUE_ENUM 0x1b taglia - 1 (0…3) ubyte[size] valore intero a quattro byte non firmato (con estensione a zero), interpretato come indice nella sezione field_ids e che rappresenta il valore di una costante di tipo enumerato
VALUE_ARRAY 0x1c (nessuno; deve essere 0) encoded_array un array di valori nel formato specificato nella sezione "Formato encoded_array" di seguito. La dimensione di value è implicita nella codifica.
VALUE_ANNOTATION 0x1d (nessuno; deve essere 0) encoded_annotation una sottotitolo codificato, nel formato specificato da "Formato encoded_annotation" di seguito. La dimensione di value è implicita nella codifica.
VALUE_NULL 0x1e (nessuno; deve essere 0) (nessuno) Valore di riferimento null
VALUE_BOOLEAN 0x1f booleano (0…1) (nessuno) valore a 1 bit; 0 per false e 1 per true. Il bit è rappresentato in value_arg.

encoded_array format

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 in questa sezione, concatenate in sequenza.

encoded_annotation format

Nome Formato Descrizione
type_idx uleb128 tipo di annotazione. Deve essere un tipo di classe (non un array o un tipo 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.

annotation_element format

Nome Formato Descrizione
name_idx uleb128 Nome dell'elemento, rappresentato come indice nella sezione string_ids. La stringa deve rispettare la sintassi di MemberName, definita sopra.
valore encoded_value valore dell'elemento

Sintassi delle stringhe

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

SimpleName

Un SimpleName è la base per la sintassi dei nomi di altre cose. Il formato .dex consente una discreta libertà in questo caso (molto più della maggior parte delle lingue di origine comuni). In breve, un nome semplice è costituito da qualsiasi carattere alfabetico o cifra ASCII minuscolo, alcuni simboli ASCII minuscoli specifici e la maggior parte dei punti di codice non ASCII che non sono caratteri di controllo, spazi o caratteri speciali. A partire dalla versione 040 il formato consente inoltre caratteri di spaziatura (categoria Unicode Zs). Tieni presente che i punti di codice surrogati (nell'intervallo U+d800U+dfff) non sono considerati caratteri validi per i nomi, 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 surrogati 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, i cui membri sono campi, metodi e classi interne.

MemberName
SimpleName
| '<' SimpleName '>'

FullClassName

Un FullClassName è un nome di classe completo, incluso uno specificatore di pacchetto facoltativo seguito da un nome obbligatorio.

FullClassName
OptionalPackagePrefix SimpleName
OptionalPackagePrefix
(SimpleName '/')*

TypeDescriptor

Utilizzata da type_id_item

Un TypeDescriptor è la rappresentazione di qualsiasi tipo, inclusi 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 parametri e di ritorno, tranne che non viene fatta distinzione tra i vari tipi di riferimento (classe o array). Al contrario, 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

Di seguito è riportato 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
V float
D double
Lfully/qualified/Name; 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 essere visualizzati in un file .dex.

header_item

Viene visualizzata 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" riportata sopra.
checksum uint Checksum Adler-32 del resto del file (tutto tranne magic e questo campo); utilizzato per rilevare il danneggiamento 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 versioni precedenti)

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

header_size uint

Le 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 di 0x70 (112) byte (v40 o versioni precedenti)

deve essere di 0x78 (120) byte (v41 o versioni successive)

endian_tag uint = ENDIAN_CONSTANT tag endianness. Per ulteriori dettagli, consulta la sezione "ENDIAN_CONSTANT e REVERSE_ENDIAN_CONSTANT" sopra.
link_size uint dimensione della sezione dei link o 0 se questo file non è collegato staticamente
link_off uint offset dall'inizio del file alla sezione dei link oppure 0 se link_size == 0. L'offset, se diverso da zero, deve essere un offset nella sezione link_data. Il formato dei dati a cui fa riferimento non è specificato in questo documento; questo campo dell'intestazione (e il precedente) vengono lasciati come hook da utilizzare dalle implementazioni di runtime.
map_off uint offset dall'inizio del file all'elemento della mappa. L'offset, che deve essere diverso da zero, deve essere un offset nella sezione data e i dati devono essere nel formato specificato di seguito da "map_list".
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, a dire il vero). L'offset, se diverso da zero, deve essere all'inizio della sezione string_ids.
type_ids_size uint Conteggio degli elementi nell'elenco degli identificatori di tipo, al massimo 65535
type_ids_off uint offset dall'inizio del file all'elenco degli identificatori di tipo oppure 0 se type_ids_size == 0 (un caso limite strano, a dire il vero). L'offset, se diverso da zero, deve essere all'inizio della sezione type_ids.
proto_ids_size uint Conteggio degli elementi nell'elenco degli identificatori di prototipi, al 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 metodo
method_ids_off uint offset dall'inizio del file all'elenco degli identificatori di 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 delle classi oppure 0 se class_defs_size == 0 (un caso limite strano, a dire il vero). 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 versioni 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)

le dimensioni dell'intero file (incluse le altre intestazioni dex e i relativi dati). (v41 o versioni successive)

header_offset uint

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

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

map_list

Viene visualizzato nella sezione dei dati

Referenziato da header_item

Allineamento: 4 byte

Si tratta di un elenco di tutti i contenuti di un file, in ordine. Contiene alcune ridondanze rispetto a header_item ma è pensato per essere un modulo facile da usare per scorrere un intero file. Un determinato tipo deve apparire al massimo una volta in una mappa, ma non ci sono limitazioni all'ordine in cui possono apparire i tipi, a parte le limitazioni implicite nel resto del formato (ad es. una sezione header deve apparire per prima, 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 la dimensione dell'elenco, in voci
lista map_item[size] elementi dell'elenco

map_item format

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

Codici tipo

Tipo di elemento Costante Valore Dimensione 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 implicito; deve essere analizzato
code_item TYPE_CODE_ITEM 0x2001 implicito; deve essere analizzato
string_data_item TYPE_STRING_DATA_ITEM 0x2002 implicito; deve essere analizzato
debug_info_item TYPE_DEBUG_INFO_ITEM 0x2003 implicito; deve essere analizzato
annotation_item TYPE_ANNOTATION_ITEM 0x2004 implicito; deve essere analizzato
encoded_array_item TYPE_ENCODED_ARRAY_ITEM 0x2005 implicito; deve essere analizzato
annotations_directory_item TYPE_ANNOTATIONS_DIRECTORY_ITEM 0x2006 implicito; deve essere analizzato
hiddenapi_class_data_item TYPE_HIDDENAPI_CLASS_DATA_ITEM 0xF000 implicito; deve essere analizzato

string_id_item

Viene visualizzato nella sezione string_ids

Allineamento: 4 byte

Nome Formato Descrizione
string_data_off uint offset dall'inizio del file ai dati della stringa per questo elemento. L'offset deve essere in 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 dei dati

Allineamento: nessuno (allineamento byte)

Nome Formato Descrizione
utf16_size uleb128 dimensione di questa stringa, in unità di codice UTF-16 (che è la "lunghezza della stringa" in molti sistemi). ovvero la lunghezza decodificata della stringa. La lunghezza codificata è implicita nella posizione del byte 0.
di dati ubyte[] una serie di unità di codice MUTF-8 (ovvero ottetti, ovvero byte) seguita da un byte di valore 0. Per informazioni dettagliate e una discussione sul formato dei dati, vedi "Codifica MUTF-8 (UTF-8 modificato)" sopra.

Nota:è accettabile una stringa che includa (la forma codificata di) unità di codice surrogato UTF-16 (ovvero, U+d800U+dfff) in isolamento o in ordine diverso rispetto alla normale 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 indice 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 descrittore del formato breve di questo prototipo. La stringa deve essere conforme alla sintassi di ShortyDescriptor, definita sopra, e deve corrispondere al tipo restituito e ai parametri di questo elemento.
return_type_idx uint indice nell'elenco type_ids per il tipo restituito 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. Se diverso da zero, questo offset deve essere nella sezione data e i dati devono essere nel formato specificato di seguito da "type_list". 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 indice nell'elenco type_ids per il definer di questo campo. Deve essere un tipo di classe e non un tipo primitivo o di array.
type_idx ushort indice nell'elenco type_ids per il tipo di questo campo
name_idx uint Indice nell'elenco string_ids per il nome di questo campo. La stringa deve rispettare la 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 definer 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 Indice nell'elenco string_ids per il nome di questo metodo. La stringa deve rispettare la sintassi di MemberName, definita sopra.

class_def_item

Viene visualizzato nella sezione class_defs

Allineamento: 4 byte

Nome Formato Descrizione
class_idx uint indice nell'elenco type_ids per questo corso. Deve essere un tipo di classe e non un tipo primitivo o di array.
access_flags uint flag di accesso per il corso (public, final, ecc.). Per ulteriori dettagli, consulta la sezione "Definizioni di access_flags".
superclass_idx uint Indice nell'elenco type_ids per la superclasse oppure il valore costante NO_INDEX se questa classe non ha una superclasse (ovvero è una classe radice come Object). Se presente, deve essere un tipo di classe e non un tipo primitivo o di array.
interfaces_off uint offset dall'inizio del file all'elenco delle interfacce oppure 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. Ogni elemento dell'elenco deve essere un tipo di classe (non una matrice o un tipo primitivo) e non devono essere presenti duplicati.
source_file_idx uint indice nell'elenco string_ids per il nome del file contenente l'origine originale di (almeno la maggior parte di) questa classe o il valore speciale NO_INDEX per rappresentare la mancanza di queste informazioni. L'debug_info_item di qualsiasi metodo potrebbe sostituire questo file di origine, ma si prevede che la maggior parte delle classi proverrà da un solo file di origine.
annotations_off uint offset dall'inizio del file alla struttura delle annotazioni per questa classe o 0 se non sono presenti annotazioni in questa classe. Se diverso da zero, questo offset deve essere nella sezione data e i dati devono essere nel formato specificato da "annotations_directory_item" di seguito, con tutti gli elementi che fanno riferimento a questa classe come definitori.
class_data_off uint offset dall'inizio del file ai dati della classe associati a questo elemento oppure 0 se non sono presenti dati della classe per questa classe. (Questo potrebbe essere il caso, ad esempio, se questa classe è un'interfaccia marker.) Se diverso da zero, l'offset deve essere nella sezione data e i dati devono essere nel formato specificato da "class_data_item" di seguito, con tutti gli elementi che fanno riferimento a questa classe come definente.
static_values_off uint offset dall'inizio del file all'elenco dei valori iniziali per i campi static o 0 se non ce ne sono (e tutti i campi static devono essere inizializzati con 0 o null). Questo offset deve trovarsi nella sezione data e i dati devono essere nel formato specificato di seguito da "encoded_array_item". La dimensione dell'array non deve essere superiore al numero di campi static dichiarati da questa classe e gli elementi corrispondono ai campi static nello stesso ordine in cui sono dichiarati nel field_list corrispondente. Il tipo di ogni elemento dell'array deve corrispondere al tipo dichiarato del campo corrispondente. Se l'array contiene meno elementi rispetto ai campi static, i campi rimanenti vengono inizializzati con un valore 0 o 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 alla definizione del sito di chiamata. L'offset deve trovarsi 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 dei dati

Allineamento: nessuno (allineamento dei byte)

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

  1. Un handle del metodo che rappresenta il metodo di collegamento del 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 di nome del metodo da risolvere (VALUE_METHOD_TYPE).

Eventuali argomenti aggiuntivi sono valori costanti passati al metodo di collegamento 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 restituito 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 parametri 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 una funzione di accesso o un invoker di metodi
unused ushort (non utilizzato)

Codici dei tipi di handle del metodo

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

class_data_item

Referenziato da class_def_item

Viene visualizzato nella sezione dei dati

Allineamento: nessuno (allineamento 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 dell'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 dell'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 definiti (uno qualsiasi di static, private o costruttore), 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 definiti (nessuno di static, private o costruttore), rappresentati come una sequenza di elementi codificati. Questo elenco non deve includere i metodi ereditati a meno che non vengano sostituiti dalla classe rappresentata da questo elemento. I metodi devono essere ordinati in base a 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.

encoded_field format

Nome Formato Descrizione
field_idx_diff uleb128 indice nell'elenco field_ids per l'identità di questo campo (inclusi nome e descrittore), rappresentato come differenza rispetto all'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 ulteriori dettagli, consulta la sezione "Definizioni di access_flags".

encoded_method format

Nome Formato Descrizione
method_idx_diff uleb128 indice nell'elenco method_ids per l'identità di questo metodo (inclusi nome e descrittore), rappresentato come differenza rispetto all'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 ulteriori dettagli, consulta la sezione "Definizioni di access_flags".
code_off uleb128 offset dall'inizio del file alla struttura del codice per questo metodo o 0 se questo metodo è abstract o native. L'offset deve essere in una posizione nella sezione data. Il formato dei dati è specificato da "code_item" di seguito.

type_list

Referenziato da class_def_item e proto_id_item

Viene visualizzato nella sezione dei dati

Allineamento: 4 byte

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

type_item format

Nome Formato Descrizione
type_idx ushort indice nell'elenco type_ids

code_item

Referenziato da encoded_method

Viene visualizzato nella sezione dei 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 del metodo a cui si riferisce questo codice
outs_size ushort il numero di parole dello spazio degli 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, questi vengono visualizzati come array tries subito dopo 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 riferirsi a una posizione nella sezione data. Il formato dei dati è specificato di seguito in "debug_info_item".
insns_size uint dimensione dell'elenco delle istruzioni, in unità di codice a 16 bit
insns ushort[insns_size] l'array effettivo di bytecode. Il formato del codice in un array insns è specificato dal documento complementare Bytecode Dalvik. Tieni presente che, sebbene sia definito come un array di ushort, esistono alcune strutture interne che preferiscono l'allineamento a 4 byte. Inoltre, se si tratta di un file con endianness invertito, l'inversione viene eseguita solo sulle singole istanze ushort e non sulle strutture interne più grandi.
padding ushort (facoltativo) = 0 due byte di riempimento per allineare tries a quattro byte. Questo elemento è presente solo se tries_size è diverso da zero e insns_size è dispari.
prova 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 crescente di indirizzo. 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 catch e indirizzi del gestore associati. Ogni try_item ha un offset byte per byte in questa struttura. Questo elemento è presente solo se tries_size è diverso da zero.

Formato try_item

Nome Formato Descrizione
start_addr uint indirizzo iniziale del blocco di codice coperto da questa voce. L'indirizzo è un conteggio delle unità di codice a 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 associato al encoded_catch_handler per questa voce. Deve essere un offset rispetto all'inizio di un encoded_catch_handler.

encoded_catch_handler_list format

Nome Formato Descrizione
dimensioni uleb128 dimensioni 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 encoded_catch_handler

Nome Formato Descrizione
dimensioni sleb128 numero di tipi di cattura in questo elenco. Se non è positivo, questo è il negativo del numero di tipi di catch e i catch sono seguiti da un gestore catch-all. Ad esempio: un size di 0 significa che esiste un catch-all, ma non catch digitati in modo esplicito. Un size di 2 significa che ci sono due catch digitati in modo esplicito e nessun catch-all. Un size di -1 indica che è presente un catch digitato insieme a un catch-all.
gestori encoded_type_addr_pair[abs(size)] stream di elementi codificati abs(size), uno per ogni tipo di cattura, nell'ordine in cui devono essere testati i tipi.
catch_all_addr uleb128 (facoltativo) indirizzo bytecode del gestore catch-all. Questo elemento è presente solo se size non è positivo.

encoded_type_addr_pair format

Nome Formato Descrizione
type_idx uleb128 indice nell'elenco type_ids per il tipo di eccezione da rilevare
addr uleb128 indirizzo bytecode del gestore delle eccezioni associato

debug_info_item

Referenziato da code_item

Viene visualizzato nella sezione dei dati

Allineamento: nessuno (allineamento byte)

Ogni debug_info_item definisce una macchina a stati con codifica byte ispirata a DWARF3 che, una volta interpretata, emette la tabella delle posizioni e (potenzialmente) le informazioni sulle variabili locali per una code_item. La sequenza inizia con un'intestazione 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 registro 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 da associare alla successiva voce della tabella delle posizioni emessa dalla macchina a stati. Viene inizializzato nell'intestazione della sequenza e può variare in direzione positiva o negativa, ma non deve mai essere inferiore a 1. Il registro source_file rappresenta il file sorgente 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 su false) che indicano se la posizione successiva emessa deve essere considerata un prologo o un epilogo del metodo. La macchina a stati deve anche tenere traccia del nome e del 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 del registro line della macchina a stati. Non rappresenta una voce di posizioni effettiva.
parameters_size uleb128 il numero di nomi dei parametri codificati. Deve essercene uno per ogni parametro del metodo, escluso this di un metodo di istanza, se presente.
parameter_names uleb128p1[parameters_size] Indice della stringa del nome del parametro del metodo. Un valore codificato di NO_INDEX indica che non è disponibile un nome per il parametro associato. Il descrittore del tipo e la firma sono impliciti nel descrittore e nella firma del metodo.

I valori del codice byte sono i seguenti:

Nome Valore Formato Argomenti Descrizione
DBG_END_SEQUENCE 0x00 (nessuno) 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 di cui modificare il registro di linea avanza il registro delle righe senza emettere una voce di posizioni
DBG_START_LOCAL 0x03 uleb128 register_num
uleb128p1 name_idx
uleb128p1 type_idx
register_num: registro che conterrà
name_idx: indice stringa del nome
type_idx: indice del tipo
introduce una variabile locale all'indirizzo attuale. name_idx o type_idx possono essere NO_INDEX per indicare che il valore è sconosciuto.
DBG_START_LOCAL_EXTENDED 0x04 uleb128 register_num
uleb128p1 name_idx
uleb128p1 type_idx
uleb128p1 sig_idx
register_num: registro che conterrà
name_idx: indice della stringa del nome
type_idx: indice del tipo di tipo
sig_idx: indice della stringa della firma del tipo
introduce una variabile locale con una firma di tipo all'indirizzo corrente. name_idx, type_idx o sig_idx possono essere NO_INDEX per indicare che il valore è sconosciuto. Se sig_idx è -1, tuttavia, gli stessi dati potrebbero essere rappresentati in modo più efficiente utilizzando il codice operativo DBG_START_LOCAL.

Nota: per i dettagli sulla gestione delle firme, consulta la sezione "dalvik.annotation.Signature" di seguito.

DBG_END_LOCAL 0x05 uleb128 register_num register_num: il registro che conteneva il locale contrassegna una variabile locale attualmente attiva come fuori ambito all'indirizzo attuale
DBG_RESTART_LOCAL 0x06 uleb128 register_num register_num: registrati per riavviare reintroduce una variabile locale all'indirizzo corrente. Il nome e il tipo sono gli stessi dell'ultimo locale attivo nel registro specificato.
DBG_SET_PROLOGUE_END 0x07 (nessuno) imposta il registro della macchina a stati prologue_end, indicando che la successiva voce di posizione aggiunta deve essere considerata la fine di un prologo del metodo (un punto appropriato per un punto di interruzione del metodo). Il registro prologue_end viene cancellato da qualsiasi codice operativo speciale (>= 0x0a).
DBG_SET_EPILOGUE_BEGIN 0x08 (nessuno) imposta il registro della macchina a stati epilogue_begin, indicando che la successiva voce di posizione aggiunta deve essere considerata l'inizio di un epilogo del metodo (un punto appropriato per sospendere l'esecuzione prima dell'uscita dal metodo). Il registro epilogue_begin viene cancellato da qualsiasi codice operativo speciale (>= 0x0a).
DBG_SET_FILE 0x09 uleb128p1 name_idx name_idx: indice della stringa del nome del file sorgente; NO_INDEX se sconosciuto indica che tutte le voci successive del numero di riga fanno riferimento a questo nome del file sorgente, anziché al nome predefinito specificato in code_item
Special Opcodes 0x0a…0xff (nessuno) fa avanzare i registri line e address, emette una voce di posizione e cancella prologue_end e epilogue_begin. Vedi la descrizione di seguito.

Special opcodes

I codici operativi con valori compresi tra 0x0a e 0xff (inclusi) spostano i registri line e address di una piccola quantità, quindi 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

Referenziato da class_def_item

Viene visualizzato nella sezione dei dati

Allineamento: 4 byte

Nome Formato Descrizione
class_annotations_off uint offset dall'inizio del file alle annotazioni apportate direttamente alla classe o 0 se la classe non ha annotazioni dirette. L'offset, se diverso da zero, deve essere impostato su 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 del metodo annotati da questo elemento
field_annotations field_annotation[fields_size] (facoltativo) Elenco delle annotazioni dei campi associati. Gli elementi dell'elenco devono essere ordinati in ordine crescente, per field_idx.
method_annotations method_annotation[methods_size] (facoltativo) elenco delle annotazioni dei metodi associati. Gli elementi dell'elenco devono essere ordinati in ordine crescente, per method_idx.
parameter_annotations parameter_annotation[parameters_size] (facoltativo) elenco delle annotazioni dei parametri del metodo associato. Gli elementi dell'elenco devono essere ordinati in ordine crescente, per method_idx.

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

formato field_annotation

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

formato method_annotation

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

formato parameter_annotation

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

annotation_set_ref_list

Referenziato da parameter_annotations_item

Viene visualizzato nella sezione dei dati

Allineamento: 4 byte

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

annotation_set_ref_item format

Nome Formato Descrizione
annotations_off uint offset dall'inizio del file al set di annotazioni a cui viene fatto riferimento o 0 se non sono presenti annotazioni per questo elemento. L'offset, se diverso da zero, deve essere una posizione nella sezione data. Il formato dei dati è specificato da "annotation_set_item" di seguito.

annotation_set_item

Referenziato da annotations_directory_item, field_annotations_item, method_annotations_item e annotation_set_ref_item

Viene visualizzato nella sezione dei dati

Allineamento: 4 byte

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

annotation_off_item format

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

annotation_item

Referenziato da annotation_set_item

Viene visualizzato nella sezione dei dati

Allineamento: nessuno (allineamento byte)

Nome Formato Descrizione
visibilità ubyte visibilità prevista di questa annotazione (vedi sotto)
annotazione encoded_annotation contenuti dell'annotazione codificati, nel formato descritto in "Formato encoded_annotation" nella sezione "Codifica encoded_value" riportata sopra.

Valori di visibilità

Queste sono 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 destinati a essere visibili durante il runtime
VISIBILITY_SYSTEM 0x02 destinato a essere visibile in fase di runtime, ma solo al sistema sottostante (e non al codice utente normale)

encoded_array_item

Referenziato da class_def_item

Viene visualizzato nella sezione dei dati

Allineamento: nessuno (allineamento byte)

Nome Formato Descrizione
valore encoded_array byte che rappresentano il valore dell'array codificato, nel formato specificato da "encoded_array Format" (Formato) nella sezione "encoded_value Encoding" (Codifica) riportata sopra.

hiddenapi_class_data_item

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

Nota: La funzionalità 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 descritti di seguito potrebbe essere esteso nelle versioni future di Android. Per ulteriori informazioni, consulta le limitazioni relative alle interfacce non SDK.

Nome Formato Descrizione
dimensioni uint dimensione totale della sezione
compensazioni uint[] array di offset indicizzati da class_idx. Una voce di array pari a zero all'indice class_idx indica che non sono presenti dati per questo class_idx oppure che tutti i flag 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 dei flag sono descritti nella tabella seguente. I flag sono codificati nello stesso ordine dei campi e i metodi sono codificati nei dati della classe.

Tipi di flag di limitazione:

Nome Valore Descrizione
whitelist 0 Interfacce che possono essere utilizzate liberamente e sono supportate come parte del framework Android documentato ufficialmente Package Index.
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 varie informazioni riflettive su classi (e metodi e campi). Queste informazioni in genere sono accessibili 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 nelle interfacce di annotazione

Un'annotazione AnnotationDefault è allegata a ogni interfaccia di annotazione che vuole indicare i binding predefiniti.

Nome Formato Descrizione
valore Annotazione i binding predefiniti per questa annotazione, rappresentati come annotazione di questo tipo. L'annotazione non deve includere tutti i nomi definiti dall'annotazione; i nomi mancanti semplicemente non hanno valori predefiniti.

dalvik.annotation.EnclosingClass

Visualizzato nei corsi

A ogni classe è associata un'annotazione EnclosingClass che è definita come membro di un'altra classe o è 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, una classe non deve avere sia un'annotazione EnclosingClass sia un'annotazione EnclosingMethod.

Nome Formato Descrizione
valore Classe la classe che definisce l'ambito lessicale più vicino a questa classe

dalvik.annotation.EnclosingMethod

Visualizzato nei corsi

Un'annotazione EnclosingMethod viene allegata a ogni classe 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 più vicino a questa classe

dalvik.annotation.InnerClass

Visualizzato nei corsi

Un'annotazione InnerClass viene allegata a ogni classe definita nell'ambito lessicale della definizione di un'altra classe. Qualsiasi classe con questa annotazione deve avere o un'annotazione EnclosingClass o un'annotazione EnclosingMethod.

Nome Formato Descrizione
nome Stringa il nome semplice dichiarato originariamente di questa classe (senza prefisso del pacchetto). Se questo corso è anonimo, il nome è null.
accessFlags int i flag di accesso dichiarati originariamente per la classe (che potrebbero differire 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

Visualizzato nei corsi

A ogni classe che dichiara classi membro è associata un'annotazione MemberClasses. (Una classe membro è una classe interna diretta che ha un nome.)

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

dalvik.annotation.MethodParameters

Compare sui metodi

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

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

L'annotazione può essere omessa da un metodo o da un costruttore in modo sicuro quando i metadati del parametro non sono richiesti in fase di runtime. java.lang.reflect.Parameter.isNamePresent() può essere utilizzato per verificare se sono presenti metadati per un parametro e i metodi di reflection associati, come java.lang.reflect.Parameter.getName(), torneranno al comportamento predefinito in fase di runtime 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 includono se un parametro è sintetico o obbligatorio.

Un'annotazione MethodParameters descrive solo i singoli parametri del metodo. Pertanto, i compilatori potrebbero omettere completamente l'annotazione per i costruttori e i metodi senza parametri, per ridurre le dimensioni del codice e migliorare l'efficienza di runtime.

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

ovvero 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 del metodo formale, anche quelli non dichiarati in modo esplicito o implicito nel codice sorgente, le dimensioni degli array possono differire dalla firma o da altre informazioni sui metadati basate solo sui parametri espliciti dichiarati nel codice sorgente. MethodParameters non includerà inoltre informazioni sui parametri del ricevitore di annotazioni di tipo che non esistono nella firma del metodo effettivo.

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

dalvik.annotation.Signature

Visualizzato in classi, campi e metodi

A ogni classe, campo o metodo definito in termini di un tipo più complesso di quello rappresentabile da un type_id_item è associata un'annotazione Signature. Il formato .dex non definisce il formato delle firme; è semplicemente pensato per poter rappresentare le firme richieste da una lingua di origine per l'implementazione corretta della semantica di quella lingua. Pertanto, le firme non vengono generalmente analizzate (o verificate) dalle implementazioni delle macchine virtuali. Le firme vengono semplicemente trasferite a API e strumenti di livello superiore (come i debugger). Qualsiasi utilizzo di una firma, pertanto, deve essere scritto in modo da non fare alcuna ipotesi sulla ricezione solo di firme valide, proteggendosi esplicitamente dalla possibilità di imbattersi in 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 si riferiscono naturalmente agli stessi dati sottostanti e la firma è considerata la concatenazione di tutte le stringhe dell'array. Non esistono regole su come separare una firma in stringhe distinte; ciò dipende interamente dagli strumenti che generano i file .dex.

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

dalvik.annotation.Throws

Compare sui metodi

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

Nome Formato Descrizione
valore Classe[] l'array di tipi di eccezione generati