일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- tracerpid
- on stack replacement
- 난독화
- apm
- Linux packer
- initial-exec
- 안티디버깅
- anti debugging
- Android
- LLVM
- LLVM Obfuscator
- custom packer
- uftrace
- TLS
- v8 optimizing
- linux debugging
- linux thread
- thread local storage
- LLVM 난독화
- tracing
- pinpoint
- on-stack replacement
- Injection
- Obfuscator
- v8 tracing
- pthread
- Linux custom packer
- so inject
- OSR
- android inject
- Today
- Total
Why should I know this?
[AArch64] STR (STRroX, STRXui) 본문
Store IR 원형
store [volatile] <ty> <value>, ptr <pointer>
[, align <alignment>][, !nontemporal !<nontemp_node>][, !invariant.group !<empty_node>]; yields void
store atomic [volatile] <ty> <value>, ptr <pointer> [syncscope("<target-scope>")] <ordering>, align <alignment>
[, !invariant.group !<empty_node>] ; yields void
!<nontemp_node> = !{ i32 1 }
!<empty_node> = !{}
STRroX, STRroW
STR(register)
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
1 | x | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | Rm | option | S | 1 | 0 | Rn | Rt | ||||||||||||||
size | opc |
STRroX, STRroW 예시
str x0, [x9, x8, lsl #3]
storeop | Ty regtype:$Rt | ro_Windexed64 GPR64sp:$Rn | GPR32:$Rm | ro_Wextend64:$extend |
str | x2 | x0 | w1 | lsl #3 |
regtype:$Rt | GPR64sp:$Rn | GPR32:$Rm | ro_Wextend64:$extend |
defm STRX : Store64RO<0b11, 0, 0b00, GPR64, "str", i64, store>;
multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,
string asm, ValueType Ty, SDPatternOperator storeop> {
let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
def roW : LoadStore64RO<sz, V, opc, asm, (outs),
(ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
[(storeop (Ty regtype:$Rt),
(ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
ro_Wextend64:$extend))]>,
Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
let Inst{13} = 0b0;
}
let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
def roX : LoadStore64RO<sz, V, opc, asm, (outs),
(ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
[(storeop (Ty regtype:$Rt),
(ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
ro_Xextend64:$extend))]>,
Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {
let Inst{13} = 0b1;
}
def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
}
class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,
dag outs, list<dag> pat>
: I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
bits<5> Rt;
bits<5> Rn;
bits<5> Rm;
bits<2> extend;
let Inst{31-30} = sz;
let Inst{29-27} = 0b111;
let Inst{26} = V;
let Inst{25-24} = 0b00;
let Inst{23-22} = opc;
let Inst{21} = 1;
let Inst{20-16} = Rm;
option<extend> | |
010 | UXTW |
011 | LSL |
110 | SXTW |
111 | SXTX |
(아래 옵션 FLAG를 Setting하는 의미, {15} 는 Signed여부, Inst{14}는 32bit이상이기 때문에 항상 1 )
let Inst{15} = extend{1}; // sign extend Rm?
let Inst{14} = 1;
(inst{13} 은 이전에 설정했다. let Inst{13} = 0b1; 32bit 는 0 64bit는 1)
(Inst{12) : extend가 LSL 이 아닌 경우 shift amount 정의 32bit (0:#0 1:#2->4의 배수) 64bit (0:#0, 1:#3->8의 배수)
let Inst{12} = extend{0}; // do shift?
let Inst{11-10} = 0b10;
let Inst{9-5} = Rn;
let Inst{4-0} = Rt;
}
// Normal instructions
class I<dag oops, dag iops, string asm, string operands, string cstr,
list<dag> pattern>
: EncodedI<cstr, pattern> {
dag OutOperandList = oops;
dag InOperandList = iops;
let AsmString = !strconcat(asm, operands);
}
oops | (outs) |
iops | (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend) |
Pattern : | [(storeop (Ty regtype:$Rt), (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend))] |
STRXui STRWui
STR (immediate)
Unsigned offset
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
1 | x | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | imm12 | Rn | Rt | |||||||||||||||||||
size | VR | opc |
STRXui 예시
STRXui killed renamable $x8, killed renamable $x0, 31
GPR64:$val | GPR64sp:$Rn | uimm12s8:$offset | |
STRXui | killed renamable $x8 | killed renamable $x0 | 31 |
GPR64:$val | am_indexed64 GPR64sp:$Rn | uimm12s8:$offset |
// An atomic store operation that doesn't actually need to be atomic on AArch64.
class relaxed_store<PatFrag base>
: PatFrag<(ops node:$ptr, node:$val), (base node:$val, node:$ptr)> {
let IsAtomic = 1;
let IsAtomicOrderingReleaseOrStronger = 0;
}
def : Pat<(relaxed_store<atomic_store_64>
(am_indexed64 GPR64sp:$Rn, uimm12s8:$offset), GPR64:$val),
(STRXui GPR64:$val, GPR64sp:$Rn, uimm12s8:$offset)>;
ARM Develeoper manual에 기재된 offset 계산법.
boolean wback = FALSE;
boolean postindex = FALSE;
integer scale = UInt(size);
bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);
여기서 size 는 3이므로 scale=3이다. (위 MIR 참고)
imm12 에 설정 가능한 최대값 4095 이고, 이를 기준으로 64비트라면 << 3 된 #32760 이 지정가능한 최대오프셋이 된다.
왜 scale 을 하는지는 ARM 계열의 주소지정모드의 특징을 알아보면 된다.
만약 이 범위를 벗어난 값을 MIR 에 설정하면 clang은 다음과 같은 에러를 낸다.
error: index must be an integer in range [-256, 255]
원인은 다음처럼 operand mismatch가 되기 때문...
Trying to match opcode STRXui
Matching formal operand class MCK_GPR64 against actual operand at index 1 (<register 244>): match success using generic matcher
Matching formal operand class MCK__91_ against actual operand at index 2 ('['): match success using generic matcher
Matching formal operand class MCK_GPR64sp against actual operand at index 3 (<register 236>): match success using generic matcher
Matching formal operand class MCK_UImm12Offset8 against actual operand at index 4 (32768): Opcode result: multiple operand mismatches, ignoring this opcode
Matching 을 찾다가 마지막에 찾지 못한 경우로 에러를 내기 때문에 위와 같은 에러가 난다.
STRXui는 12bit Unsigned Offset 을 가질 수 있으므로 최대 12bit까지 값을 허용할 수 있다.
; STRXui killed %1:gpr64, killed %0:gpr64common, 4095
0000000000000000 <ltmp0>:
0: d28acf08 mov x8, #22136
4: f2a24688 movk x8, #4660, lsl #16
8: aa088108 orr x8, x8, x8, lsl #32
c: f93ffc08 str x8, [x0, #32760]
10: d65f03c0 ret
PatFag
llvm/utils/TableGen/Common/GlobalISel/Patterns.h
class PatFrag {
public:
static constexpr StringLiteral ClassName = "GICombinePatFrag";
'LLVM-STUDY > MIR' 카테고리의 다른 글
LESSONS IN TABLEGEN (0) | 2024.06.21 |
---|---|
[AArch64] LDR (LDRroX, LDRXui) (0) | 2024.04.16 |
[AArch64] STPX (0) | 2024.03.18 |