data_access_analysis

The data access analysis computes:

-‘data_access_patterns’ which represent that the address ‘Address’ is

accessed with size ‘Size’ and multiplier ‘Multiplier’ from an instruction in ‘FromWhere’.

-‘preferred_data_access’ the address is most likely accessed from the data access

pattern located at ea_data_access.

data_access_patterns are computed by checking memory accesses and with the help of the value analysis.

data_access_patterns give us very sparse information, but if an address ‘ea’ is accessed with a multiplier, it is likely that ‘ea’+multiplier, ‘ea’+2*multiplier, etc are also accessed the same way. Unfortunately, we do not know until when. Therefore, we propagate these accesses using the multiplier until we reach some other access.

instruction_memory_access_size(EA:address, Op_index:operand_index, Size:unsigned)

data_access(EA:address, Op_index:operand_index, RegSegment:reg_nullable, RegBase:reg_nullable, RegIndex:reg_nullable, Mult:number, Offset:number, Size:unsigned)

value_reg_at_operand(EA:address, Op_index:operand_index, Reg:reg_nullable, EA_from:address, Mult:number, Offset:number, Type:symbol)

value_reg_at_operand_loop(EA:address, Op_index:operand_index, Reg:reg_nullable, EA_from:address, Mult:number, Offset:number, Type:symbol)

data_access_pattern(Address:address, Size:unsigned, Multiplier:number, FromWhere:address)

The address ‘Address’ is accessed from an instruction at address ‘FromWhere’. The access has size ‘Size’ and uses a multiplier ‘Multiplier’.

data_access_pattern_candidate(Address:address, Size:unsigned, Multiplier:number, FromWhere:address)

Auxiliary predicate that computes initial approximation of data_access_pattern

simple_data_access_pattern(Address:address, Op_index:unsigned, Size:unsigned, FromWhere:address)

The address Address is accessed from instruction at address FromWhere. The access is done from operand Op_index and has size Size. simple_data_access_pattern is a subset of data_access_pattern_candidate that can be computed without using the value register analysis.

preferred_data_access(EA:address, Size:unsigned, AccessEA:address)

The address at ‘EA’ is probably accessed with size ‘Size’ using the same pattern as the data access in ‘AccessEA’. Preferred data accesses are computed by propagating data accesses based on their multiplier.

data_access_pattern_candidate_refined(Address:address, Size:unsigned, Multiplier:number, FromWhere:address)

Filter out some invalid DAP candidates before performing expensive aggregation

dap_location(Address:address, Size:unsigned)

Unique DAP Address,Size pairs at which the max must be evaluated.

Prevents evaluating the max for each non-unique copy of the pair.

dap_max_mult(Address:address, Size:unsigned, Max:number)

The largest multiplier for each Address,Size combination among the data access pattern candidates

data_access_limit(EA:address)

Data limits are the candidates for labeled data and the boundaries of data segments.

data_limit(EA:address)

Labeled data boundaries

next_data_limit(EA:address, Next:address)

The next data limit after ‘EA’ is at ‘Next’.

data_limit_after_access(Access:address, DataLimit:address)

The first data limit after the data access at address ‘Access’ is at address ‘DataLimit’.

next_data_access(EA:address, Next:address)

The next data access after the one at ‘EA’ is at ‘Next’.

data_access_pattern_non_zero(Address:address, Size:unsigned, Multiplier:unsigned, FromWhere:address)

synchronous_access_barrier(EA:address)

Barriers are the candidates for limiting synchronous access pairing.

synchronous_access_barrier_after_access(EA:address, Barrier:address)

The first synchronous_access barrier after the data access to ‘EA’ is at address ‘Barrier’.

synchronous_access(RefAccess:address, LastEA:address)

Two data accesses are synchronous if: 1. The second access has multiplier 0 and it originates from the same address

as the first.

  1. Or, They have the same multiplier and the space between them

means they do not collide with each other even if they are propagated.

synchronous_access denotes that the access at RefAccess is synchronous with all the accesses from RefAccess to LastEA. For example, if we have the consecutive accesses: A, B, C, D. synchronous_access(A,D) means that A is synchronous with B, C and D.

Note that if synchronous_access(A,D) is generated, so will synchronous_access(A,B) and synchronous_access(A,C) since the computation is incremental. We could use subsumption to remove those intermediate results but that would require reworking first_synchronous_access as well.

first_synchronous_access(Ref:address, Access:address)

The first synchronous data access of ‘Access’ is located at address ‘Ref’.

next_dyssynchronous_data_access(EA:address, Next:address)

The next data access after ‘EA’ that is not synchronous with ‘EA’ is located at address ‘Next’.