mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-29 08:01:04 +00:00
Fix null derefs in anal.avr plugin and improve defaults ##anal
This commit is contained in:
parent
cdd4748192
commit
0da98904c1
@ -15,8 +15,6 @@ https://en.wikipedia.org/wiki/Atmel_AVR_instruction_set
|
||||
|
||||
#include "../../asm/arch/avr/disasm.h"
|
||||
|
||||
static RDESContext desctx;
|
||||
|
||||
typedef struct _cpu_const_tag {
|
||||
const char *const key;
|
||||
ut8 type;
|
||||
@ -36,6 +34,9 @@ typedef struct _cpu_model_tag {
|
||||
CPU_CONST *consts[10];
|
||||
} CPU_MODEL;
|
||||
|
||||
static R_TH_LOCAL RDESContext desctx;
|
||||
static R_TH_LOCAL CPU_MODEL *Gcpu = NULL;
|
||||
|
||||
typedef void (*inst_handler_t) (RAnal *anal, RAnalOp *op, const ut8 *buf, int len, int *fail, CPU_MODEL *cpu);
|
||||
|
||||
typedef struct _opcodes_tag_ {
|
||||
@ -58,7 +59,7 @@ static OPCODE_DESC* avr_op_analyze(RAnal *anal, RAnalOp *op, ut64 addr, const ut
|
||||
}
|
||||
#define MASK(bits) ((bits) == 32 ? 0xffffffff : (~((~((ut32) 0)) << (bits))))
|
||||
#define CPU_PC_MASK(cpu) MASK((cpu)->pc)
|
||||
#define CPU_PC_SIZE(cpu) ((((cpu)->pc) >> 3) + ((((cpu)->pc) & 0x07) ? 1 : 0))
|
||||
#define CPU_PC_SIZE(cpu) cpu? ((((cpu)->pc) >> 3) + ((((cpu)->pc) & 0x07) ? 1 : 0)): 0
|
||||
|
||||
#define INST_HANDLER(OPCODE_NAME) static void _inst__ ## OPCODE_NAME (RAnal *anal, RAnalOp *op, const ut8 *buf, int len, int *fail, CPU_MODEL *cpu)
|
||||
#define INST_DECL(OP, M, SL, C, SZ, T) { #OP, (M), (SL), _inst__ ## OP, (C), (SZ), R_ANAL_OP_TYPE_ ## T }
|
||||
@ -143,7 +144,8 @@ CPU_MODEL cpu_models[] = {
|
||||
// CPU_MODEL_DECL ("ATmega168", 13, 512, 512),
|
||||
// last model is the default AVR - ATmega8 forever!
|
||||
{
|
||||
.model = "ATmega8", .pc = 13,
|
||||
.model = "ATmega8",
|
||||
.pc = 13,
|
||||
.consts = {
|
||||
cpu_reg_common,
|
||||
cpu_memsize_common,
|
||||
@ -159,34 +161,31 @@ static CPU_MODEL *get_cpu_model(const char *model);
|
||||
|
||||
static CPU_MODEL *__get_cpu_model_recursive(const char *model) {
|
||||
CPU_MODEL *cpu = NULL;
|
||||
|
||||
for (cpu = cpu_models; cpu < cpu_models + ((sizeof (cpu_models) / sizeof (CPU_MODEL))) - 1; cpu++) {
|
||||
if (!r_str_casecmp (model, cpu->model)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// fix inheritance tree
|
||||
if (cpu->inherit && !cpu->inherit_cpu_p) {
|
||||
if (cpu && cpu->inherit && !cpu->inherit_cpu_p) {
|
||||
cpu->inherit_cpu_p = get_cpu_model (cpu->inherit);
|
||||
if (!cpu->inherit_cpu_p) {
|
||||
eprintf ("ERROR: Cannot inherit from unknown CPU model '%s'.\n", cpu->inherit);
|
||||
R_LOG_ERROR ("Cannot inherit from unknown CPU model '%s'.", cpu->inherit);
|
||||
}
|
||||
}
|
||||
|
||||
return cpu;
|
||||
}
|
||||
|
||||
static CPU_MODEL *get_cpu_model(const char *model) {
|
||||
static CPU_MODEL *cpu = NULL;
|
||||
if (!model) {
|
||||
return NULL;
|
||||
model = "ATmega8";
|
||||
}
|
||||
// cache
|
||||
if (cpu && cpu->model && !r_str_casecmp (model, cpu->model)) {
|
||||
return cpu;
|
||||
if (Gcpu && Gcpu->model && !r_str_casecmp (model, Gcpu->model)) {
|
||||
return Gcpu;
|
||||
}
|
||||
return cpu = __get_cpu_model_recursive (model);
|
||||
Gcpu = __get_cpu_model_recursive (model);
|
||||
return Gcpu;
|
||||
}
|
||||
|
||||
static ut32 const_get_value(CPU_CONST *c) {
|
||||
@ -195,11 +194,13 @@ static ut32 const_get_value(CPU_CONST *c) {
|
||||
|
||||
static CPU_CONST *const_by_name(CPU_MODEL *cpu, int type, char *c) {
|
||||
CPU_CONST **clist, *citem;
|
||||
if (!cpu) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (clist = cpu->consts; *clist; clist++) {
|
||||
for (citem = *clist; citem->key; citem++) {
|
||||
if (!strcmp (c, citem->key)
|
||||
&& (type == CPU_CONST_NONE || type == citem->type)) {
|
||||
if (!strcmp (c, citem->key) && (type == CPU_CONST_NONE || type == citem->type)) {
|
||||
return citem;
|
||||
}
|
||||
}
|
||||
@ -207,7 +208,7 @@ static CPU_CONST *const_by_name(CPU_MODEL *cpu, int type, char *c) {
|
||||
if (cpu->inherit_cpu_p) {
|
||||
return const_by_name (cpu->inherit_cpu_p, type, c);
|
||||
}
|
||||
eprintf ("ERROR: CONSTANT key[%s] NOT FOUND.\n", c);
|
||||
R_LOG_ERROR ("CONSTANT key[%s] NOT FOUND.", c);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -482,14 +483,18 @@ INST_HANDLER (call) { // CALL k
|
||||
| (buf[0] & 0x01) << 17
|
||||
| (buf[0] & 0xf0) << 14;
|
||||
op->fail = op->addr + op->size;
|
||||
op->cycles = cpu->pc <= 16 ? 3 : 4;
|
||||
if (!STR_BEGINS (cpu->model, "ATxmega")) {
|
||||
op->cycles--; // AT*mega optimizes one cycle
|
||||
if (cpu) {
|
||||
op->cycles = cpu->pc <= 16 ? 3 : 4;
|
||||
if (!STR_BEGINS (cpu->model, "ATxmega")) {
|
||||
op->cycles--; // AT*mega optimizes one cycle
|
||||
}
|
||||
ESIL_A ("pc,"); // esil is already pointing to
|
||||
// next instruction (@ret)
|
||||
__generic_push (op, CPU_PC_SIZE (cpu)); // push @ret in stack
|
||||
ESIL_A ("%"PFMT64d",pc,=,", op->jump); // jump!
|
||||
} else {
|
||||
op->cycles = 1;
|
||||
}
|
||||
ESIL_A ("pc,"); // esil is already pointing to
|
||||
// next instruction (@ret)
|
||||
__generic_push (op, CPU_PC_SIZE (cpu)); // push @ret in stack
|
||||
ESIL_A ("%"PFMT64d",pc,=,", op->jump); // jump!
|
||||
}
|
||||
|
||||
INST_HANDLER (cbi) { // CBI A, b
|
||||
@ -1115,23 +1120,20 @@ INST_HANDLER (pop) { // POP Rd
|
||||
int d = ((buf[1] & 0x1) << 4) | ((buf[0] >> 4) & 0xf);
|
||||
__generic_pop (op, 1);
|
||||
ESIL_A ("r%d,=,", d); // store in Rd
|
||||
|
||||
}
|
||||
|
||||
INST_HANDLER (push) { // PUSH Rr
|
||||
INST_HANDLER(push) { // PUSH Rr
|
||||
if (len < 2) {
|
||||
return;
|
||||
}
|
||||
int r = ((buf[1] & 0x1) << 4) | ((buf[0] >> 4) & 0xf);
|
||||
ESIL_A ("r%d,", r); // load Rr
|
||||
__generic_push (op, 1); // push it into stack
|
||||
// cycles
|
||||
op->cycles = !STR_BEGINS (cpu->model, "ATxmega")
|
||||
? 1 // AT*mega optimizes one cycle
|
||||
: 2;
|
||||
ESIL_A ("r%d,", r); // load Rr
|
||||
__generic_push (op, 1); // push it into stack
|
||||
// AT*mega optimizes one cycle
|
||||
op->cycles = !STR_BEGINS (cpu->model, "ATxmega") ?1: 2;
|
||||
}
|
||||
|
||||
INST_HANDLER (rcall) { // RCALL k
|
||||
INST_HANDLER(rcall) { // RCALL k
|
||||
if (len < 2) {
|
||||
return;
|
||||
}
|
||||
@ -1697,8 +1699,7 @@ static int avr_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len,
|
||||
|
||||
int size = avr_anal (anal, mnemonic, sizeof (mnemonic), addr, buf, len);
|
||||
|
||||
if (!strcmp (mnemonic, "invalid")
|
||||
|| !strcmp (mnemonic, "truncated")) {
|
||||
if (!strcmp (mnemonic, "invalid") || !strcmp (mnemonic, "truncated")) {
|
||||
op->eob = true;
|
||||
op->mnemonic = strdup (mnemonic);
|
||||
op->size = 2;
|
||||
@ -1713,7 +1714,7 @@ static int avr_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len,
|
||||
ut64 offset = 0;
|
||||
r_anal_esil_reg_write (anal->esil, "_prog", offset);
|
||||
|
||||
offset += (1ULL << cpu->pc);
|
||||
offset += (1ULL << (cpu ? cpu->pc: 8));
|
||||
r_anal_esil_reg_write (anal->esil, "_io", offset);
|
||||
|
||||
offset += const_get_value (const_by_name (cpu, CPU_CONST_PARAM, "sram_start"));
|
||||
@ -2357,12 +2358,26 @@ RAnalPlugin r_anal_plugin_avr = {
|
||||
.arch = "avr",
|
||||
.esil = true,
|
||||
.archinfo = archinfo,
|
||||
.endian = R_SYS_ENDIAN_LITTLE | R_SYS_ENDIAN_BIG,
|
||||
.bits = 8 | 16, // 24 big regs conflicts
|
||||
.op = &avr_op,
|
||||
.set_reg_profile = &set_reg_profile,
|
||||
.esil_init = esil_avr_init,
|
||||
.esil_fini = esil_avr_fini,
|
||||
.anal_mask = anal_mask_avr
|
||||
.anal_mask = anal_mask_avr,
|
||||
.cpus =
|
||||
"ATmega8," // First one is default
|
||||
"ATmega1280,"
|
||||
"ATmega1281,"
|
||||
"ATmega168,"
|
||||
"ATmega2560,"
|
||||
"ATmega2561,"
|
||||
"ATmega328p,"
|
||||
"ATmega32u4,"
|
||||
"ATmega48,"
|
||||
"ATmega640,"
|
||||
"ATmega88,"
|
||||
"ATxmega128a4u"
|
||||
};
|
||||
|
||||
#ifndef R2_PLUGIN_INCORE
|
||||
|
@ -126,7 +126,7 @@ static int archinfo(RAnal *anal, int q) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
RAnalPlugin r_anal_plugin_s390_gnu= {
|
||||
RAnalPlugin r_anal_plugin_s390_gnu = {
|
||||
.name = "s390.gnu",
|
||||
.desc = "SystemZ S390 from binutils",
|
||||
.esil = false,
|
||||
|
@ -38,106 +38,6 @@
|
||||
static int disassembleOperands(disassembledInstruction *dInstruction);
|
||||
/* Extracts certain bits of data from a mask, used to extract operands from their encoding in the opcode. */
|
||||
static uint16_t extractDataFromMask(uint16_t data, uint16_t mask);
|
||||
/* Look up an instruction by it's opcode in the instructionSet,
|
||||
* starting from index offset. Always returns a valid instruction
|
||||
* index because the last instruction in the instruction set database
|
||||
* is set to be a generic data word (.DW). */
|
||||
static int lookupInstruction(uint16_t opcode, int offset);
|
||||
|
||||
|
||||
/* Disassembles an assembled instruction, including its operands. */
|
||||
int disassembleInstruction(avrDisassembleContext *context, disassembledInstruction *dInstruction, const assembledInstruction aInstruction) {
|
||||
int insidx, i;
|
||||
|
||||
if (!dInstruction || !context)
|
||||
return ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
|
||||
/* Look up the instruction */
|
||||
insidx = lookupInstruction(aInstruction.opcode, 0);
|
||||
if (insidx == AVR_TOTAL_INSTRUCTIONS) {
|
||||
// invalid instruction
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** AVR SPECIFIC */
|
||||
/* If a long instruction was found in the last instruction disassembly,
|
||||
* extract the rest of the address, and indicate that it is to be printed */
|
||||
if (context->status == AVR_LONG_INSTRUCTION_FOUND) {
|
||||
context->status = AVR_LONG_INSTRUCTION_PRINT;
|
||||
context->longAddress |= aInstruction.opcode;
|
||||
/* We must multiply by two, because every instruction is 2 bytes,
|
||||
* so in order to jump/call to the right address (which increments by
|
||||
* two for every instruction), we must multiply this distance by two. */
|
||||
//printf ("ii=%d\n", insidx);
|
||||
if(!strcmp(context->longInstruction.instruction->mnemonic, "call")||
|
||||
!strcmp(context->longInstruction.instruction->mnemonic, "jmp")) {
|
||||
context->longAddress *= 2;
|
||||
}
|
||||
*dInstruction = context->longInstruction;
|
||||
return 0;
|
||||
/* If a long instruction was printed in the last instruction disassembly,
|
||||
* reset the AVR_Call_Instruction variable back to zero. */
|
||||
} else if (context->status == AVR_LONG_INSTRUCTION_PRINT) {
|
||||
context->status = 0;
|
||||
}
|
||||
|
||||
/* Copy over the address, and reference to the instruction, set
|
||||
* the equivilant-encoded but different instruction to NULL for now. */
|
||||
dInstruction->address = aInstruction.address;
|
||||
dInstruction->instruction = &instructionSet[insidx];
|
||||
dInstruction->alternateInstruction = NULL;
|
||||
|
||||
/* Copy out each operand, extracting the operand data from the original
|
||||
* opcode using the operand mask. */
|
||||
for (i = 0; i < instructionSet[insidx].numOperands; i++) {
|
||||
dInstruction->operands[i] = extractDataFromMask(aInstruction.opcode, dInstruction->instruction->operandMasks[i]);
|
||||
/*** AVR SPECIFIC */
|
||||
/* If this is an instruction with a long absolute operand, indicate that a long instruction has been found,
|
||||
* and extract the first part of the long address. */
|
||||
if (dInstruction->instruction->operandTypes[i] == OPERAND_LONG_ABSOLUTE_ADDRESS) {
|
||||
context->status = AVR_LONG_INSTRUCTION_FOUND;
|
||||
context->longAddress = dInstruction->operands[i] << 16;
|
||||
context->longInstruction = *dInstruction;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disassemble operands */
|
||||
if (disassembleOperands(dInstruction) < 0)
|
||||
return ERROR_INVALID_ARGUMENTS; /* Only possible error for disassembleOperands() */
|
||||
|
||||
if (context->status == AVR_LONG_INSTRUCTION_FOUND) {
|
||||
/* If we found a long instruction (32-bit one),
|
||||
* Copy this instruction over to our special longInstruction variable, that
|
||||
* will exist even after we move onto the next 16-bits */
|
||||
context->longInstruction = *dInstruction;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Extracts certain bits of data from a mask, used to extract operands from their encoding in the opcode. */
|
||||
static uint16_t extractDataFromMask(uint16_t data, uint16_t mask) {
|
||||
int i, j;
|
||||
uint16_t result = 0;
|
||||
|
||||
/* i counts through every bit of the data,
|
||||
* j counts through every bit of the data we're copying out. */
|
||||
for (i = 0, j = 0; i < 16; i++) {
|
||||
/* If the mask has a bit in this position */
|
||||
if (mask & (1<<i)) {
|
||||
/* If there is a data bit with this mask bit,
|
||||
* then toggle that bit in the extracted data (result).
|
||||
* Notice that it uses its own bit counter j. */
|
||||
if (((mask & (1<<i)) & data) != 0)
|
||||
result |= (1<<j);
|
||||
/* Increment the extracted data bit count. */
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Look up an instruction by it's opcode in the instructionSet,
|
||||
* starting from index offset. Always returns a valid instruction
|
||||
@ -173,11 +73,12 @@ static int lookupInstruction(uint16_t opcode, int offset) {
|
||||
/* If we encountered a ghost register and were unable confirm that
|
||||
* all register operands were equal (in this case ghostRegisterConfirmed
|
||||
* would have changed), then move the match-search onto the next instruction. */
|
||||
if (ghostRegisterConfirmed == 0)
|
||||
if (ghostRegisterConfirmed == 0) {
|
||||
continue;
|
||||
|
||||
if (opcodeSearch == instructionSet[insidx].opcodeMask)
|
||||
}
|
||||
if (opcodeSearch == instructionSet[insidx].opcodeMask) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* It's impossible not to find an instruction, because the last instruction ".DW",
|
||||
* specifies a word of data at the addresses, instead of an instruction.
|
||||
@ -186,16 +87,108 @@ static int lookupInstruction(uint16_t opcode, int offset) {
|
||||
return insidx;
|
||||
}
|
||||
|
||||
|
||||
/* Disassembles an assembled instruction, including its operands. */
|
||||
int disassembleInstruction(avrDisassembleContext *context, disassembledInstruction *dInstruction, const assembledInstruction aInstruction) {
|
||||
int insidx, i;
|
||||
if (!dInstruction || !context) {
|
||||
return ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
/* Look up the instruction */
|
||||
insidx = lookupInstruction (aInstruction.opcode, 0);
|
||||
if (insidx == AVR_TOTAL_INSTRUCTIONS) {
|
||||
// invalid instruction
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** AVR SPECIFIC */
|
||||
/* If a long instruction was found in the last instruction disassembly,
|
||||
* extract the rest of the address, and indicate that it is to be printed */
|
||||
if (context->status == AVR_LONG_INSTRUCTION_FOUND) {
|
||||
context->status = AVR_LONG_INSTRUCTION_PRINT;
|
||||
context->longAddress |= aInstruction.opcode;
|
||||
/* We must multiply by two, because every instruction is 2 bytes,
|
||||
* so in order to jump/call to the right address (which increments by
|
||||
* two for every instruction), we must multiply this distance by two. */
|
||||
//printf ("ii=%d\n", insidx);
|
||||
if(!strcmp(context->longInstruction.instruction->mnemonic, "call") ||
|
||||
!strcmp(context->longInstruction.instruction->mnemonic, "jmp")) {
|
||||
context->longAddress *= 2;
|
||||
}
|
||||
*dInstruction = context->longInstruction;
|
||||
return 0;
|
||||
/* If a long instruction was printed in the last instruction disassembly,
|
||||
* reset the AVR_Call_Instruction variable back to zero. */
|
||||
} else if (context->status == AVR_LONG_INSTRUCTION_PRINT) {
|
||||
context->status = 0;
|
||||
}
|
||||
|
||||
/* Copy over the address, and reference to the instruction, set
|
||||
* the equivilant-encoded but different instruction to NULL for now. */
|
||||
dInstruction->address = aInstruction.address;
|
||||
dInstruction->instruction = &instructionSet[insidx];
|
||||
dInstruction->alternateInstruction = NULL;
|
||||
|
||||
/* Copy out each operand, extracting the operand data from the original
|
||||
* opcode using the operand mask. */
|
||||
for (i = 0; i < instructionSet[insidx].numOperands; i++) {
|
||||
dInstruction->operands[i] = extractDataFromMask(aInstruction.opcode, dInstruction->instruction->operandMasks[i]);
|
||||
/*** AVR SPECIFIC */
|
||||
/* If this is an instruction with a long absolute operand, indicate that a long instruction has been found,
|
||||
* and extract the first part of the long address. */
|
||||
if (dInstruction->instruction->operandTypes[i] == OPERAND_LONG_ABSOLUTE_ADDRESS) {
|
||||
context->status = AVR_LONG_INSTRUCTION_FOUND;
|
||||
context->longAddress = dInstruction->operands[i] << 16;
|
||||
context->longInstruction = *dInstruction;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disassemble operands */
|
||||
if (disassembleOperands(dInstruction) < 0) {
|
||||
return ERROR_INVALID_ARGUMENTS; /* Only possible error for disassembleOperands() */
|
||||
}
|
||||
|
||||
if (context->status == AVR_LONG_INSTRUCTION_FOUND) {
|
||||
/* If we found a long instruction (32-bit one),
|
||||
* Copy this instruction over to our special longInstruction variable, that
|
||||
* will exist even after we move onto the next 16-bits */
|
||||
context->longInstruction = *dInstruction;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Extracts certain bits of data from a mask, used to extract operands from their encoding in the opcode. */
|
||||
static uint16_t extractDataFromMask(uint16_t data, uint16_t mask) {
|
||||
int i, j;
|
||||
uint16_t result = 0;
|
||||
|
||||
/* i counts through every bit of the data,
|
||||
* j counts through every bit of the data we're copying out. */
|
||||
for (i = 0, j = 0; i < 16; i++) {
|
||||
/* If the mask has a bit in this position */
|
||||
if (mask & (1<<i)) {
|
||||
/* If there is a data bit with this mask bit,
|
||||
* then toggle that bit in the extracted data (result).
|
||||
* Notice that it uses its own bit counter j. */
|
||||
if (((mask & (1<<i)) & data) != 0)
|
||||
result |= (1<<j);
|
||||
/* Increment the extracted data bit count. */
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Disassembles/decodes operands back to their original form. */
|
||||
static int disassembleOperands(disassembledInstruction *dInstruction) {
|
||||
int i;
|
||||
|
||||
/* This should never happen */
|
||||
if (!dInstruction)
|
||||
if (!dInstruction || !dInstruction->instruction) {
|
||||
return ERROR_INVALID_ARGUMENTS;
|
||||
if (!dInstruction->instruction)
|
||||
return ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
}
|
||||
/* For each operand, decode its original value. */
|
||||
for (i = 0; i < dInstruction->instruction->numOperands; i++) {
|
||||
switch (dInstruction->instruction->operandTypes[i]) {
|
||||
|
@ -45,7 +45,7 @@ RAsmPlugin r_asm_plugin_avr = {
|
||||
.name = "avr",
|
||||
.arch = "avr",
|
||||
.license = "GPL",
|
||||
.bits = 8|16,
|
||||
.bits = 8 | 16,
|
||||
.endian = R_SYS_ENDIAN_LITTLE | R_SYS_ENDIAN_BIG,
|
||||
.desc = "AVR Atmel",
|
||||
.disassemble = &disassemble,
|
||||
|
@ -1327,6 +1327,7 @@ typedef struct r_anal_plugin_t {
|
||||
char *arch;
|
||||
char *author;
|
||||
char *version;
|
||||
int endian; // bitmask to define little, big, etc.
|
||||
char *cpus;
|
||||
int bits;
|
||||
int esil; // can do esil or not
|
||||
|
@ -45,7 +45,7 @@ static inline void my_ac_free(RArchConfig *cfg) {
|
||||
|
||||
static inline void r_arch_use(RArchConfig *config, R_NULLABLE const char *arch) {
|
||||
r_return_if_fail (config);
|
||||
R_LOG_DEBUG ("RArch.USE (%s)", arch);
|
||||
// R_LOG_DEBUG ("RArch.USE (%s)", arch);
|
||||
if (arch && !strcmp (arch, "null")) {
|
||||
return;
|
||||
}
|
||||
@ -55,7 +55,7 @@ static inline void r_arch_use(RArchConfig *config, R_NULLABLE const char *arch)
|
||||
|
||||
static inline void r_arch_set_cpu(RArchConfig *config, R_NULLABLE const char *cpu) {
|
||||
r_return_if_fail (config);
|
||||
R_LOG_DEBUG ("RArch.CPU (%s)", cpu);
|
||||
// R_LOG_DEBUG ("RArch.CPU (%s)", cpu);
|
||||
free (config->cpu);
|
||||
config->cpu = R_STR_ISNOTEMPTY (cpu) ? strdup (cpu) : NULL;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ FILE=malloc://1024
|
||||
CMDS=<<EOF
|
||||
e asm.arch=avr
|
||||
e asm.bits=8
|
||||
wx 0xf8 0x94 0x08 0xe0 0x0e 0xbf 0x0f 0xe5 0x0d 0xbf 0x0e 0x94 0x08 0x00 0x88 0x95 0x08 0x95
|
||||
wx f89408e00ebf0fe50dbf0e94080088950895
|
||||
aei
|
||||
aeim 0x00000100 0xffff avr_ram
|
||||
6aeso
|
||||
@ -16,4 +16,4 @@ EXPECT=<<EOF
|
||||
0x0000000e
|
||||
0x0000000e
|
||||
EOF
|
||||
RUN
|
||||
RUN
|
||||
|
Loading…
Reference in New Issue
Block a user