Constraints

A .dex file is the transport format for Dalvik bytecode. There are certain syntactical and semantical constraints for a file to be a valid .dex file, and a runtime is required to support only valid .dex files.

General .dex integrity constraints

General integrity constraints are concerned with the larger structure of a .dex file, as described in detail in .dex format.

Identifier Description
G1 The magic number of the .dex file must be dex\n035\0 or dex\n037\0.
G2 The checksum must be an Adler-32 checksum of the whole file contents except magic and checksum field.
G3 The signature must be a SHA-1 hash of the whole file contents except magic, checksum, and signature.
G4 The file_size must match the actual file size in bytes.
G5 The header_size must have the value: 0x70
G6 The endian_tag must have either the value: ENDIAN_CONSTANT or REVERSE_ENDIAN_CONSTANT
G7 For each of the link, string_ids, type_ids, proto_ids, field_ids, method_ids, class_defs, and data sections, the offset and size fields must be either both zero or both non-zero. In the latter case, the offset must be four-byte-aligned.
G8 All offset fields in the header except map_off must be four-byte-aligned.
G9 The map_off field must be either zero or point into the data section. In the latter case, the data section must exist.
G10 None of the link, string_ids, type_ids, proto_ids, field_ids, method_ids, class_defs and data sections must overlap each other or the header.
G11 If a map exists, then each map entry must have a valid type. Each type may appear at most once.
G12 If a map exists, then each map entry must have a non-zero offset and size. The offset must point into the corresponding section of the file (i.e. a string_id_item must point into the string_ids section) and the explicit or implicit size of the item must match the actual contents and size of the section.
G13 If a map exists, then the offset of map entry n+1 must be greater or equal to the offset of map entry n plus than size of map entry n. This implies non-overlapping entries and low-to-high ordering.
G14 The following types of entries must have an offset that is four-byte-aligned: string_id_item, type_id_item, proto_id_item, field_id_item, method_id_item, class_def_item, type_list, code_item, annotations_directory_item.
G15 For each string_id_item, the string_data_off field must contain a valid reference into the data section. For the referenced string_data_item, the data field must contain a valid MUTF-8 string, and the utf16_size must match the decoded length of the string.
G16 For each type_id_item, the descriptor_idx field must contain a valid reference into the string_ids list. The referenced string must be a valid type descriptor.
G17 For each proto_id_item, the shorty_idx field must contain a valid reference into the string_ids list. The referenced string must be a valid shorty descriptor. Also, the return_type_idx field must be a valid index into the type_ids section, and the parameters_off field must be either zero or a valid offset pointing into the data section. If non-zero, the parameter list must not contain any void entries.
G18 For each field_id_item, both the class_idx and type_idx fields must be valid indices into the type_ids list. The entry referenced by class_idx must be a non-array reference type. In addition, the name_idx field must be a valid reference into the string_ids section, and the contents of the referenced entry must conform to the MemberName specification.
G19 For each method_id_item, the class_idx field must be a valid index into the type_ids section, and the referenced entry must be a non-array reference type. The proto_id field must be a valid reference into the proto_ids list. The name_idx field must be a valid reference into the string_ids section, and the contents of the referenced entry must conform to the MemberName specification.
G20 For each field_id_item, the class_idx field must be a valid index into the type_ids list. The referenced entry must be a non-array reference type.

Static bytecode constraints

Static constraints are constraints on individual elements of the bytecode. They usually can be checked without employing control or data-flow analysis techniques.

