Skip to content

Commit

Permalink
Merge branch 'aseitz/arm-invalid-size' into 'main'
Browse files Browse the repository at this point in the history
Fix false invalid Thumb stm instruction

See merge request rewriting/ddisasm!1184
  • Loading branch information
aeflores committed Oct 23, 2024
2 parents b134d8d + 53b34c5 commit 415a2be
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
declared invalid if a data directory was attached to the end of the section.
* Add alignments to data blocks that require alignment even within data
sections
* Fix 16-Thumb STM instructions considered to be invalid if the same register
is used in reglist and register operands with writeback enabled.

# 1.9.0

Expand Down
10 changes: 10 additions & 0 deletions examples/arm_asm_examples/ex_stm_reglist_invalid/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.PHONY: clean check
out.txt: ex
@qemu-arm -L /usr/arm-linux-gnueabihf $^ > $@
ex: ex_original.s
arm-linux-gnueabihf-gcc -o $@ $^
clean:
rm -f ex out.txt
check: ex
qemu-arm -L /usr/arm-linux-gnueabihf $^ > /tmp/res.txt
@ diff out.txt /tmp/res.txt && echo TEST OK
28 changes: 28 additions & 0 deletions examples/arm_asm_examples/ex_stm_reglist_invalid/ex_original.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Regression test: `stm r0!, {r0, r1}` is not considered an invalid instruction.
# `stm r1!, {r0, r1, r2}` causes a warning but compiles and it has been
# seen in real binaries

.syntax unified
.section .text

.global main
.type main, %function
.thumb
.align 4
main:
push { lr }

ldr r0, =data
stm r0!, {r0, r1}
ldr r1, =data
# this causes a warning "Warning: value stored for r1 is UNKNOWN", but compiles
# if r1 is later not used it is acceptable
stm r1!, {r0, r1, r2}
mov r0, 0
pop { pc }

.section .data
data:
.long 0
.long 1
.long 2
20 changes: 11 additions & 9 deletions src/datalog/arch/arm32_code_inference.dl
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,14 @@ invalid(EA,"arm: pre/post-index disallows Rt[2] eq Rn"):-
// For LDRD operations, there will be an 'arch.memory_access' for each of
// Rt and Rt2, so this rule will check both for conflict with Rn.
arch.memory_access(_,EA,_,_,Rt,Rn,_,_,_),
Rt = Rn,
instruction_writeback(EA),
Rt = Rn.
instruction_get_operation(EA,Operation),
BaseOperation = substr(Operation,0,3),
(
BaseOperation = "LDR";
BaseOperation = "STR"
).

// Rm must be different from Rt and Rt2 in LDRD instructions.
// LDRD{cond} Rt, Rt2, [Rn], ±Rm
Expand Down Expand Up @@ -188,17 +194,13 @@ invalid(EA, "arm: invalid stm/ldm"):-
op_regdirect_contains_reg(RegOp,Reg),
op_regdirect_contains_reg(RegListOp,Reg),
(
// Reg is not the lowest-indexed register in the reglist.
op_regdirect_contains_reg(RegListOp,Reg2),
arch.reg_index(Reg,RegIdx),
arch.reg_index(Reg2,Reg2Idx),
Reg2Idx < RegIdx
;
// Reg is not allowed in the reglist in 32-bit Thumb instructions
EA band 1 = 1, Size = 4
EA band 1 = 1,
Size = 4
;
// Reg is not allowed in the reglist in LDM instructions (all modes)
BaseOperation = "LDM"
BaseOperation = "LDM",
UNUSED(Size)
).


Expand Down
4 changes: 4 additions & 0 deletions tests/qemu-elf-arm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ default: &default
strip: false
skip: false
cfg_checks:
- main_is_code
- dangling_auxdata

assembly: &assembly
Expand Down Expand Up @@ -121,6 +122,9 @@ tests:
- name: ex_zero_size_object_sym
<<: *assembly

- name: ex_stm_reglist_invalid
<<: *assembly

- name: ex_adr_to_code
<<: *assembly

Expand Down

0 comments on commit 415a2be

Please sign in to comment.