Add lowercase_dis option

The lowercase_dis option, if set to true, changes instruction and
register names of disassembler command to lower case. This can be
matched with hexadecimal dump of raw instruction and address.  It also
matches with GNU debugger and assembler.
This commit is contained in:
Tadashi G. Takaoka 2018-04-01 19:34:57 +09:00
parent 7c41acd418
commit 5b9bdbc2aa
3 changed files with 125 additions and 104 deletions

View File

@ -24,6 +24,7 @@
#include "dis.h" #include "dis.h"
#include "util.h" #include "util.h"
#include "opdb.h"
#define ALL_ONES 0xfffff #define ALL_ONES 0xfffff
#define EXTENSION_BIT 0x20000 #define EXTENSION_BIT 0x20000
@ -845,127 +846,128 @@ int dis_decode(const uint8_t *code, address_t offset, address_t len,
static const struct { static const struct {
msp430_op_t op; msp430_op_t op;
const char *mnemonic; const char *const mnemonic;
const char *const lowercase;
} opcode_names[] = { } opcode_names[] = {
/* Single operand */ /* Single operand */
{MSP430_OP_RRC, "RRC"}, {MSP430_OP_RRC, "RRC", "rrc"},
{MSP430_OP_SWPB, "SWPB"}, {MSP430_OP_SWPB, "SWPB", "swpb"},
{MSP430_OP_RRA, "RRA"}, {MSP430_OP_RRA, "RRA", "rra"},
{MSP430_OP_SXT, "SXT"}, {MSP430_OP_SXT, "SXT", "sxt"},
{MSP430_OP_PUSH, "PUSH"}, {MSP430_OP_PUSH, "PUSH", "push"},
{MSP430_OP_CALL, "CALL"}, {MSP430_OP_CALL, "CALL", "call"},
{MSP430_OP_RETI, "RETI"}, {MSP430_OP_RETI, "RETI", "reti"},
/* Jump */ /* Jump */
{MSP430_OP_JNZ, "JNZ"}, {MSP430_OP_JNZ, "JNZ", "jnz"},
{MSP430_OP_JZ, "JZ"}, {MSP430_OP_JZ, "JZ", "jz"},
{MSP430_OP_JNC, "JNC"}, {MSP430_OP_JNC, "JNC", "jnc"},
{MSP430_OP_JC, "JC"}, {MSP430_OP_JC, "JC", "jc"},
{MSP430_OP_JN, "JN"}, {MSP430_OP_JN, "JN", "jn"},
{MSP430_OP_JL, "JL"}, {MSP430_OP_JL, "JL", "jl"},
{MSP430_OP_JGE, "JGE"}, {MSP430_OP_JGE, "JGE", "jge"},
{MSP430_OP_JMP, "JMP"}, {MSP430_OP_JMP, "JMP", "jmp"},
/* Double operand */ /* Double operand */
{MSP430_OP_MOV, "MOV"}, {MSP430_OP_MOV, "MOV", "mov"},
{MSP430_OP_ADD, "ADD"}, {MSP430_OP_ADD, "ADD", "add"},
{MSP430_OP_ADDC, "ADDC"}, {MSP430_OP_ADDC, "ADDC", "addc"},
{MSP430_OP_SUBC, "SUBC"}, {MSP430_OP_SUBC, "SUBC", "subc"},
{MSP430_OP_SUB, "SUB"}, {MSP430_OP_SUB, "SUB", "sub"},
{MSP430_OP_CMP, "CMP"}, {MSP430_OP_CMP, "CMP", "cmp"},
{MSP430_OP_DADD, "DADD"}, {MSP430_OP_DADD, "DADD", "dadd"},
{MSP430_OP_BIT, "BIT"}, {MSP430_OP_BIT, "BIT", "bit"},
{MSP430_OP_BIC, "BIC"}, {MSP430_OP_BIC, "BIC", "bic"},
{MSP430_OP_BIS, "BIS"}, {MSP430_OP_BIS, "BIS", "bis"},
{MSP430_OP_XOR, "XOR"}, {MSP430_OP_XOR, "XOR", "xor"},
{MSP430_OP_AND, "AND"}, {MSP430_OP_AND, "AND", "and"},
/* Emulated instructions */ /* Emulated instructions */
{MSP430_OP_ADC, "ADC"}, {MSP430_OP_ADC, "ADC", "adc"},
{MSP430_OP_BR, "BR"}, {MSP430_OP_BR, "BR", "br"},
{MSP430_OP_CLR, "CLR"}, {MSP430_OP_CLR, "CLR", "clr"},
{MSP430_OP_CLRC, "CLRC"}, {MSP430_OP_CLRC, "CLRC", "clrc"},
{MSP430_OP_CLRN, "CLRN"}, {MSP430_OP_CLRN, "CLRN", "clrn"},
{MSP430_OP_CLRZ, "CLRZ"}, {MSP430_OP_CLRZ, "CLRZ", "clrz"},
{MSP430_OP_DADC, "DADC"}, {MSP430_OP_DADC, "DADC", "dadc"},
{MSP430_OP_DEC, "DEC"}, {MSP430_OP_DEC, "DEC", "dec"},
{MSP430_OP_DECD, "DECD"}, {MSP430_OP_DECD, "DECD", "decd"},
{MSP430_OP_DINT, "DINT"}, {MSP430_OP_DINT, "DINT", "dint"},
{MSP430_OP_EINT, "EINT"}, {MSP430_OP_EINT, "EINT", "eint"},
{MSP430_OP_INC, "INC"}, {MSP430_OP_INC, "INC", "inc"},
{MSP430_OP_INCD, "INCD"}, {MSP430_OP_INCD, "INCD", "incd"},
{MSP430_OP_INV, "INV"}, {MSP430_OP_INV, "INV", "inv"},
{MSP430_OP_NOP, "NOP"}, {MSP430_OP_NOP, "NOP", "nop"},
{MSP430_OP_POP, "POP"}, {MSP430_OP_POP, "POP", "pop"},
{MSP430_OP_RET, "RET"}, {MSP430_OP_RET, "RET", "ret"},
{MSP430_OP_RLA, "RLA"}, {MSP430_OP_RLA, "RLA", "rla"},
{MSP430_OP_RLC, "RLC"}, {MSP430_OP_RLC, "RLC", "rlc"},
{MSP430_OP_SBC, "SBC"}, {MSP430_OP_SBC, "SBC", "sbc"},
{MSP430_OP_SETC, "SETC"}, {MSP430_OP_SETC, "SETC", "setc"},
{MSP430_OP_SETN, "SETN"}, {MSP430_OP_SETN, "SETN", "setn"},
{MSP430_OP_SETZ, "SETZ"}, {MSP430_OP_SETZ, "SETZ", "setz"},
{MSP430_OP_TST, "TST"}, {MSP430_OP_TST, "TST", "tst"},
/* MSP430X double operand (extension word) */ /* MSP430X double operand (extension word) */
{MSP430_OP_MOVX, "MOVX"}, {MSP430_OP_MOVX, "MOVX", "movx"},
{MSP430_OP_ADDX, "ADDX"}, {MSP430_OP_ADDX, "ADDX", "addx"},
{MSP430_OP_ADDCX, "ADDCX"}, {MSP430_OP_ADDCX, "ADDCX", "addcx"},
{MSP430_OP_SUBCX, "SUBCX"}, {MSP430_OP_SUBCX, "SUBCX", "subcx"},
{MSP430_OP_SUBX, "SUBX"}, {MSP430_OP_SUBX, "SUBX", "subx"},
{MSP430_OP_CMPX, "CMPX"}, {MSP430_OP_CMPX, "CMPX", "cmpx"},
{MSP430_OP_DADDX, "DADDX"}, {MSP430_OP_DADDX, "DADDX", "daddx"},
{MSP430_OP_BITX, "BITX"}, {MSP430_OP_BITX, "BITX", "bitx"},
{MSP430_OP_BICX, "BICX"}, {MSP430_OP_BICX, "BICX", "bicx"},
{MSP430_OP_BISX, "BISX"}, {MSP430_OP_BISX, "BISX", "bisx"},
{MSP430_OP_XORX, "XORX"}, {MSP430_OP_XORX, "XORX", "xorx"},
{MSP430_OP_ANDX, "ANDX"}, {MSP430_OP_ANDX, "ANDX", "andx"},
/* MSP430X single operand (extension word) */ /* MSP430X single operand (extension word) */
{MSP430_OP_RRCX, "RRCX"}, {MSP430_OP_RRCX, "RRCX", "rrcx"},
{MSP430_OP_RRUX, "RRUX"}, {MSP430_OP_RRUX, "RRUX", "rrux"},
{MSP430_OP_SWPBX, "SWPBX"}, {MSP430_OP_SWPBX, "SWPBX", "swpbx"},
{MSP430_OP_RRAX, "RRAX"}, {MSP430_OP_RRAX, "RRAX", "rrax"},
{MSP430_OP_SXTX, "SXTX"}, {MSP430_OP_SXTX, "SXTX", "sxtx"},
{MSP430_OP_PUSHX, "PUSHX"}, {MSP430_OP_PUSHX, "PUSHX", "pushx"},
/* MSP430X group 13xx */ /* MSP430X group 13xx */
{MSP430_OP_CALLA, "CALLA"}, {MSP430_OP_CALLA, "CALLA", "calla"},
/* MSP430X group 14xx */ /* MSP430X group 14xx */
{MSP430_OP_PUSHM, "PUSHM"}, {MSP430_OP_PUSHM, "PUSHM", "pushm"},
{MSP430_OP_POPM, "POPM"}, {MSP430_OP_POPM, "POPM", "popm"},
/* MSP430X address instructions */ /* MSP430X address instructions */
{MSP430_OP_MOVA, "MOVA"}, {MSP430_OP_MOVA, "MOVA", "mova"},
{MSP430_OP_CMPA, "CMPA"}, {MSP430_OP_CMPA, "CMPA", "cmpa"},
{MSP430_OP_SUBA, "SUBA"}, {MSP430_OP_SUBA, "SUBA", "suba"},
{MSP430_OP_ADDA, "ADDA"}, {MSP430_OP_ADDA, "ADDA", "adda"},
/* MSP430X group 00xx, non-address */ /* MSP430X group 00xx, non-address */
{MSP430_OP_RRCM, "RRCM"}, {MSP430_OP_RRCM, "RRCM", "rrcm"},
{MSP430_OP_RRAM, "RRAM"}, {MSP430_OP_RRAM, "RRAM", "rram"},
{MSP430_OP_RLAM, "RLAM"}, {MSP430_OP_RLAM, "RLAM", "rlam"},
{MSP430_OP_RRUM, "RRUM"}, {MSP430_OP_RRUM, "RRUM", "rrum"},
/* MSP430X emulated instructions */ /* MSP430X emulated instructions */
{MSP430_OP_ADCX, "ADCX"}, {MSP430_OP_ADCX, "ADCX", "adcx"},
{MSP430_OP_BRA, "BRA"}, {MSP430_OP_BRA, "BRA", "bra"},
{MSP430_OP_RETA, "RETA"}, {MSP430_OP_RETA, "RETA", "reta"},
{MSP430_OP_CLRX, "CLRX"}, {MSP430_OP_CLRX, "CLRX", "clrx"},
{MSP430_OP_DADCX, "DADCX"}, {MSP430_OP_DADCX, "DADCX", "dadcx"},
{MSP430_OP_DECX, "DECX"}, {MSP430_OP_DECX, "DECX", "decx"},
{MSP430_OP_DECDA, "DECDA"}, {MSP430_OP_DECDA, "DECDA", "decda"},
{MSP430_OP_DECDX, "DECDX"}, {MSP430_OP_DECDX, "DECDX", "decdx"},
{MSP430_OP_INCX, "INCX"}, {MSP430_OP_INCX, "INCX", "incx"},
{MSP430_OP_INCDA, "INCDA"}, {MSP430_OP_INCDA, "INCDA", "incda"},
{MSP430_OP_INVX, "INVX"}, {MSP430_OP_INVX, "INVX", "invx"},
{MSP430_OP_RLAX, "RLAX"}, {MSP430_OP_RLAX, "RLAX", "rlax"},
{MSP430_OP_RLCX, "RLCX"}, {MSP430_OP_RLCX, "RLCX", "rlcx"},
{MSP430_OP_SECX, "SECX"}, {MSP430_OP_SECX, "SECX", "secx"},
{MSP430_OP_TSTA, "TSTA"}, {MSP430_OP_TSTA, "TSTA", "tsta"},
{MSP430_OP_TSTX, "TSTX"}, {MSP430_OP_TSTX, "TSTX", "tstx"},
{MSP430_OP_POPX, "POPX"}, {MSP430_OP_POPX, "POPX", "popx"},
{MSP430_OP_INCDX, "INCDX"} {MSP430_OP_INCDX, "INCDX", "incdx"}
}; };
/* Return the mnemonic for an operation, if possible. */ /* Return the mnemonic for an operation, if possible. */
@ -975,7 +977,9 @@ const char *dis_opcode_name(msp430_op_t op)
for (i = 0; i < ARRAY_LEN(opcode_names); i++) for (i = 0; i < ARRAY_LEN(opcode_names); i++)
if (op == opcode_names[i].op) if (op == opcode_names[i].op)
return opcode_names[i].mnemonic; return opdb_get_boolean("lowercase_dis")
? opcode_names[i].lowercase
: opcode_names[i].mnemonic;
return NULL; return NULL;
} }
@ -997,6 +1001,12 @@ static const char *const msp430_reg_names[] = {
"R8", "R9", "R10", "R11", "R8", "R9", "R10", "R11",
"R12", "R13", "R14", "R15" "R12", "R13", "R14", "R15"
}; };
static const char *const msp430_reg_lowercases[] = {
"pc", "sp", "sr", "r3",
"r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11",
"r12", "r13", "r14", "r15"
};
int dis_reg_from_name(const char *name) int dis_reg_from_name(const char *name)
{ {
@ -1026,7 +1036,9 @@ int dis_reg_from_name(const char *name)
const char *dis_reg_name(msp430_reg_t reg) const char *dis_reg_name(msp430_reg_t reg)
{ {
if (reg <= 15) if (reg <= 15)
return msp430_reg_names[reg]; return opdb_get_boolean("lowercase_dis")
? msp430_reg_lowercases[reg]
: msp430_reg_names[reg];
return NULL; return NULL;
} }

View File

@ -113,7 +113,14 @@ static const struct opdb_key keys[] = {
"\x1b[1mWARNING: this is an irreversible operation!\x1b[0m\n" "\x1b[1mWARNING: this is an irreversible operation!\x1b[0m\n"
"\n" "\n"
"If in doubt, do not enable this option.\n" "If in doubt, do not enable this option.\n"
} },
{
.name = "lowercase_dis",
.type = OPDB_TYPE_BOOLEAN,
.help =
"If set, disassembled instruction and register name are displayed in\n"
"lowercase.\n"
},
}; };
static union opdb_value values[ARRAY_LEN(keys)]; static union opdb_value values[ARRAY_LEN(keys)];