Identifier Description
A1 The insns array must not be empty.
A2 The first opcode in the insns array must have index zero.
A3 The insns array must contain only valid Dalvik opcodes.
A4 The index of instruction n+1 must equal the index of instruction n plus the length of instruction n, taking into account possible operands.
A5 The last instruction in the insns array must end at index insns_size-1.
A6 All goto and if-<kind> targets must be opcodes within the same method.
A7 All targets of a packed-switch instruction must be opcodes within the same method. The size and the list of targets must be consistent.
A8 All targets of a sparse-switch instruction must be opcodes within the same method. The corresponding table must be consistent and sorted low-to-high.
A9 The B operand of the const-string and const-string/jumbo instructions must be a valid index into the string constant pool.
A10 The C operand of the iget<kind> and iput<kind> instructions must be a valid index into the field constant pool. The referenced entry must represent an instance field.
A11 The C operand of the sget<kind> and sput<kind> instructions must be a valid index into the field constant pool. The referenced entry must represent a static field.
A12 The C operand of the invoke-virtual, invoke-super, invoke-direct and invoke-static instructions must be a valid index into the method constant pool.
A13 The B operand of the invoke-virtual/range, invoke-super/range, invoke-direct/range, and invoke-static/range instructions must be a valid index into the method constant pool.
A14 A method the name of which starts with a '<' must only be invoked implicitly by the VM, not by code originating from a .dex file. The only exception is the instance initializer, which may be invoked by invoke-direct.
A15 The C operand of the invoke-interface instruction must be a valid index into the method constant pool. The referenced method_id must belong to an interface (not a class).
A16 The B operand of the invoke-interface/range instruction must be a valid index into the method constant pool. The referenced method_id must belong to an interface (not a class).
A17 The B operand of the const-class, check-cast, new-instance, and filled-new-array/range instructions must be a valid index into the type constant pool.
A18 The C operand of the instance-of, new-array, and filled-new-array instructions must be a valid index into the type constant pool.
A19 The dimensions of an array created by a new-array instruction must be less than 256.
A20 The new instruction must not refer to array classes, interfaces, or abstract classes.
A21 The type referred to by a new-array instruction must be a valid, non-reference type.
A22 All registers referred to by an instruction in a single-width (non-pair) fashion must be valid for the current method. That is, their indices must be non-negative and smaller than registers_size.
A23 All registers referred to by an instruction in a double-width (pair) fashion must be valid for the current method. That is, their indices must be non-negative and smaller than registers_size-1.
A24 The method_id operand of the invoke-virtual and invoke-direct instructions must belong to a class (not an interface). In Dex files prior to version 037 the same must be true of invoke-super and invoke-static instructions.
A25 The method_id operand of the invoke-virtual/range and invoke-direct/range instructions must belong to a class (not an interface). In Dex files prior to version 037 the same must be true of invoke-super/range and invoke-static/range instructions.

Structural bytecode constraints

Structural constraints are constraints on relationships between several elements of the bytecode. They usually can't be checked without employing control or data-flow analysis techniques.

Identifier Description
B1 The number and types of arguments (registers and immediate values) must always match the instruction.
B2 Register pairs must never be broken up.
B3 A register (or pair) has to be assigned first before it can be read.
B4 An invoke-direct instruction must invoke an instance initializer or a method only in the current class or one of its superclasses.
B5 An instance initializer must be invoked only on an uninitialized instance.
B6 Instance methods may be invoked only on and instance fields may only be accessed on already initialized instances.
B7 A register that holds the result of a new-instance instruction must not be used if the same new-instance instruction is again executed before the instance is initialized.
B8 An instance initializer must call another instance initializer (same class or superclass) before any instance members can be accessed. Exceptions are non-inherited instance fields, which can be assigned before calling another initializer, and the Object class in general.
B9 All actual method arguments must be assignment-compatible with their respective formal arguments.
B10 For each instance method invocation, the actual instance must be assignment-compatible with the class or interface specified in the instruction.
B11 A return<kind> instruction must match its method's return type.
B12 When accessing protected members of a superclass, the actual type of the instance being accessed must be either the current class or one of its subclasses.
B13 The type of a value stored into a static field must be assignment-compatible with or convertible to the field's type.
B14 The type of a value stored into a field must be assignment-compatible with or convertible to the field's type.
B15 The type of every value stored into an array must be assignment-compatible with the array's component type.
B16 The A operand of a throw instruction must be assignment-compatible with java.lang.Throwable.
B17 The last reachable instruction of a method must either be a backwards goto or branch, a return, or a throw instruction. It must not be possible to leave the insns array at the bottom.
B18 The unassigned half of a former register pair may not be read (is considered invalid) until it has been re-assigned by some other instruction.
B19 A move-result<kind> instruction must be immediately preceded (in the insns array) by an invoke-<kind> instruction. The only exception is the move-result-object instruction, which may also be preceded by a filled-new-array instruction.
B20 A move-result<kind> instruction must be immediately preceded (in actual control flow) by a matching return-<kind> instruction (it must not be jumped to). The only exception is the move-result-object instruction, which may also be preceded by a filled-new-array instruction.
B21 A move-exception instruction must appear only as the first instruction in an exception handler.
B22 The packed-switch-data, sparse-switch-data, and fill-array-data pseudo-instructions must not be reachable by control flow.