forked from cirosantilli/linux-kernel-module-cheat
/
str.S
60 lines (51 loc) · 1.45 KB
/
str.S
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/* https://cirosantilli.com/linux-kernel-module-cheat#arm-str-instruction */
#include <lkmc.h>
.data;
/* Must be in the .data section, since we want to modify it. */
myvar:
.word 0x12345678
LKMC_PROLOGUE
/* Sanity check. */
ldr r0, =myvar
ldr r1, [r0]
movw r2, 0x5678
movt r2, 0x1234
LKMC_ASSERT_EQ_REG(r1, r2)
/* Modify the value. */
ldr r0, =myvar
movw r1, 0xDEF0
movt r1, 0x9ABC
str r1, [r0]
/* Check that it changed. */
ldr r0, =myvar
ldr r1, [r0]
movw r2, 0xDEF0
movt r2, 0x9ABC
LKMC_ASSERT_EQ_REG(r1, r2)
/* Cannot use PC relative addressing to a different segment,
* or else it fails with:
*
* ....
* Error: internal_relocation (type: OFFSET_IMM) not fixed up
* ....
*
* https://stackoverflow.com/questions/10094282/internal-relocation-not-fixed-up
*/
/*ldr r0, myvar*/
#if 0
/* We could in theory write this to set the address of myvar,
* but it will always segfault under Linux because the text segment is read-only.
* This is however useful in baremetal programming.
* This construct is not possible in ARMv8 for str:
* https://cirosantilli.com/linux-kernel-module-cheat#armv8-aarch64-str-instruction
*/
str r1, .Lvar_in_same_section
.Lvar_in_same_section:
#endif
/* = sign just doesn't make sense for str, you can't set the
* address of a variable.
*/
#if 0
str r1, =myvar
#endif
LKMC_EPILOGUE