CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
733 lines
30 KiB
C++
733 lines
30 KiB
C++
//
|
|
// Created by ssunny on 7/1/16.
|
|
//
|
|
|
|
#include <algorithm>
|
|
#include "SymEvalSemantics.h"
|
|
|
|
#include "Register.h"
|
|
#include "BaseSemantics2.h"
|
|
#include "dyn_regs.h"
|
|
|
|
using namespace rose::BinaryAnalysis::InstructionSemantics2;
|
|
using RoseException = BaseSemantics::Exception;
|
|
|
|
///////////////////////////////////////////////////////
|
|
// StateAST
|
|
///////////////////////////////////////////////////////
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::StateAST::readRegister(const RegisterDescriptor &desc,
|
|
const BaseSemantics::SValuePtr &/*dflt*/, BaseSemantics::RiscOperators */*ops*/) {
|
|
ASSERT_require(desc.is_valid());
|
|
SymEvalSemantics::RegisterStateASTPtr registers = SymEvalSemantics::RegisterStateAST::promote(registerState());
|
|
return registers->readRegister(desc, addr);
|
|
}
|
|
|
|
void SymEvalSemantics::StateAST::writeRegister(const RegisterDescriptor ®, const BaseSemantics::SValuePtr &value,
|
|
BaseSemantics::RiscOperators */*ops*/) {
|
|
ASSERT_require(reg.is_valid());
|
|
ASSERT_not_null(value);
|
|
SymEvalSemantics::RegisterStateASTPtr registers = SymEvalSemantics::RegisterStateAST::promote(registerState());
|
|
registers->writeRegister(reg, value, res, aaMap);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::StateAST::readMemory(const BaseSemantics::SValuePtr &address,
|
|
const BaseSemantics::SValuePtr &/*dflt*/,
|
|
BaseSemantics::RiscOperators */*addrOps*/,
|
|
BaseSemantics::RiscOperators */*valOps*/,
|
|
size_t readSize) {
|
|
ASSERT_not_null(address);
|
|
SymEvalSemantics::MemoryStateASTPtr memory = SymEvalSemantics::MemoryStateAST::promote(memoryState());
|
|
return memory->readMemory(address, readSize);
|
|
}
|
|
|
|
void SymEvalSemantics::StateAST::writeMemory(const BaseSemantics::SValuePtr &addr,
|
|
const BaseSemantics::SValuePtr &value,
|
|
BaseSemantics::RiscOperators */*addrOps*/,
|
|
BaseSemantics::RiscOperators */*valOps*/,
|
|
size_t writeSize) {
|
|
ASSERT_not_null(addr);
|
|
ASSERT_not_null(value);
|
|
SymEvalSemantics::MemoryStateASTPtr memory = SymEvalSemantics::MemoryStateAST::promote(memoryState());
|
|
memory->writeMemory(addr, value, res, aaMap, writeSize);
|
|
}
|
|
|
|
void SymEvalSemantics::StateAST::writeMemory(const BaseSemantics::SValuePtr &addr,
|
|
const BaseSemantics::SValuePtr &value,
|
|
BaseSemantics::RiscOperators *addrOps,
|
|
BaseSemantics::RiscOperators *valOps) {
|
|
ASSERT_not_null(addr);
|
|
ASSERT_not_null(value);
|
|
SymEvalSemantics::MemoryStateASTPtr memory = SymEvalSemantics::MemoryStateAST::promote(memoryState());
|
|
memory->writeMemory(addr, value, res, aaMap, value->get_width());
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////
|
|
// RegisterStateAST
|
|
///////////////////////////////////////////////////////
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RegisterStateAST::readRegister(const RegisterDescriptor ®,
|
|
Dyninst::Address addr) {
|
|
return SymEvalSemantics::SValue::instance(wrap(convert(reg), addr),reg.get_nbits());
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RegisterStateAST::readRegister(const RegisterDescriptor ®,
|
|
const BaseSemantics::SValuePtr &/*dflt*/,
|
|
BaseSemantics::RiscOperators */*ops*/) {
|
|
ASSERT_always_forbid("overridden RegisterState::readRegister() should never be called for AST, always use the non-virtual readRegister that takes Dyninst::Address as an argument.");
|
|
}
|
|
|
|
void SymEvalSemantics::RegisterStateAST::writeRegister(const RegisterDescriptor ®,
|
|
const BaseSemantics::SValuePtr &value,
|
|
Dyninst::DataflowAPI::Result_t &res,
|
|
std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr> &aaMap) {
|
|
std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr>::iterator i = aaMap.find(convert(reg));
|
|
if (i != aaMap.end()) {
|
|
SymEvalSemantics::SValuePtr value_ = SymEvalSemantics::SValue::promote(value);
|
|
res[i->second] = value_->get_expression();
|
|
}
|
|
}
|
|
|
|
void SymEvalSemantics::RegisterStateAST::writeRegister(const RegisterDescriptor &/*reg*/,
|
|
const BaseSemantics::SValuePtr &/*value*/,
|
|
BaseSemantics::RiscOperators */*ops*/) {
|
|
ASSERT_always_forbid("overridden RegisterState::writeRegister() should never be called for AST, always use the non-virtual writeRegister that also takes additional parameters.");
|
|
}
|
|
|
|
Dyninst::Absloc SymEvalSemantics::RegisterStateAST::convert(const RegisterDescriptor ®) {
|
|
ASSERT_always_forbid("converting ROSE register to Dyninst register is platform specific, should not call this base class method.");
|
|
}
|
|
|
|
Dyninst::Absloc SymEvalSemantics::RegisterStateAST_amdgpu_gfx908::convert(const RegisterDescriptor ®) {
|
|
Dyninst::MachRegister mreg;
|
|
|
|
unsigned int major = reg.get_major();
|
|
unsigned int minor = reg.get_minor();
|
|
unsigned int size = reg.get_nbits();
|
|
unsigned int offset = reg.get_offset();
|
|
//std::cout << "in func " << __func__ << " major = " << major << " minor = " << minor << std::endl;
|
|
bool found = false;
|
|
switch (major) {
|
|
case amdgpu_regclass_sgpr : {
|
|
Dyninst::MachRegister base = Dyninst::amdgpu_gfx908::s0;
|
|
//std::cout << "dealing with sgpr pair in , offset = " << minor << std::endl;
|
|
mreg = Dyninst::MachRegister(base.val() + minor) ;
|
|
|
|
found = true;
|
|
break;
|
|
}
|
|
case amdgpu_regclass_pc : {
|
|
mreg = Dyninst::amdgpu_gfx908::pc_all;
|
|
|
|
found = true;
|
|
break;
|
|
}
|
|
case amdgpu_regclass_hwr : {
|
|
switch(minor){
|
|
case amdgpu_status:{
|
|
switch (offset) {
|
|
case 0:
|
|
mreg = Dyninst::amdgpu_gfx908::src_scc;
|
|
found = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
ASSERT_always_forbid("Unexpected register major type.");
|
|
}
|
|
if(found)
|
|
return Dyninst::Absloc(mreg);
|
|
|
|
ASSERT_always_forbid("Unexpected register major type.");
|
|
}
|
|
|
|
Dyninst::Absloc SymEvalSemantics::RegisterStateAST_amdgpu_gfx90a::convert(const RegisterDescriptor ®) {
|
|
Dyninst::MachRegister mreg;
|
|
|
|
unsigned int major = reg.get_major();
|
|
unsigned int minor = reg.get_minor();
|
|
unsigned int size = reg.get_nbits();
|
|
unsigned int offset = reg.get_offset();
|
|
//std::cout << "in func " << __func__ << " major = " << major << " minor = " << minor << std::endl;
|
|
bool found = false;
|
|
switch (major) {
|
|
case amdgpu_regclass_sgpr : {
|
|
Dyninst::MachRegister base = Dyninst::amdgpu_gfx90a::s0;
|
|
//std::cout << "dealing with sgpr pair in , offset = " << minor << std::endl;
|
|
mreg = Dyninst::MachRegister(base.val() + minor) ;
|
|
|
|
found = true;
|
|
break;
|
|
}
|
|
case amdgpu_regclass_pc : {
|
|
mreg = Dyninst::amdgpu_gfx90a::pc_all;
|
|
|
|
found = true;
|
|
break;
|
|
}
|
|
case amdgpu_regclass_hwr : {
|
|
switch(minor){
|
|
case amdgpu_status:{
|
|
switch (offset) {
|
|
case 0:
|
|
mreg = Dyninst::amdgpu_gfx90a::src_scc;
|
|
found = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
ASSERT_always_forbid("Unexpected register major type.");
|
|
}
|
|
if(found)
|
|
return Dyninst::Absloc(mreg);
|
|
|
|
ASSERT_always_forbid("Unexpected register major type.");
|
|
}
|
|
|
|
Dyninst::Absloc SymEvalSemantics::RegisterStateAST_amdgpu_gfx940::convert(const RegisterDescriptor ®) {
|
|
Dyninst::MachRegister mreg;
|
|
|
|
unsigned int major = reg.get_major();
|
|
unsigned int minor = reg.get_minor();
|
|
unsigned int size = reg.get_nbits();
|
|
unsigned int offset = reg.get_offset();
|
|
//std::cout << "in func " << __func__ << " major = " << major << " minor = " << minor << std::endl;
|
|
bool found = false;
|
|
switch (major) {
|
|
case amdgpu_regclass_sgpr : {
|
|
Dyninst::MachRegister base = Dyninst::amdgpu_gfx940::s0;
|
|
//std::cout << "dealing with sgpr pair in , offset = " << minor << std::endl;
|
|
mreg = Dyninst::MachRegister(base.val() + minor) ;
|
|
|
|
found = true;
|
|
break;
|
|
}
|
|
case amdgpu_regclass_pc : {
|
|
mreg = Dyninst::amdgpu_gfx940::pc_all;
|
|
|
|
found = true;
|
|
break;
|
|
}
|
|
case amdgpu_regclass_hwr : {
|
|
switch(minor){
|
|
case amdgpu_status:{
|
|
switch (offset) {
|
|
case 0:
|
|
mreg = Dyninst::amdgpu_gfx940::src_scc;
|
|
found = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
ASSERT_always_forbid("Unexpected register major type.");
|
|
}
|
|
if(found)
|
|
return Dyninst::Absloc(mreg);
|
|
|
|
ASSERT_always_forbid("Unexpected register major type.");
|
|
}
|
|
|
|
|
|
Dyninst::Absloc SymEvalSemantics::RegisterStateASTARM64::convert(const RegisterDescriptor ®) {
|
|
Dyninst::MachRegister mreg;
|
|
|
|
unsigned int major = reg.get_major();
|
|
unsigned int size = reg.get_nbits();
|
|
|
|
switch (major) {
|
|
case armv8_regclass_gpr: {
|
|
unsigned int minor = reg.get_minor();
|
|
|
|
if (minor == armv8_gpr_zr) {
|
|
mreg = Dyninst::MachRegister((size == 32) ? Dyninst::aarch64::wzr : Dyninst::aarch64::xzr);
|
|
} else {
|
|
Dyninst::MachRegister base = (size == 32) ? Dyninst::aarch64::w0 : Dyninst::aarch64::x0;
|
|
mreg = Dyninst::MachRegister(base.val() + (minor - armv8_gpr_r0));
|
|
}
|
|
}
|
|
break;
|
|
case armv8_regclass_simd_fpr: {
|
|
Dyninst::MachRegister base;
|
|
unsigned int minor = reg.get_minor();
|
|
|
|
switch(size) {
|
|
case 8: base = Dyninst::aarch64::b0;
|
|
break;
|
|
case 16: base = Dyninst::aarch64::h0;
|
|
break;
|
|
case 32: base = Dyninst::aarch64::s0;
|
|
break;
|
|
case 64:
|
|
if (reg.get_offset() == 64) {
|
|
base = Dyninst::aarch64::hq0;
|
|
} else {
|
|
base = Dyninst::aarch64::d0;
|
|
}
|
|
break;
|
|
case 128: base = Dyninst::aarch64::q0;
|
|
break;
|
|
default:
|
|
throw RoseException("invalid size of RegisterDescriptor!", nullptr);
|
|
break;
|
|
}
|
|
mreg = Dyninst::MachRegister(base.val() + (minor - armv8_simdfpr_v0));
|
|
}
|
|
break;
|
|
case armv8_regclass_pc:
|
|
mreg = Dyninst::MachRegister(Dyninst::aarch64::pc);
|
|
break;
|
|
case armv8_regclass_sp:
|
|
mreg = Dyninst::MachRegister((size == 32) ? Dyninst::aarch64::wsp : Dyninst::aarch64::sp);
|
|
break;
|
|
case armv8_regclass_pstate: {
|
|
unsigned int offset = reg.get_offset();
|
|
switch (offset) {
|
|
case armv8_pstatefield_n:
|
|
mreg = Dyninst::MachRegister(Dyninst::aarch64::n);
|
|
break;
|
|
case armv8_pstatefield_z:
|
|
mreg = Dyninst::MachRegister(Dyninst::aarch64::z);
|
|
break;
|
|
case armv8_pstatefield_c:
|
|
mreg = Dyninst::MachRegister(Dyninst::aarch64::c);
|
|
break;
|
|
case armv8_pstatefield_v:
|
|
mreg = Dyninst::MachRegister(Dyninst::aarch64::v);
|
|
break;
|
|
default:
|
|
ASSERT_always_forbid("No part of the PSTATE register other than NZCV should be used.");
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
ASSERT_always_forbid("Unexpected register major type.");
|
|
}
|
|
|
|
return Dyninst::Absloc(mreg);
|
|
}
|
|
|
|
Dyninst::Absloc SymEvalSemantics::RegisterStateASTPPC32::convert(const RegisterDescriptor ®) {
|
|
Dyninst::MachRegister mreg;
|
|
|
|
unsigned int major = reg.get_major();
|
|
unsigned int size = reg.get_nbits();
|
|
|
|
switch (major) {
|
|
case powerpc_regclass_gpr: {
|
|
unsigned int minor = reg.get_minor();
|
|
Dyninst::MachRegister base = Dyninst::ppc32::r0;
|
|
|
|
// For some reason, ROSE does not provide a enum representation for power registers
|
|
mreg = Dyninst::MachRegister(base.val() + minor);
|
|
}
|
|
break;
|
|
case powerpc_regclass_fpr: {
|
|
Dyninst::MachRegister base = Dyninst::ppc32::fpr0;
|
|
unsigned int minor = reg.get_minor();
|
|
mreg = Dyninst::MachRegister(base.val() + minor);
|
|
}
|
|
break;
|
|
|
|
case powerpc_regclass_cr: {
|
|
unsigned int offset = reg.get_offset();
|
|
if (size == 32) {
|
|
mreg = Dyninst::ppc32::cr;
|
|
}if (size == 4) {
|
|
Dyninst::MachRegister base = Dyninst::ppc32::cr0;
|
|
mreg = Dyninst::MachRegister(base.val() + offset / 4);
|
|
} else if (size == 1) {
|
|
Dyninst::MachRegister base = Dyninst::ppc32::cr0l;
|
|
mreg = Dyninst::MachRegister(base.val() + offset);
|
|
} else {
|
|
throw RoseException("bad cr register size", nullptr);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case powerpc_regclass_fpscr:
|
|
throw RoseException("not implemented register class fpscr", nullptr);
|
|
break;
|
|
|
|
case powerpc_regclass_spr: {
|
|
unsigned int minor = reg.get_minor();
|
|
switch (minor) {
|
|
case powerpc_spr_xer:
|
|
mreg = Dyninst::ppc32::xer;
|
|
break;
|
|
case powerpc_spr_lr:
|
|
mreg = Dyninst::ppc32::lr;
|
|
break;
|
|
case powerpc_spr_ctr:
|
|
mreg = Dyninst::ppc32::ctr;
|
|
break;
|
|
case powerpc_spr_dsisr:
|
|
mreg = Dyninst::ppc32::dsisr;
|
|
break;
|
|
case powerpc_spr_dar:
|
|
mreg = Dyninst::ppc32::dar;
|
|
break;
|
|
case powerpc_spr_dec:
|
|
mreg = Dyninst::ppc32::dec;
|
|
break;
|
|
default:
|
|
throw RoseException("not implemented special register", nullptr);
|
|
}
|
|
}
|
|
break;
|
|
case powerpc_regclass_tbr:
|
|
throw RoseException("not implemented regclass tbr", nullptr);
|
|
break;
|
|
|
|
case powerpc_regclass_msr:
|
|
mreg = Dyninst::ppc32::msr;
|
|
break;
|
|
|
|
case powerpc_regclass_sr:
|
|
throw RoseException("not implemented regclass sr", nullptr);
|
|
break;
|
|
|
|
case powerpc_regclass_iar:
|
|
mreg = Dyninst::ppc32::pc;
|
|
break;
|
|
|
|
case powerpc_regclass_pvr:
|
|
mreg = Dyninst::ppc32::pvr;
|
|
break;
|
|
default:
|
|
ASSERT_always_forbid("Unexpected register major type.");
|
|
}
|
|
|
|
return Dyninst::Absloc(mreg);
|
|
}
|
|
|
|
Dyninst::Absloc SymEvalSemantics::RegisterStateASTPPC64::convert(const RegisterDescriptor ®) {
|
|
Dyninst::MachRegister mreg;
|
|
|
|
unsigned int major = reg.get_major();
|
|
unsigned int size = reg.get_nbits();
|
|
|
|
switch (major) {
|
|
case powerpc_regclass_gpr: {
|
|
unsigned int minor = reg.get_minor();
|
|
Dyninst::MachRegister base = Dyninst::ppc64::r0;
|
|
|
|
// For some reason, ROSE does not provide a enum representation for power registers
|
|
mreg = Dyninst::MachRegister(base.val() + minor);
|
|
}
|
|
break;
|
|
case powerpc_regclass_fpr: {
|
|
Dyninst::MachRegister base = Dyninst::ppc64::fpr0;
|
|
unsigned int minor = reg.get_minor();
|
|
mreg = Dyninst::MachRegister(base.val() + minor);
|
|
}
|
|
break;
|
|
|
|
case powerpc_regclass_cr: {
|
|
unsigned int offset = reg.get_offset();
|
|
if (size == 32) {
|
|
mreg = Dyninst::ppc64::cr;
|
|
} else if (size == 4) {
|
|
Dyninst::MachRegister base = Dyninst::ppc64::cr0;
|
|
mreg = Dyninst::MachRegister(base.val() + offset / 4);
|
|
} else if (size == 1) {
|
|
Dyninst::MachRegister base = Dyninst::ppc64::cr0l;
|
|
mreg = Dyninst::MachRegister(base.val() + offset);
|
|
} else {
|
|
throw RoseException("bad cr register size", nullptr);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case powerpc_regclass_fpscr:
|
|
throw RoseException("not implemented register class fpscr", nullptr);
|
|
break;
|
|
|
|
case powerpc_regclass_spr: {
|
|
unsigned int minor = reg.get_minor();
|
|
switch (minor) {
|
|
case powerpc_spr_xer:
|
|
mreg = Dyninst::ppc64::xer;
|
|
break;
|
|
case powerpc_spr_lr:
|
|
mreg = Dyninst::ppc64::lr;
|
|
break;
|
|
case powerpc_spr_ctr:
|
|
mreg = Dyninst::ppc64::ctr;
|
|
break;
|
|
case powerpc_spr_dsisr:
|
|
mreg = Dyninst::ppc64::dsisr;
|
|
break;
|
|
case powerpc_spr_dar:
|
|
mreg = Dyninst::ppc64::dar;
|
|
break;
|
|
case powerpc_spr_dec:
|
|
mreg = Dyninst::ppc64::dec;
|
|
break;
|
|
default:
|
|
throw RoseException("not implemented special register", nullptr);
|
|
}
|
|
}
|
|
break;
|
|
case powerpc_regclass_tbr:
|
|
throw RoseException("not implemented regclass tbr", nullptr);
|
|
break;
|
|
|
|
case powerpc_regclass_msr:
|
|
mreg = Dyninst::ppc64::msr;
|
|
break;
|
|
|
|
case powerpc_regclass_sr:
|
|
throw RoseException("not implemented regclass sr", nullptr);
|
|
break;
|
|
|
|
case powerpc_regclass_iar:
|
|
mreg = Dyninst::ppc64::pc;
|
|
break;
|
|
|
|
case powerpc_regclass_pvr:
|
|
mreg = Dyninst::ppc64::pvr;
|
|
break;
|
|
default:
|
|
ASSERT_always_forbid("Unexpected register major type.");
|
|
}
|
|
|
|
return Dyninst::Absloc(mreg);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////
|
|
// MemoryStateAST
|
|
///////////////////////////////////////////////////////
|
|
|
|
//TODO: what is Len in this case?
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::MemoryStateAST::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::MemoryStateAST::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, dflt->get_number()),
|
|
addr->get_expression(),
|
|
Dyninst::DataflowAPI::ConstantAST::create(Dyninst::DataflowAPI::Constant(1, 1))));
|
|
|
|
}
|
|
|
|
void SymEvalSemantics::MemoryStateAST::writeMemory(const BaseSemantics::SValuePtr &address,
|
|
const BaseSemantics::SValuePtr &value,
|
|
Dyninst::DataflowAPI::Result_t &res,
|
|
std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr> &aaMap,
|
|
size_t writeSize) {
|
|
std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr>::iterator i = aaMap.find(Dyninst::Absloc(0));
|
|
SymEvalSemantics::SValuePtr addr = SymEvalSemantics::SValue::promote(address);
|
|
|
|
if (i != aaMap.end()) {
|
|
i->second->out().setGenerator(addr->get_expression());
|
|
//i->second->out().setSize(Len);
|
|
|
|
SymEvalSemantics::SValuePtr data = SymEvalSemantics::SValue::promote(value);
|
|
res[i->second] = data->get_expression();
|
|
}
|
|
}
|
|
|
|
void SymEvalSemantics::MemoryStateAST::writeMemory(const BaseSemantics::SValuePtr &addr,
|
|
const BaseSemantics::SValuePtr &value,
|
|
BaseSemantics::RiscOperators */*addrOps*/,
|
|
BaseSemantics::RiscOperators */*valOps*/) {
|
|
ASSERT_always_forbid("overridden MemoryState::writeMemory() should never be called for AST, always use the non-virtual writeMemory that also takes additional parameters.");
|
|
}
|
|
|
|
///////////////////////////////////////////////////////
|
|
// RiscOperators
|
|
///////////////////////////////////////////////////////
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::and_(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::andOp, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::or_(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::orOp, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::xor_(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::xorOp, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::invert(const BaseSemantics::SValuePtr &a_) {
|
|
return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::invertOp, a_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::extract(const BaseSemantics::SValuePtr &a_, uint64_t begin,
|
|
uint64_t end) {
|
|
BaseSemantics::SValuePtr begin_ = SymEvalSemantics::SValue::instance(64, begin);
|
|
BaseSemantics::SValuePtr end_ = SymEvalSemantics::SValue::instance(64, end);
|
|
|
|
return createTernaryAST(Dyninst::DataflowAPI::ROSEOperation::extractOp, a_, begin_, end_, end - begin);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::ite(const BaseSemantics::SValuePtr &sel_,
|
|
const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createTernaryAST(Dyninst::DataflowAPI::ROSEOperation::ifOp, sel_, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::concat(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
//TODO: should be able to specify number of bits to concat for each expression
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::concatOp, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::leastSignificantSetBit(const BaseSemantics::SValuePtr &a_) {
|
|
return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::LSBSetOp, a_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::mostSignificantSetBit(const BaseSemantics::SValuePtr &a_) {
|
|
return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::MSBSetOp, a_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::rotateLeft(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::rotateLOp, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::rotateRight(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::rotateROp, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::shiftLeft(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::shiftLOp, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::shiftRight(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::shiftROp, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::shiftRightArithmetic(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::shiftRArithOp, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::equalToZero(const BaseSemantics::SValuePtr &a_) {
|
|
return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::equalToZeroOp, a_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::signExtend(const BaseSemantics::SValuePtr &a_,
|
|
uint64_t newwidth) {
|
|
BaseSemantics::SValuePtr width_ = SymEvalSemantics::SValue::instance(64, newwidth);
|
|
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::signExtendOp, a_, width_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::add(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::addOp, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::addWithCarries(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_,
|
|
const BaseSemantics::SValuePtr &c_,
|
|
BaseSemantics::SValuePtr &carry_out) {
|
|
BaseSemantics::SValuePtr aa_ = unsignedExtend(a_, a_->get_width() + 1);
|
|
BaseSemantics::SValuePtr bb_ = unsignedExtend(b_, b_->get_width() + 1);
|
|
BaseSemantics::SValuePtr sum_ = createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::addOp, aa_,
|
|
createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::addOp, bb_, c_));
|
|
|
|
BaseSemantics::SValuePtr cc_ = createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::xorOp, aa_,
|
|
createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::xorOp, bb_, sum_));
|
|
carry_out = extract(cc_, 1, a_->get_width() + 1);
|
|
|
|
return extract(sum_, 0, a_->get_width());
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::negate(const BaseSemantics::SValuePtr &a_) {
|
|
return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::negateOp, a_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::signedDivide(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::sDivOp, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::signedModulo(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::sModOp, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::signedMultiply(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::sMultOp, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::unsignedDivide(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::uDivOp, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::unsignedModulo(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::uModOp, a_, b_);
|
|
}
|
|
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::unsignedMultiply(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_) {
|
|
return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::uMultOp, a_, b_);
|
|
}
|
|
|
|
//TODO: do we deal with byte ordering?
|
|
BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::readMemory(const RegisterDescriptor &/*segreg*/,
|
|
const BaseSemantics::SValuePtr &addr,
|
|
const BaseSemantics::SValuePtr &dflt,
|
|
const BaseSemantics::SValuePtr &/*cond*/) {
|
|
return currentState()->readMemory(addr, dflt, this, this);
|
|
}
|
|
|
|
void SymEvalSemantics::RiscOperatorsAST::writeMemory(const RegisterDescriptor &/*segreg*/,
|
|
const BaseSemantics::SValuePtr &addr,
|
|
const BaseSemantics::SValuePtr &data,
|
|
const BaseSemantics::SValuePtr &/*cond*/) {
|
|
currentState()->writeMemory(addr, data, this, this);
|
|
}
|