diff --git a/dataflowAPI/rose/semantics/DispatcherARM64.C b/dataflowAPI/rose/semantics/DispatcherARM64.C index d9b2e08a42..3f8ff179df 100644 --- a/dataflowAPI/rose/semantics/DispatcherARM64.C +++ b/dataflowAPI/rose/semantics/DispatcherARM64.C @@ -4,6 +4,7 @@ //#include "Diagnostics.h" #include "DispatcherARM64.h" #include "../integerOps.h" +#include "SymEvalSemantics.h" #undef si_value // name pollution from siginfo.h @@ -941,6 +942,1085 @@ namespace rose { } }; + struct IP_ldr_imm_gen_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch (EXTR(22, 22) ^ EXTR(23, 23)) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_str_imm_gen_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch (EXTR(22, 22) ^ EXTR(23, 23)) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_ldrb_imm_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch (EXTR(22, 22) ^ EXTR(23, 23)) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_strb_imm_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch (EXTR(22, 22) ^ EXTR(23, 23)) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_ldrh_imm_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch (EXTR(22, 22) ^ EXTR(23, 23)) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_ldrsb_imm_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch (EXTR(22, 22) ^ EXTR(23, 23)) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_ldrsh_imm_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch (EXTR(22, 22) ^ EXTR(23, 23)) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_ldrsw_imm_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch (EXTR(22, 22) ^ EXTR(23, 23)) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_strh_imm_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch (EXTR(22, 22) ^ EXTR(23, 23)) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_ldr_reg_gen_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr offset = d->read(args[2]); + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch ((EXTR(22, 22) ^ EXTR(23, 23))) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_ldrb_reg_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr offset = d->read(args[2]); + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch ((EXTR(22, 22) ^ EXTR(23, 23))) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_ldrh_reg_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr offset = d->read(args[2]); + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch ((EXTR(22, 22) ^ EXTR(23, 23))) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_ldrsb_reg_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr offset = d->read(args[2]); + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch ((EXTR(22, 22) ^ EXTR(23, 23))) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_ldrsh_reg_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr offset = d->read(args[2]); + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch ((EXTR(22, 22) ^ EXTR(23, 23))) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_ldrsw_reg_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr offset = d->read(args[2]); + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch ((EXTR(22, 22) ^ EXTR(23, 23))) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_str_reg_gen_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr offset = d->read(args[2]); + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch ((EXTR(22, 22) ^ EXTR(23, 23))) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_strb_reg_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr offset = d->read(args[2]); + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch ((EXTR(22, 22) ^ EXTR(23, 23))) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_strh_reg_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr offset = d->read(args[2]); + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + bool wb_unknown = false; + bool rt_unknown = false; + + if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + switch ((EXTR(22, 22) ^ EXTR(23, 23))) { + case MemOp_STORE: { + + if (rt_unknown) { + data = ops->unspecified_(1); + } + else { + data = d->read(args[0]); + } + d->writeMemory(address, 0x8 << EXTR(30, 31), data); + } + break; + case MemOp_LOAD: { + data = d->readMemory(address, 0x8 << EXTR(30, 31)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, d->getRegSize(raw))); + } + else { + d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw))); + } + } + break; + } + + if ((EXTR(24, 24) == 0)) { + + if (wb_unknown) { + address = ops->unspecified_(1); + } + + else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) { + address = ops->add(address, d->read(args[2])); + } + + if (EXTR(5, 9) == 31) { + d->writeRegister(d->REG_SP, address); + } + else { + d->write(args[1], address); + } + } + + } + }; + + struct IP_ldr_lit_gen_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + + switch ((EXTR(22, 22) ^ EXTR(23, 23))) { + case MemOp_LOAD: { + data = d->readMemory(address, d->ldStrLiteralAccessSize(raw)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, 64)); + } + else { + d->write(args[0], data); + } + } + break; + } + + } + }; + + struct IP_ldrsw_lit_execute : P { + void p(D d, Ops ops, I insn, A args, B raw) { + BaseSemantics::SValuePtr address = d->read(args[1]); + BaseSemantics::SValuePtr data; + + switch ((EXTR(22, 22) ^ EXTR(23, 23))) { + case MemOp_LOAD: { + data = d->readMemory(address, d->ldStrLiteralAccessSize(raw)); + + if ((EXTR(23, 23) == 1)) { + d->write(args[0], d->SignExtend(data, 64)); + } + else { + d->write(args[0], data); + } + } + break; + } + + } + }; + } // namespace @@ -983,7 +2063,26 @@ namespace rose { iproc_set (rose_aarch64_op_cmn_adds_addsub_shift, new ARM64::IP_cmn_adds_addsub_shift_execute); iproc_set (rose_aarch64_op_ccmn_reg, new ARM64::IP_ccmn_reg_execute); iproc_set (rose_aarch64_op_ccmn_imm, new ARM64::IP_ccmn_imm_execute); - + iproc_set (rose_aarch64_op_ldr_imm_gen, new ARM64::IP_ldr_imm_gen_execute); + iproc_set (rose_aarch64_op_str_imm_gen, new ARM64::IP_str_imm_gen_execute); + iproc_set (rose_aarch64_op_ldrb_imm, new ARM64::IP_ldrb_imm_execute); + iproc_set (rose_aarch64_op_strb_imm, new ARM64::IP_strb_imm_execute); + iproc_set (rose_aarch64_op_ldrh_imm, new ARM64::IP_ldrh_imm_execute); + iproc_set (rose_aarch64_op_ldrsb_imm, new ARM64::IP_ldrsb_imm_execute); + iproc_set (rose_aarch64_op_ldrsh_imm, new ARM64::IP_ldrsh_imm_execute); + iproc_set (rose_aarch64_op_ldrsw_imm, new ARM64::IP_ldrsw_imm_execute); + iproc_set (rose_aarch64_op_strh_imm, new ARM64::IP_strh_imm_execute); + iproc_set (rose_aarch64_op_ldr_reg_gen, new ARM64::IP_ldr_reg_gen_execute); + iproc_set (rose_aarch64_op_ldrb_reg, new ARM64::IP_ldrb_reg_execute); + iproc_set (rose_aarch64_op_ldrh_reg, new ARM64::IP_ldrh_reg_execute); + iproc_set (rose_aarch64_op_ldrsb_reg, new ARM64::IP_ldrsb_reg_execute); + iproc_set (rose_aarch64_op_ldrsh_reg, new ARM64::IP_ldrsh_reg_execute); + iproc_set (rose_aarch64_op_ldrsw_reg, new ARM64::IP_ldrsw_reg_execute); + iproc_set (rose_aarch64_op_str_reg_gen, new ARM64::IP_str_reg_gen_execute); + iproc_set (rose_aarch64_op_strb_reg, new ARM64::IP_strb_reg_execute); + iproc_set (rose_aarch64_op_strh_reg, new ARM64::IP_strh_reg_execute); + iproc_set (rose_aarch64_op_ldr_lit_gen, new ARM64::IP_ldr_lit_gen_execute); + iproc_set (rose_aarch64_op_ldrsw_lit, new ARM64::IP_ldrsw_lit_execute); } void @@ -991,7 +2090,7 @@ namespace rose { if (regdict) { REG_PC = findRegister("pc", 64); REG_NZCV = findRegister("nzcv", 4); - REG_SP = findRegister("pc", 64); + REG_SP = findRegister("sp", 64); } } @@ -1155,6 +2254,38 @@ namespace rose { return operators->number_(nbits, 0); } + BaseSemantics::SValuePtr + DispatcherARM64::SignExtend(const BaseSemantics::SValuePtr &expr, size_t newsize) { + ASSERT_require(newsize > 0); + return operators->signExtend(expr, newsize); + } + + BaseSemantics::SValuePtr + DispatcherARM64::ZeroExtend(const BaseSemantics::SValuePtr &expr, size_t newsize) { + ASSERT_require(newsize > 0); + return operators->unsignedExtend(expr, newsize); + } + + size_t + DispatcherARM64::getRegSize(uint32_t raw) { + if(IntegerOps::extract2(23, 23, raw) == 0) { + if(IntegerOps::extract2(30, 31, raw) == 0x3) + return 64; + else + return 32; + } else { + if(IntegerOps::extract2(122, 22, raw) == 1) + return 32; + else + return 64; + } + } + + size_t + DispatcherARM64::ldStrLiteralAccessSize(uint32_t raw) { + return 0; + } + BaseSemantics::SValuePtr DispatcherARM64::doAddOperation(BaseSemantics::SValuePtr a, BaseSemantics::SValuePtr b, bool invertCarries, const BaseSemantics::SValuePtr &carryIn, @@ -1222,6 +2353,22 @@ namespace rose { } return addr; } + + BaseSemantics::SValuePtr + DispatcherARM64::readMemory(const BaseSemantics::SValuePtr &addr, size_t readSize) { + SymEvalSemantics::StateARM64Ptr state = SymEvalSemantics::StateARM64::promote(operators->currentState()); + + //The second, third and fourth arguments will remain and unused and hence these values are used + return state->readMemory(addr, operators->unspecified_(1), NULL, NULL, readSize); + } + + void + DispatcherARM64::writeMemory(const BaseSemantics::SValuePtr &addr, size_t writeSize, const BaseSemantics::SValuePtr &data) { + SymEvalSemantics::StateARM64Ptr state = SymEvalSemantics::StateARM64::promote(operators->currentState()); + + //The third and fourth arguments will remain and unused and hence these values are used + state->writeMemory(addr, data, NULL, NULL, writeSize); + } } // namespace } // namespace } // namespace diff --git a/dataflowAPI/rose/semantics/DispatcherARM64.h b/dataflowAPI/rose/semantics/DispatcherARM64.h index 9b8993b97f..2898955775 100644 --- a/dataflowAPI/rose/semantics/DispatcherARM64.h +++ b/dataflowAPI/rose/semantics/DispatcherARM64.h @@ -185,6 +185,22 @@ namespace rose { /** Returns a value that equals 0. nbits specifies what should be the bit-length of the value, * but is irrelevant in practice as a 64-bit zero is returned anyway. */ virtual BaseSemantics::SValuePtr Zeros(const unsigned int nbits); + + /** Returns the input value sign extended to the provided length. */ + virtual BaseSemantics::SValuePtr SignExtend(const BaseSemantics::SValuePtr &expr, size_t newsize); + + /** Returns the input value zero extended to the provided length. */ + virtual BaseSemantics::SValuePtr ZeroExtend(const BaseSemantics::SValuePtr &expr, size_t newsize); + + size_t getRegSize(uint32_t raw); + + size_t ldStrLiteralAccessSize(uint32_t raw); + + /** */ + BaseSemantics::SValuePtr readMemory(const BaseSemantics::SValuePtr &addr, size_t readSize); + + /** */ + void writeMemory(const BaseSemantics::SValuePtr &addr, size_t writeSize, const BaseSemantics::SValuePtr &data); }; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -213,6 +229,12 @@ namespace rose { virtual void assert_args(I insn, A args, size_t nargs); //void check_arg_width(D d, I insn, A args); + + public: + enum MemOp { + MemOp_STORE, + MemOp_LOAD + }; }; } // namespace diff --git a/dataflowAPI/rose/semantics/SymEvalSemantics.C b/dataflowAPI/rose/semantics/SymEvalSemantics.C index 3cc3d01540..394c18ff2f 100644 --- a/dataflowAPI/rose/semantics/SymEvalSemantics.C +++ b/dataflowAPI/rose/semantics/SymEvalSemantics.C @@ -26,14 +26,25 @@ void SymEvalSemantics::StateARM64::writeRegister(const RegisterDescriptor ®, registers->writeRegister(reg, value, res, aaMap); } +BaseSemantics::SValuePtr SymEvalSemantics::StateARM64::readMemory(const BaseSemantics::SValuePtr &address, + const BaseSemantics::SValuePtr &/*dflt*/, + BaseSemantics::RiscOperators */*addrOps*/, + BaseSemantics::RiscOperators */*valOps*/, + size_t readSize) { + ASSERT_not_null(address); + SymEvalSemantics::MemoryStateARM64Ptr memory = SymEvalSemantics::MemoryStateARM64::promote(memoryState()); + return memory->readMemory(address, readSize); +} + void SymEvalSemantics::StateARM64::writeMemory(const BaseSemantics::SValuePtr &addr, const BaseSemantics::SValuePtr &value, BaseSemantics::RiscOperators */*addrOps*/, - BaseSemantics::RiscOperators */*valOps*/) { + BaseSemantics::RiscOperators */*valOps*/, + size_t writeSize) { ASSERT_not_null(addr); ASSERT_not_null(value); SymEvalSemantics::MemoryStateARM64Ptr memory = SymEvalSemantics::MemoryStateARM64::promote(memoryState()); - memory->writeMemory(addr, value, res, aaMap); + memory->writeMemory(addr, value, res, aaMap, writeSize); } /////////////////////////////////////////////////////// @@ -124,20 +135,26 @@ Dyninst::Absloc SymEvalSemantics::RegisterStateARM64::convert(const RegisterDesc //TODO: what is Len in this case? +BaseSemantics::SValuePtr SymEvalSemantics::MemoryStateARM64::readMemory(const BaseSemantics::SValuePtr &address, + size_t readSize) { + SymEvalSemantics::SValuePtr addr = SymEvalSemantics::SValue::promote(address); + return SymEvalSemantics::SValue::instance(Dyninst::DataflowAPI::RoseAST::create(Dyninst::DataflowAPI::ROSEOperation(Dyninst::DataflowAPI::ROSEOperation::derefOp, readSize), + addr->get_expression(), + Dyninst::DataflowAPI::ConstantAST::create(Dyninst::DataflowAPI::Constant(1, 1)))); +} + BaseSemantics::SValuePtr SymEvalSemantics::MemoryStateARM64::readMemory(const BaseSemantics::SValuePtr &address, const BaseSemantics::SValuePtr &/*dflt*/, BaseSemantics::RiscOperators */*addrOps*/, BaseSemantics::RiscOperators */*valOps*/) { - SymEvalSemantics::SValuePtr addr = SymEvalSemantics::SValue::promote(address); - return SymEvalSemantics::SValue::instance(Dyninst::DataflowAPI::RoseAST::create(Dyninst::DataflowAPI::ROSEOperation(Dyninst::DataflowAPI::ROSEOperation::derefOp), - addr->get_expression(), - Dyninst::DataflowAPI::ConstantAST::create(Dyninst::DataflowAPI::Constant(1, 1)))); + ASSERT_always_forbid("overridden MemoryState::readMemory() should never be called for ARM64, always use the non-virtual readMemory that also takes additional parameters."); } void SymEvalSemantics::MemoryStateARM64::writeMemory(const BaseSemantics::SValuePtr &address, const BaseSemantics::SValuePtr &value, Dyninst::DataflowAPI::Result_t &res, - std::map &aaMap) { + std::map &aaMap, + size_t writeSize) { std::map::iterator i = aaMap.find(Dyninst::Absloc(0)); SymEvalSemantics::SValuePtr addr = SymEvalSemantics::SValue::promote(address); @@ -154,7 +171,7 @@ void SymEvalSemantics::MemoryStateARM64::writeMemory(const BaseSemantics::SValue const BaseSemantics::SValuePtr &/*value*/, BaseSemantics::RiscOperators */*addrOps*/, BaseSemantics::RiscOperators */*valOps*/) { - ASSERT_always_forbid("overridden MemoryState::writeMemory() should never be called for ARM64, always use the non-virtual writeRegister that also takes additional parameters."); + ASSERT_always_forbid("overridden MemoryState::writeMemory() should never be called for ARM64, always use the non-virtual writeMemory that also takes additional parameters."); } /////////////////////////////////////////////////////// diff --git a/dataflowAPI/rose/semantics/SymEvalSemantics.h b/dataflowAPI/rose/semantics/SymEvalSemantics.h index a1204e495b..18e361e13b 100644 --- a/dataflowAPI/rose/semantics/SymEvalSemantics.h +++ b/dataflowAPI/rose/semantics/SymEvalSemantics.h @@ -226,11 +226,13 @@ namespace rose { virtual BaseSemantics::SValuePtr readMemory(const BaseSemantics::SValuePtr &address, const BaseSemantics::SValuePtr &dflt, BaseSemantics::RiscOperators *addrOps, BaseSemantics::RiscOperators *valOps); + BaseSemantics::SValuePtr readMemory(const BaseSemantics::SValuePtr &address, size_t readSize); + virtual void writeMemory(const BaseSemantics::SValuePtr &addr, const BaseSemantics::SValuePtr &value, BaseSemantics::RiscOperators *addrOps, BaseSemantics::RiscOperators *valOps); void writeMemory(const BaseSemantics::SValuePtr &addr, const BaseSemantics::SValuePtr &value, - Dyninst::DataflowAPI::Result_t &res, std::map &aaMap); + Dyninst::DataflowAPI::Result_t &res, std::map &aaMap, size_t writeSize); }; @@ -297,8 +299,10 @@ namespace rose { public: virtual BaseSemantics::SValuePtr readRegister(const RegisterDescriptor ®, const BaseSemantics::SValuePtr &dflt, BaseSemantics::RiscOperators *ops); virtual void writeRegister(const RegisterDescriptor ®, const BaseSemantics::SValuePtr &value, BaseSemantics::RiscOperators *ops); + virtual BaseSemantics::SValuePtr readMemory(const BaseSemantics::SValuePtr &address, const BaseSemantics::SValuePtr &dflt, + BaseSemantics::RiscOperators *addrOps, BaseSemantics::RiscOperators *valOps, size_t readSize = 0); virtual void writeMemory(const BaseSemantics::SValuePtr &addr, const BaseSemantics::SValuePtr &value, BaseSemantics::RiscOperators *addrOps, - BaseSemantics::RiscOperators *valOps); + BaseSemantics::RiscOperators *valOps, size_t writeSize = 0); protected: Dyninst::DataflowAPI::Result_t &res;