Fix arm64 adrp assembler (#3519)

Fixed the calculation of the immediate value and more spaces, e.g.
"adrp     x0, 0x1234000" are allowed now.
This commit is contained in:
Florian Märkl 2023-05-21 05:16:37 +02:00 committed by GitHub
parent 105bc0ed50
commit daffe8bbbb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 30 deletions

View file

@ -846,41 +846,26 @@ static ut32 logical(ArmOp *op, bool invert, LogicalOp opc) {
} else {
return UT32_MAX;
}
ut8 flip[4];
rz_write_le32(flip, data);
return rz_read_be32(flip);
return rz_swap_ut32(data);
}
static ut32 adrp(ArmOp *op, ut64 addr, ut32 k) { //, int reg, ut64 dst) {
ut64 at = 0LL;
ut32 data = k;
if (op->operands[0].type == ARM_GPR) {
data |= encode1reg(op);
} else {
static ut32 adrp(ArmOp *op, ut64 addr) { //, int reg, ut64 dst) {
ut32 data = 0x90000000;
if (op->operands[0].type != ARM_GPR) {
RZ_LOG_ERROR("assembler: arm64: adrp: invalid assembly. valid usage: adrp x0, addr\n");
return UT32_MAX;
}
if (op->operands[1].type == ARM_CONSTANT) {
// XXX what about negative values?
at = op->operands[1].immediate - addr;
at /= 4;
} else {
data |= op->operands[0].reg & 0x1f;
if (op->operands[1].type != ARM_CONSTANT) {
RZ_LOG_ERROR("assembler: arm64: adrp: invalid assembly. valid usage: adrp x0, addr\n");
return UT32_MAX;
}
ut8 b0 = at;
ut8 b1 = (at >> 3) & 0xff;
#if 0
ut8 b2 = (at >> (8 + 7)) & 0xff;
data += b0 << 29;
data += b1 << 16;
data += b2 << 24;
#endif
data += b0 << 16;
data += b1 << 8;
return data;
ut64 imm = op->operands[1].immediate & ~0xfff;
imm -= addr & ~0xfff;
imm >>= 12;
data |= (imm & 3) << 29;
data |= ((imm >> 2) & rz_num_bitmask(19)) << 5;
return rz_swap_ut32(data);
}
static ut32 adr(ArmOp *op, int addr) {
@ -1396,8 +1381,8 @@ bool arm64ass(const char *str, ut64 addr, ut32 *op) {
*op = arithmetic(&ops, 0x11);
} else if (!strncmp(str, "adr x", 5)) { // w
*op = adr(&ops, addr);
} else if (!strncmp(str, "adrp x", 6)) {
*op = adrp(&ops, addr, 0x00000090);
} else if (!strncmp(str, "adrp ", 5)) {
*op = adrp(&ops, addr);
} else if (!strncmp(str, "neg", 3)) {
*op = neg(&ops);
} else if (!strcmp(str, "isb")) {

View file

@ -42,6 +42,8 @@ a "eon w0, w13, w20" a001344a
a "eon x0, x13, x20" a00134ca
a "eon x0, x13, x20, ror 15" a03df4ca
a "adrp x5, 0x0" 05000090
ad "adrp x0, 0x11341000" e07fff90 0x12345678
ad "adrp x0, 0x18343000" e0ff02d0 0x12345678
a "add x0, x1, x2" 2000028b
a "add x0, xzr, x30" e0031e8b
a "b 0x0" 00000014
@ -428,7 +430,7 @@ d "add w1, w2, w2, lsl 10" 4128020b 0x0 (set x1 (cast 64 false (+ (cast 32 false
d "add w1, w2, w2, lsr 12" 4130420b 0x0 (set x1 (cast 64 false (+ (cast 32 false (var x2)) (>> (cast 32 false (var x2)) (bv 6 0xc) false))))
d "add w1, w2, w2, asr 31" 417c820b 0x0 (set x1 (cast 64 false (+ (cast 32 false (var x2)) (>> (cast 32 false (var x2)) (bv 6 0x1f) (msb (cast 32 false (var x2)))))))
d "adr x2, 0x10042" 02020050 0x10000 (set x2 (bv 64 0x10042))
d "adrp x2, 0x4000" 020000b0 0x3210 (set x2 (bv 64 0x4000))
ad "adrp x2, 0x4000" 020000b0 0x3210 (set x2 (bv 64 0x4000))
d "and x1, x2, x3" 4100038a 0x0 (set x1 (& (var x2) (var x3)))
d "and w1, w2, w3" 4100030a 0x0 (set x1 (cast 64 false (& (cast 32 false (var x2)) (cast 32 false (var x3)))))
d "ands x1, x2, x3" 410003ea 0x0 (seq (set x1 (& (var x2) (var x3))) (set zf (is_zero (var x1))) (set nf (msb (var x1))) (set cf false) (set vf false))