mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-14 00:38:55 +00:00
Add short jumps to nz (#5832)
This commit is contained in:
parent
cecc994541
commit
8ab5f5fb5b
@ -110,6 +110,7 @@ typedef struct Opcode_t {
|
|||||||
char *mnemonic;
|
char *mnemonic;
|
||||||
ut32 op[3];
|
ut32 op[3];
|
||||||
size_t op_len;
|
size_t op_len;
|
||||||
|
bool is_short;
|
||||||
ut8 opcode[3];
|
ut8 opcode[3];
|
||||||
Operand operands[2];
|
Operand operands[2];
|
||||||
} Opcode;
|
} Opcode;
|
||||||
@ -785,6 +786,9 @@ static int opjc(RAsm *a, ut8 *data, const Opcode op) {
|
|||||||
int l = 0;
|
int l = 0;
|
||||||
ut64 instr_offset = a->pc;
|
ut64 instr_offset = a->pc;
|
||||||
int immediate = op.operands[0].immediate * op.operands[0].sign;
|
int immediate = op.operands[0].immediate * op.operands[0].sign;
|
||||||
|
if (op.is_short && (immediate > ST8_MAX || immediate < ST8_MIN)) {
|
||||||
|
return l;
|
||||||
|
}
|
||||||
if (!strcmp (op.mnemonic, "jmp")) {
|
if (!strcmp (op.mnemonic, "jmp")) {
|
||||||
if (op.operands[0].type & OT_GPREG) {
|
if (op.operands[0].type & OT_GPREG) {
|
||||||
data[l++] = 0xff;
|
data[l++] = 0xff;
|
||||||
@ -807,59 +811,70 @@ static int opjc(RAsm *a, ut8 *data, const Opcode op) {
|
|||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
immediate -= 6;
|
if (op.is_short) {
|
||||||
data[l++] = 0x0f;
|
immediate -= 2;
|
||||||
|
} else {
|
||||||
|
immediate -= 6;
|
||||||
|
}
|
||||||
|
if (!op.is_short) {data[l++] = 0x0f;}
|
||||||
if (!strcmp (op.mnemonic, "ja") ||
|
if (!strcmp (op.mnemonic, "ja") ||
|
||||||
!strcmp (op.mnemonic, "jnbe")) {
|
!strcmp (op.mnemonic, "jnbe")) {
|
||||||
data[l++] = 0x87;
|
data[l++] = 0x87;
|
||||||
} else if (!strcmp (op.mnemonic, "jae") ||
|
} else if (!strcmp (op.mnemonic, "jae") ||
|
||||||
!strcmp (op.mnemonic, "jnb") ||
|
!strcmp (op.mnemonic, "jnb") ||
|
||||||
!strcmp (op.mnemonic, "jnc")) {
|
!strcmp (op.mnemonic, "jnc")) {
|
||||||
data[l++] = 0x83;
|
data[l++] = 0x83;
|
||||||
} else if (!strcmp (op.mnemonic, "jz") ||
|
} else if (!strcmp (op.mnemonic, "jz") ||
|
||||||
!strcmp (op.mnemonic, "je")) {
|
!strcmp (op.mnemonic, "je")) {
|
||||||
data[l++] = 0x84;
|
data[l++] = 0x84;
|
||||||
} else if (!strcmp (op.mnemonic, "jb") ||
|
} else if (!strcmp (op.mnemonic, "jb") ||
|
||||||
!strcmp (op.mnemonic, "jnae") ||
|
!strcmp (op.mnemonic, "jnae") ||
|
||||||
!strcmp (op.mnemonic, "jc")) {
|
!strcmp (op.mnemonic, "jc")) {
|
||||||
data[l++] = 0x82;
|
data[l++] = 0x82;
|
||||||
} else if (!strcmp (op.mnemonic, "jbe") ||
|
} else if (!strcmp (op.mnemonic, "jbe") ||
|
||||||
!strcmp (op.mnemonic, "jna")) {
|
!strcmp (op.mnemonic, "jna")) {
|
||||||
data[l++] = 0x86;
|
data[l++] = 0x86;
|
||||||
} else if (!strcmp (op.mnemonic, "jg")) {
|
} else if (!strcmp (op.mnemonic, "jg") ||
|
||||||
|
!strcmp (op.mnemonic, "jnle")) {
|
||||||
data[l++] = 0x8f;
|
data[l++] = 0x8f;
|
||||||
} else if (!strcmp (op.mnemonic, "jge") ||
|
} else if (!strcmp (op.mnemonic, "jge") ||
|
||||||
!strcmp (op.mnemonic, "jnl")) {
|
!strcmp (op.mnemonic, "jnl")) {
|
||||||
data[l++] = 0x8d;
|
data[l++] = 0x8d;
|
||||||
} else if (!strcmp (op.mnemonic, "jl") ||
|
} else if (!strcmp (op.mnemonic, "jl") ||
|
||||||
!strcmp (op.mnemonic, "jnge")) {
|
!strcmp (op.mnemonic, "jnge")) {
|
||||||
data[l++] = 0x8c;
|
data[l++] = 0x8c;
|
||||||
} else if (!strcmp (op.mnemonic, "jle") ||
|
} else if (!strcmp (op.mnemonic, "jle") ||
|
||||||
!strcmp (op.mnemonic, "jng")) {
|
!strcmp (op.mnemonic, "jng")) {
|
||||||
data[l++] = 0x8e;
|
data[l++] = 0x8e;
|
||||||
} else if (!strcmp (op.mnemonic, "jne") ||
|
} else if (!strcmp (op.mnemonic, "jne") ||
|
||||||
!strcmp (op.mnemonic, "jnz")) {
|
!strcmp (op.mnemonic, "jnz")) {
|
||||||
data[l++] = 0x85;
|
data[l++] = 0x85;
|
||||||
} else if (!strcmp (op.mnemonic, "jno")) {
|
} else if (!strcmp (op.mnemonic, "jno")) {
|
||||||
data[l++] = 0x81;
|
data[l++] = 0x81;
|
||||||
} else if (!strcmp (op.mnemonic, "jnp")) {
|
} else if (!strcmp (op.mnemonic, "jnp") ||
|
||||||
|
!strcmp (op.mnemonic, "jpo")) {
|
||||||
data[l++] = 0x8b;
|
data[l++] = 0x8b;
|
||||||
} else if (!strcmp (op.mnemonic, "jns")) {
|
} else if (!strcmp (op.mnemonic, "jns")) {
|
||||||
data[l++] = 0x89;
|
data[l++] = 0x89;
|
||||||
} else if (!strcmp (op.mnemonic, "jo")) {
|
} else if (!strcmp (op.mnemonic, "jo")) {
|
||||||
data[l++] = 0x80;
|
data[l++] = 0x80;
|
||||||
} else if (!strcmp (op.mnemonic, "jp") ||
|
} else if (!strcmp (op.mnemonic, "jp") ||
|
||||||
!strcmp(op.mnemonic, "jpe")) {
|
!strcmp(op.mnemonic, "jpe")) {
|
||||||
data[l++] = 0x8a;
|
data[l++] = 0x8a;
|
||||||
} else if (!strcmp (op.mnemonic, "js") ||
|
} else if (!strcmp (op.mnemonic, "js") ||
|
||||||
!strcmp (op.mnemonic, "jz") ||
|
!strcmp (op.mnemonic, "jz")) {
|
||||||
!strcmp (op.mnemonic, "jpo")) {
|
|
||||||
data[l++] = 0x88;
|
data[l++] = 0x88;
|
||||||
}
|
}
|
||||||
|
if (op.is_short) {
|
||||||
|
data[l-1] -= 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
data[l++] = immediate;
|
data[l++] = immediate;
|
||||||
data[l++] = immediate >> 8;
|
if (!op.is_short) {
|
||||||
data[l++] = immediate >> 16;
|
data[l++] = immediate >> 8;
|
||||||
data[l++] = immediate >> 24;
|
data[l++] = immediate >> 16;
|
||||||
|
data[l++] = immediate >> 24;
|
||||||
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1525,6 +1540,7 @@ LookupTable oplookup[] = {
|
|||||||
{"jae", &opjc, 0},
|
{"jae", &opjc, 0},
|
||||||
{"jb", &opjc, 0},
|
{"jb", &opjc, 0},
|
||||||
{"jbe", &opjc, 0},
|
{"jbe", &opjc, 0},
|
||||||
|
{"jc", &opjc, 0},
|
||||||
{"je", &opjc, 0},
|
{"je", &opjc, 0},
|
||||||
{"jg", &opjc, 0},
|
{"jg", &opjc, 0},
|
||||||
{"jge", &opjc, 0},
|
{"jge", &opjc, 0},
|
||||||
@ -1533,11 +1549,14 @@ LookupTable oplookup[] = {
|
|||||||
{"jmp", &opjc, 0},
|
{"jmp", &opjc, 0},
|
||||||
{"jna", &opjc, 0},
|
{"jna", &opjc, 0},
|
||||||
{"jnae", &opjc, 0},
|
{"jnae", &opjc, 0},
|
||||||
|
{"jnb", &opjc, 0},
|
||||||
{"jnbe", &opjc, 0},
|
{"jnbe", &opjc, 0},
|
||||||
|
{"jnc", &opjc, 0},
|
||||||
{"jne", &opjc, 0},
|
{"jne", &opjc, 0},
|
||||||
{"jng", &opjc, 0},
|
{"jng", &opjc, 0},
|
||||||
{"jnge", &opjc, 0},
|
{"jnge", &opjc, 0},
|
||||||
{"jnl", &opjc, 0},
|
{"jnl", &opjc, 0},
|
||||||
|
{"jnle", &opjc, 0},
|
||||||
{"jno", &opjc, 0},
|
{"jno", &opjc, 0},
|
||||||
{"jnp", &opjc, 0},
|
{"jnp", &opjc, 0},
|
||||||
{"jns", &opjc, 0},
|
{"jns", &opjc, 0},
|
||||||
@ -1986,12 +2005,18 @@ static int parseOpcode(RAsm *a, const char *op, Opcode *out) {
|
|||||||
out->operands[0].immediate = out->operands[1].immediate = 0;
|
out->operands[0].immediate = out->operands[1].immediate = 0;
|
||||||
out->operands[0].sign = out->operands[1].sign = 1;
|
out->operands[0].sign = out->operands[1].sign = 1;
|
||||||
out->operands[0].is_good_flag = out->operands[1].is_good_flag = true;
|
out->operands[0].is_good_flag = out->operands[1].is_good_flag = true;
|
||||||
|
out->is_short = false;
|
||||||
if (args) {
|
if (args) {
|
||||||
args++;
|
args++;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strncasecmp (args, "short", 5)) {
|
||||||
|
out->is_short = true;
|
||||||
|
args += 5;
|
||||||
|
}
|
||||||
|
|
||||||
parseOperand (a, args, &(out->operands[0]));
|
parseOperand (a, args, &(out->operands[0]));
|
||||||
args = strchr (args, ',');
|
args = strchr (args, ',');
|
||||||
if (args) {
|
if (args) {
|
||||||
@ -2057,7 +2082,7 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//eprintf ("Error: Unknown instruction (%s)\n", instr.mnemonic);
|
//eprintf ("Error: Unknown instruction (%s)\n", instr.mnemonic);
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user