View File

@ -26,6 +26,7 @@
#include "stab.h" #include "stab.h"
#include "util.h" #include "util.h"
#include "demangle.h" #include "demangle.h"
#include "opdb.h"
static int format_addr(msp430_amode_t amode, address_t addr) static int format_addr(msp430_amode_t amode, address_t addr)
{ {
@ -111,14 +112,15 @@ static int dis_format(const struct msp430_instruction *insn)
int len = 0; int len = 0;
const char *opname = dis_opcode_name(insn->op); const char *opname = dis_opcode_name(insn->op);
const char *suffix = ""; const char *suffix = "";
const int lowercase = opdb_get_boolean("lowercase_dis");
if (!opname) if (!opname)
opname = "???"; opname = "???";
if (insn->dsize == MSP430_DSIZE_BYTE) if (insn->dsize == MSP430_DSIZE_BYTE)
suffix = ".B"; suffix = lowercase ? ".b" : ".B";
else if (insn->dsize == MSP430_DSIZE_AWORD) else if (insn->dsize == MSP430_DSIZE_AWORD)
suffix = ".A"; suffix = lowercase ? ".a" : ".A";
else if (insn->dsize == MSP430_DSIZE_UNKNOWN) else if (insn->dsize == MSP430_DSIZE_UNKNOWN)
suffix = ".?"; suffix = ".?";