Skip to content

Commit

Permalink
Merge branch 'junghee/alignment' into 'main'
Browse files Browse the repository at this point in the history
Add alignment for instructions that require alignment

Closes #544

See merge request rewriting/ddisasm!1203
  • Loading branch information
junghee committed May 9, 2024
2 parents cc7e529 + ae3186a commit de896e8
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
* Infer jump table boundaries from comparisons of registers correlated to the index register.
* Relax constraints for inferring jump table boundaries from comparisons of indirect operands
* Fix bug where a relative jump table starting with consecutive zero offsets was truncated at the first non-zero value.
* Add alignment for x86-64 instructions that require explicitly aligned memory
(e.g., some SIMD instructions)

# 1.8.0

Expand Down
10 changes: 10 additions & 0 deletions examples/asm_examples/ex_aligned_data_in_code/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

all: ex_original.s
gcc ex_original.s -o ex
@./ex > out.txt
clean:
rm -f ex out.txt
rm -fr ex.unstripped ex.s *.old* dl_files *.gtirb
check:
./ex > /tmp/res.txt
@ diff out.txt /tmp/res.txt && echo TEST OK
82 changes: 82 additions & 0 deletions examples/asm_examples/ex_aligned_data_in_code/ex_original.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# This example is to demonostrate that data-in-code is properly aligned
# when it is referenced by instructions that require explicitly aligned memory.
# If not properly aligned, it may cause a segmentation fault due to alignment
# requirement violation.
# See Table 15-6 in https://cdrdv2.intel.com/v1/dl/getContent/671200.

.section .text

.globl main
.type main, @function
main:
call print_message1

# Load data into XMM register using movdqa: `data128.1` needs to be aligned.
movdqa data128.1(%rip), %xmm0

# A pair of instructions from an access to `data128.2`, which needs to
# be aligned.
lea data128.2(%rip), %rax
movdqa 0(%rax), %xmm1

# Load data into YMM register using movdqa: `data256` needs to be aligned.
vmovapd data256(%rip), %ymm0

# Load data into ZMM register using movdqa: `data512` needs to be aligned.
vmovaps data512(%rip), %zmm0

# Load data into ZMM register using vmovups: `data512u` does not need to be aligned.
vmovups data512u(%rip), %zmm1

call print_message2

xorq %rax, %rax

ret

.type print_message1, @function
print_message1:
lea message1(%rip), %rdi
call printf
ret

.align 16
.type print_message2, @function
print_message2:
lea message2(%rip), %rdi
call printf
ret
.zero 3

.align 16
data128.1:
.byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
.align 16
data128.2:
.byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
.align 32
data256:
.byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
.byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
.align 64
data512:
.byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
.byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
.byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
.byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16

.zero 3
data512u:
.byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
.byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
.byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
.byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16

.section .data

message1:
.ascii "Performing SIMD operations...\n"
.byte 0
message2:
.ascii "SIMD operations completed.\n"
.byte 0
9 changes: 9 additions & 0 deletions src/datalog/arch/arch.dl
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ cmp_zero_operation(""):-

.decl call_operation_op_index(Operation:symbol,operand_index:operand_index)


// ===========================================================================
// Address-targeted instruction properties
// ===========================================================================
Expand Down Expand Up @@ -544,6 +545,14 @@ invalid(), etc.
instruction_at(Instruction,Instruction):-
instruction(Instruction,_,_,_,_,_,_,_,_,_).

/**
Instruction at EA requires alignment on the referenced memory.
*/
.decl alignment_required(EA:address,AlignInBits:unsigned)

alignment_required(0,0):-
false.

/**
The size of a register, in bytes.
*/
Expand Down
27 changes: 27 additions & 0 deletions src/datalog/arch/intel/arch_x86.dl
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,31 @@ simple_data_load(EA,Data,Size):-
instruction_memory_access_size(EA,MemIndex,Size),
Size != 0.

// Operation that requires aligned memory
.decl operation_alignment_required(Operation:symbol)

// The following AVX instructions require explicitly aligned memory
// (See Table 15-6 in https://cdrdv2.intel.com/v1/dl/getContent/671200):

operation_alignment_required("MOVDQA").
operation_alignment_required("MOVAPS").
operation_alignment_required("MOVAPD").
operation_alignment_required("MOVNTPS").
operation_alignment_required("MOVNTPD").
operation_alignment_required("MOVNTDQ").
operation_alignment_required("MOVNTDQA").

operation_alignment_required("VMOVDQA").
operation_alignment_required("VMOVAPS").
operation_alignment_required("VMOVAPD").
operation_alignment_required("VMOVNTPS").
operation_alignment_required("VMOVNTPD").
operation_alignment_required("VMOVNTDQ").
operation_alignment_required("VMOVNTDQA").

alignment_required(EA,AlignInBits):-
instruction_get_operation(EA,Operation),
operation_alignment_required(Operation),
instruction_memory_access_size(EA,_,AlignInBits).

}
12 changes: 12 additions & 0 deletions src/datalog/main.dl
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,18 @@ Information about alignment in bits for a given address

alignment(0,0):- false.

// Data in code needs to be aligned when referenced by instruction that
// requires aligned memory: e.g., some SIMD instructions
alignment(DataEA, AlignInBits):-
arch.alignment_required(EA,AlignInBits),
(
pc_relative_operand(EA,_,DataEA);
composite_data_access(_,EA,DataEA,AlignInBits)
),
data_in_code(Begin,End),
DataEA >= Begin,
DataEA < End.

//////////////////////////////////////////////////////////////////////////////////
// Operations to abstract features of instructions

Expand Down
24 changes: 24 additions & 0 deletions tests/misc_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,30 @@ def test_soname(self):

self.assertEqual(m.aux_data["elfSoname"].data, binary)

@unittest.skipUnless(
platform.system() == "Linux", "This test is linux only."
)
def test_aligned_data_in_code(self):
"""
Test that alignment directives are correctly generated for
data_in_code referenced by instructions that require aligned memory.
"""
binary = "ex"
with cd(ex_asm_dir / "ex_aligned_data_in_code"):
self.assertTrue(compile("gcc", "g++", "-O0", []))
ir = disassemble(Path(binary)).ir()
m = ir.modules[0]

alignments = m.aux_data["alignment"].data.items()
alignment_list = [alignment for uuid, alignment in alignments]

# alignment=16: `data128.1`, `data128.2`, and `main`
self.assertEqual(alignment_list.count(16), 3)
# alignment=32: `data256`
self.assertEqual(alignment_list.count(32), 1)
# alignment=64: `data512` and `_start`
self.assertEqual(alignment_list.count(64), 2)


class RawGtirbTests(unittest.TestCase):
@unittest.skipUnless(
Expand Down

0 comments on commit de896e8

Please sign in to comment.