Add short jumps to nz (#5832)

This commit is contained in:
Sven Steinbauer 2016-09-23 16:26:07 +01:00 committed by radare
parent cecc994541
commit 8ab5f5fb5b

View File

@ -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;