Skip to content

Commit dcae6cd

Browse files
radaretrufae
authored andcommitted
Fix #24520 - Fix arm64 assembler for ldr x0,[x27,0x100]' ##arch
1 parent 2d4e97c commit dcae6cd

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

libr/arch/p/arm/armass64.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,7 @@ static inline ut32 encode1reg(ArmOp *op) {
225225
}
226226

227227
static inline ut32 encode2regs(ArmOp *op) {
228-
// p/arm/armass64.c:226:37: runtime error: left shift of 5 by 29 places cannot be represented in type 'int'
229-
ut32 a0 = op->operands[1].reg;
228+
ut32 a0 = (ut32) op->operands[1].reg & UT32_MAX;
230229
return ((a0 & 0x7) << 29) | ((a0 & 0x18) << 13) | encode1reg (op);
231230
}
232231

@@ -1052,10 +1051,12 @@ static ut32 lsop(ArmOp *op, int k, ut64 addr) {
10521051
check_cond (op->operands[1].type == ARM_GPR);
10531052
check_cond (op->operands[1].reg_type & ARM_REG64);
10541053
k |= encode2regs (op);
1054+
bool uwu = false;
10551055
if (!strcmp (op->mnemonic, "ldrb") || !strcmp (op->mnemonic, "ldrh") || !strcmp (op->mnemonic, "strb") || !strcmp (op->mnemonic, "strh")) {
10561056
check_cond (op->operands[0].reg_type & ARM_REG32);
10571057
} else if (!strcmp (op->mnemonic, "ldrsw")) {
10581058
check_cond (op->operands[0].reg_type & ARM_REG64);
1059+
uwu = true;
10591060
} else { // ldrsh, ldrsb
10601061
if (op->operands[0].reg_type & ARM_REG32) {
10611062
k |= 0x00004000;
@@ -1129,8 +1130,18 @@ static ut32 lsop(ArmOp *op, int k, ut64 addr) {
11291130
check_cond (n <= 0x1ffe && !(n & 1))
11301131
n >>= 1;
11311132
} else { // w
1132-
check_cond (n <= 0x3ffc && !(n & 3));
1133-
n >>= 2;
1133+
int scale = (op->operands[0].reg_type & ARM_REG64) ? 3 : 2;
1134+
if (uwu || scale == 2) {
1135+
check_cond (n <= 0x3ffc && !(n & 3));
1136+
if (uwu) {
1137+
n>>= 2;
1138+
} else {
1139+
n >>= 3;
1140+
}
1141+
} else {
1142+
check_cond (n <= 0x7ff8 && !(n & 7));
1143+
n >>= 3;
1144+
}
11341145
}
11351146
data = k | (n & 0x3f) << 18 | (n & 0xfc0) << 2 | 1;
11361147
return data;
@@ -2159,7 +2170,13 @@ bool arm64ass (const char *str, ut64 addr, ut32 *op) {
21592170
} else if (!strncmp (str, "strh", 4)) {
21602171
*op = lsop (&ops, 0x00000078, -1);
21612172
} else if (!strncmp (str, "ldr", 3)) {
2162-
*op = reglsop (&ops, 0x000040f8);
2173+
*op = UT32_MAX;
2174+
if (!strstr (str, " w")) {
2175+
*op = lsop (&ops, 0x000040f8, -1);
2176+
}
2177+
if (*op == UT32_MAX) {
2178+
*op = reglsop (&ops, 0x000040f8);
2179+
}
21632180
} else if (!strncmp (str, "stur", 4)) {
21642181
*op = regsluop (&ops, 0x000000f8);
21652182
} else if (!strncmp (str, "ldur", 4)) {

test/db/asm/arm_64

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ a "ldr x4, [x6, 0x14]" c44041f8
138138
a "ldr x5, [x1, -0x20]" 25005ef8
139139
a "ldr x5, [x1, -0x32]" 25e05cf8
140140
a "ldr x8, [x3, 0x10]" 680840f9
141+
ad "ldr x0, [x27, 0x108]" 608740f9
142+
ad "ldr x0, [x27, 0x110]" 608b40f9
141143
a "ldr x8, [x3, x1]" 686861f8
142144
ad "ldrb w2, [x7, -0xa]!" e26c5f38
143145
ad "ldrb w2, [x7, -0x85]!" e2bc5738

0 commit comments

Comments
 (0)