T32: Dissassembler to evaluate memory instructions.
For the T32 variant we have to evaluate the memory access instruction to find out, which memory address was accessed. Dissassmbly by OpenOCDs arm_disassembler.hpp/.cc: - fine for ARM / Thumb1 - needs fixes for Thumb2 :( (currently doing that..)
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
#include "T32Connector.hpp"
|
||||
#include <iostream>
|
||||
#include <t32.h>
|
||||
#include "sal/MemoryInstruction.hpp"
|
||||
|
||||
using namespace fail;
|
||||
|
||||
@ -93,7 +94,6 @@ void T32Connector::brk() {
|
||||
#include "sal/t32/T32Constants.hpp"
|
||||
|
||||
void T32Connector::test() {
|
||||
|
||||
}
|
||||
|
||||
/* Default T32 error handler */
|
||||
|
||||
@ -23,6 +23,8 @@
|
||||
|
||||
#include "T32Connector.hpp"
|
||||
#include "t32config.hpp"
|
||||
#include "sal/MemoryInstruction.hpp"
|
||||
#include "util/Disassembler.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
@ -96,6 +98,8 @@ int main(int argc, char** argv){
|
||||
// The experiments/traces hopefully set some Breakpoints, we can react on.
|
||||
// We may also provide a timeout, if a TimerListener was set wanted.
|
||||
|
||||
MemoryInstruction mem;
|
||||
address_t ip;
|
||||
|
||||
while(1) {
|
||||
// Start execution (with next timeout, if any)
|
||||
@ -105,8 +109,11 @@ int main(int argc, char** argv){
|
||||
// Evaluate state.
|
||||
t32.test();// TODO
|
||||
// Call appropriate callback of the SimulatorController.
|
||||
fail::simulator.onBreakpoint(&fail::simulator.getCPU(0), fail::simulator.getCPU(0).getInstructionPointer(), fail::ANY_ADDR);
|
||||
// TODO fail::simulator.onMemoryAccess(&fail::simulator.getCPU(0), 0x20002074, 1, true, fail::simulator.getCPU(0).getInstructionPointer());
|
||||
ip = fail::simulator.getCPU(0).getInstructionPointer();
|
||||
fail::simulator.onBreakpoint(&fail::simulator.getCPU(0), ip , fail::ANY_ADDR);
|
||||
if( meminstruction.eval(ip, mem) ) {
|
||||
fail::simulator.onMemoryAccess(&fail::simulator.getCPU(0), mem.getAddress(), mem.getWidth(), mem.isWriteAccess(), ip );
|
||||
}
|
||||
}
|
||||
|
||||
cout << "[T32 Backend] After startup" << endl;
|
||||
|
||||
@ -64,6 +64,8 @@ elseif(BUILD_T32)
|
||||
if(BUILD_ARM)
|
||||
set(SRCS ${SRCS}
|
||||
t32/T32ArmCPU.cc
|
||||
arm/ArmMemoryInstruction.cc
|
||||
arm/arm_disassembler.cc
|
||||
)
|
||||
endif(BUILD_ARM)
|
||||
endif(BUILD_BOCHS)
|
||||
|
||||
40
src/core/sal/MemoryInstruction.hpp
Normal file
40
src/core/sal/MemoryInstruction.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef __MEMORYINSTRUCTION_HPP__
|
||||
#define __MEMORYINSTRUCTION_HPP__
|
||||
|
||||
#include <string>
|
||||
#include "SALConfig.hpp"
|
||||
|
||||
namespace fail {
|
||||
|
||||
class MemoryInstruction {
|
||||
regdata_t address;
|
||||
regdata_t value;
|
||||
uint8_t width;
|
||||
bool writeAccess;
|
||||
public:
|
||||
MemoryInstruction(regdata_t address = ADDR_INV, regdata_t value = 0, uint8_t width = 0, bool writeAccess = false) :
|
||||
address(address), value(value), width(width), writeAccess(writeAccess) { };
|
||||
|
||||
bool isWriteAccess(void) const { return writeAccess; }
|
||||
regdata_t getAddress() const { return address; }
|
||||
regdata_t getValue() const { return value; }
|
||||
uint8_t getWidth() const { return width; }
|
||||
|
||||
bool isValid(void) const { return address != ADDR_INV; }
|
||||
|
||||
void setAddress(regdata_t addr) { address = addr; }
|
||||
void setValue(regdata_t val) { value = val; }
|
||||
void setWidth(uint8_t w) { width = w; }
|
||||
void setWriteAccess(bool iswrite) { writeAccess = iswrite; }
|
||||
};
|
||||
|
||||
class MemoryInstructionAnalyzer {
|
||||
public:
|
||||
virtual bool eval(address_t opcode, MemoryInstruction & result) = 0;
|
||||
};
|
||||
|
||||
extern MemoryInstructionAnalyzer & meminstruction;
|
||||
} // end of namespace fail
|
||||
|
||||
#endif // __MEMORYINSTRUCTION_HPP__
|
||||
|
||||
97
src/core/sal/arm/ArmMemoryInstruction.cc
Normal file
97
src/core/sal/arm/ArmMemoryInstruction.cc
Normal file
@ -0,0 +1,97 @@
|
||||
#include "ArmMemoryInstruction.hpp"
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
namespace fail {
|
||||
static ArmMemoryInstructionAnalyzer anal;
|
||||
MemoryInstructionAnalyzer & meminstruction = anal;
|
||||
|
||||
address_t ArmMemoryInstructionAnalyzer::findPrevious(address_t address){
|
||||
if(m_dis.hasInstructionAt(address-2)) {
|
||||
return address - 2;
|
||||
} else if (m_dis.hasInstructionAt(address - 4)) {
|
||||
return address - 4;
|
||||
} else {
|
||||
return ADDR_INV;
|
||||
}
|
||||
}
|
||||
|
||||
void ArmMemoryInstructionAnalyzer::evaluate(arm_instruction & inst, MemoryInstruction& result){
|
||||
cout << "Memory Access: " << inst.text << " - Size: " << inst.instruction_size << " Type " << inst.type << endl;
|
||||
inst.info.load_store.evaluate();
|
||||
result.setValue(inst.info.load_store.value);
|
||||
result.setAddress(inst.info.load_store.address);
|
||||
result.setWidth(4); // TODO;
|
||||
result.setWriteAccess(inst.isStoreInstruction());
|
||||
}
|
||||
|
||||
// The Cortex M3 Lauterbach is a pain in the ass, as a Memory Watchpoint does not stop
|
||||
// at the accessing instruction, but 1 or 2 instructions later.
|
||||
bool ArmMemoryInstructionAnalyzer::eval_cm3(address_t address, MemoryInstruction& result){
|
||||
arm_instruction inst;
|
||||
uint32_t opcode =0;
|
||||
address = findPrevious(address); // Cortex M3: memory access is at the previous instruction
|
||||
opcode = m_dis.disassemble(address).opcode;
|
||||
|
||||
// OpenOCDs thumb2_opcode evaluation is not complete yet. :(
|
||||
thumb2_opcode(address, opcode, &inst);
|
||||
|
||||
if(inst.isMemoryAccess()){
|
||||
evaluate(inst, result);
|
||||
return true;
|
||||
} else if(inst.isBranchInstruction()){
|
||||
// The memory access took place within the function previously branched
|
||||
int regop = inst.info.b_bl_bx_blx.reg_operand;
|
||||
uint32_t addr = inst.info.b_bl_bx_blx.target_address;
|
||||
//cout << " Reg:" << hex << regop << " address " << hex << addr << endl;
|
||||
// Lets look into this function
|
||||
if( regop == -1 ){
|
||||
// address should be set..
|
||||
const ElfSymbol & sym = m_elf.getSymbol(addr|1); // | 1 to set first bit -> thumbmode
|
||||
addr += sym.getSize(); // Go to end of function.
|
||||
// THIS IS DANGEROUS: The memory access can be anywhere within this function, one instruction before a ret.
|
||||
// OR, the memory access itself can result in leaving the function :e.g., ldr pc, [r3]
|
||||
// We cannot be sure :( Here we assume the first memory access from the back.
|
||||
do { // go backwards until there is a memory instruction.
|
||||
addr = findPrevious(addr); // find previous
|
||||
thumb2_opcode(addr, m_dis.disassemble(addr).opcode, &inst);
|
||||
} while( !inst.isMemoryAccess() );
|
||||
evaluate(inst, result);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// There was a memory access before, but the previous instruction
|
||||
// is neither an access nor a branch.
|
||||
// This can happen if we came here from anywhere, e.g. by ldr pc, [r4]
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ArmMemoryInstructionAnalyzer::eval_ca9(address_t address, MemoryInstruction& result){
|
||||
arm_instruction inst;
|
||||
uint32_t opcode = m_dis.disassemble(address).opcode;
|
||||
arm_evaluate_opcode(address, opcode, &inst);
|
||||
if( inst.isMemoryAccess() ){
|
||||
evaluate(inst, result);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#define CORTEXM3
|
||||
|
||||
bool ArmMemoryInstructionAnalyzer::eval(address_t address, MemoryInstruction & result){
|
||||
#ifdef CORTEXM3
|
||||
#warning "Memory Accesses cannot be evaluated completedly!"
|
||||
return eval_cm3(address, result);
|
||||
#elif defined CORTEXA9
|
||||
return eval_ca9(address, result);
|
||||
#else
|
||||
#warning "Memory Accesses are not evaluated!"
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
34
src/core/sal/arm/ArmMemoryInstruction.hpp
Normal file
34
src/core/sal/arm/ArmMemoryInstruction.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef __ARMMEMORYINSTRUCITON_HPP__
|
||||
#define __ARMMEMORYINSTRUCITON_HPP__
|
||||
|
||||
#include "../MemoryInstruction.hpp"
|
||||
#include "util/Disassembler.hpp"
|
||||
#include "util/ElfReader.hpp"
|
||||
#include "arm_disassembler.hpp"
|
||||
|
||||
namespace fail {
|
||||
|
||||
class ArmMemoryInstructionAnalyzer : public MemoryInstructionAnalyzer {
|
||||
fail::ElfReader m_elf;
|
||||
fail::Disassembler m_dis;
|
||||
|
||||
address_t findPrevious(address_t addr);
|
||||
void evaluate(arm_instruction & inst, MemoryInstruction& result);
|
||||
bool eval_ca9(address_t address, MemoryInstruction& result);
|
||||
bool eval_cm3(address_t address, MemoryInstruction& result);
|
||||
|
||||
public:
|
||||
|
||||
ArmMemoryInstructionAnalyzer() {
|
||||
m_dis.init();
|
||||
};
|
||||
|
||||
bool eval(address_t opcode, MemoryInstruction & result);
|
||||
|
||||
};
|
||||
|
||||
} //end of namespace fail
|
||||
|
||||
|
||||
#endif // __ARMMEMORYINSTRUCITON_HPP__
|
||||
|
||||
4565
src/core/sal/arm/arm_disassembler.cc
Normal file
4565
src/core/sal/arm/arm_disassembler.cc
Normal file
File diff suppressed because it is too large
Load Diff
226
src/core/sal/arm/arm_disassembler.hpp
Normal file
226
src/core/sal/arm/arm_disassembler.hpp
Normal file
@ -0,0 +1,226 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef ARM_DISASSEMBLER_H
|
||||
#define ARM_DISASSEMBLER_H
|
||||
#include <stdint.h>
|
||||
|
||||
enum arm_instruction_type {
|
||||
ARM_UNKNOWN_INSTUCTION,
|
||||
|
||||
/* Branch instructions */
|
||||
ARM_B,
|
||||
ARM_BL,
|
||||
ARM_BX,
|
||||
ARM_BLX,
|
||||
|
||||
/* Data processing instructions */
|
||||
ARM_AND,
|
||||
ARM_EOR,
|
||||
ARM_SUB,
|
||||
ARM_RSB,
|
||||
ARM_ADD,
|
||||
ARM_ADC,
|
||||
ARM_SBC,
|
||||
ARM_RSC,
|
||||
ARM_TST,
|
||||
ARM_TEQ,
|
||||
ARM_CMP,
|
||||
ARM_CMN,
|
||||
ARM_ORR,
|
||||
ARM_MOV,
|
||||
ARM_BIC,
|
||||
ARM_MVN,
|
||||
|
||||
/* Load/store instructions */
|
||||
ARM_LDR,
|
||||
ARM_LDRB,
|
||||
ARM_LDRT,
|
||||
ARM_LDRBT,
|
||||
|
||||
ARM_LDRH,
|
||||
ARM_LDRSB,
|
||||
ARM_LDRSH,
|
||||
ARM_LDREX,
|
||||
ARM_LDREXB,
|
||||
ARM_LDREXH,
|
||||
ARM_LDM,
|
||||
|
||||
ARM_STR,
|
||||
ARM_STRB,
|
||||
ARM_STRT,
|
||||
ARM_STRBT,
|
||||
|
||||
ARM_STRH,
|
||||
ARM_STREX,
|
||||
ARM_STREXB,
|
||||
ARM_STREXH,
|
||||
ARM_STM,
|
||||
|
||||
/* Status register access instructions */
|
||||
ARM_MRS,
|
||||
ARM_MSR,
|
||||
|
||||
/* Multiply instructions */
|
||||
ARM_MUL,
|
||||
ARM_MLA,
|
||||
ARM_SMULL,
|
||||
ARM_SMLAL,
|
||||
ARM_UMULL,
|
||||
ARM_UMLAL,
|
||||
|
||||
/* Miscellaneous instructions */
|
||||
ARM_CLZ,
|
||||
|
||||
/* Exception generating instructions */
|
||||
ARM_BKPT,
|
||||
ARM_SWI,
|
||||
|
||||
/* Coprocessor instructions */
|
||||
ARM_CDP,
|
||||
ARM_LDC,
|
||||
ARM_STC,
|
||||
ARM_MCR,
|
||||
ARM_MRC,
|
||||
|
||||
/* Semaphore instructions */
|
||||
ARM_SWP,
|
||||
ARM_SWPB,
|
||||
|
||||
/* Enhanced DSP extensions */
|
||||
ARM_MCRR,
|
||||
ARM_MRRC,
|
||||
ARM_PLD,
|
||||
ARM_QADD,
|
||||
ARM_QDADD,
|
||||
ARM_QSUB,
|
||||
ARM_QDSUB,
|
||||
ARM_SMLAxy,
|
||||
ARM_SMLALxy,
|
||||
ARM_SMLAWy,
|
||||
ARM_SMULxy,
|
||||
ARM_SMULWy,
|
||||
ARM_LDRD,
|
||||
ARM_STRD,
|
||||
|
||||
ARM_UNDEFINED_INSTRUCTION = 0xffffffff,
|
||||
};
|
||||
|
||||
struct arm_b_bl_bx_blx_instr {
|
||||
int reg_operand;
|
||||
uint32_t target_address;
|
||||
};
|
||||
|
||||
union arm_shifter_operand {
|
||||
struct {
|
||||
uint32_t immediate;
|
||||
} immediate;
|
||||
struct {
|
||||
uint8_t Rm;
|
||||
uint8_t shift; /* 0: LSL, 1: LSR, 2: ASR, 3: ROR, 4: RRX */
|
||||
uint8_t shift_imm;
|
||||
} immediate_shift;
|
||||
struct {
|
||||
uint8_t Rm;
|
||||
uint8_t shift;
|
||||
uint8_t Rs;
|
||||
} register_shift;
|
||||
};
|
||||
|
||||
struct arm_data_proc_instr {
|
||||
int variant; /* 0: immediate, 1: immediate_shift, 2: register_shift */
|
||||
uint8_t S;
|
||||
uint8_t Rn;
|
||||
uint8_t Rd;
|
||||
union arm_shifter_operand shifter_operand;
|
||||
};
|
||||
|
||||
struct arm_load_store_instr {
|
||||
uint8_t Rd;
|
||||
uint8_t Rn;
|
||||
uint8_t U;
|
||||
int index_mode; /* 0: offset, 1: pre-indexed, 2: post-indexed */
|
||||
int offset_mode; /* 0: immediate, 1: (scaled) register */
|
||||
union {
|
||||
uint32_t offset;
|
||||
struct {
|
||||
uint8_t Rm;
|
||||
uint8_t shift; /* 0: LSL, 1: LSR, 2: ASR, 3: ROR, 4: RRX */
|
||||
uint8_t shift_imm;
|
||||
} reg;
|
||||
} offset;
|
||||
|
||||
uint32_t address;
|
||||
uint32_t value;
|
||||
uint8_t width;
|
||||
void evaluate(void);
|
||||
};
|
||||
|
||||
struct arm_load_store_multiple_instr {
|
||||
uint8_t Rn;
|
||||
uint32_t register_list;
|
||||
uint8_t addressing_mode; /* 0: IA, 1: IB, 2: DA, 3: DB */
|
||||
uint8_t S;
|
||||
uint8_t W;
|
||||
};
|
||||
|
||||
struct arm_instruction {
|
||||
enum arm_instruction_type type;
|
||||
char text[128];
|
||||
uint32_t opcode;
|
||||
|
||||
/* return value ... Thumb-2 sizes vary */
|
||||
unsigned instruction_size;
|
||||
|
||||
union {
|
||||
struct arm_b_bl_bx_blx_instr b_bl_bx_blx;
|
||||
struct arm_data_proc_instr data_proc;
|
||||
struct arm_load_store_instr load_store;
|
||||
struct arm_load_store_multiple_instr load_store_multiple;
|
||||
} info;
|
||||
|
||||
bool isBranchInstruction(void) const {
|
||||
return (type == ARM_B) || (type == ARM_BL) || (type == ARM_BX) || (type == ARM_BLX);
|
||||
};
|
||||
|
||||
bool isLoadInstruction(void) const {
|
||||
return (type >= ARM_LDR) && (type <= ARM_LDM);
|
||||
}
|
||||
|
||||
bool isStoreInstruction(void) const {
|
||||
return (type >= ARM_STR) && (type <= ARM_STM);
|
||||
}
|
||||
|
||||
bool isMemoryAccess(void) const {
|
||||
return isLoadInstruction() || isStoreInstruction();
|
||||
};
|
||||
};
|
||||
|
||||
int arm_evaluate_opcode(uint32_t opcode, uint32_t address,
|
||||
struct arm_instruction *instruction);
|
||||
int thumb_evaluate_opcode(uint16_t opcode, uint32_t address,
|
||||
struct arm_instruction *instruction);
|
||||
int thumb2_opcode(uint32_t address, uint32_t opcode,
|
||||
struct arm_instruction *instruction);
|
||||
int arm_access_size(struct arm_instruction *instruction);
|
||||
|
||||
#define COND(opcode) (arm_condition_strings[(opcode & 0xf0000000) >> 28])
|
||||
|
||||
#endif /* ARM_DISASSEMBLER_H */
|
||||
@ -53,7 +53,9 @@ namespace fail {
|
||||
}
|
||||
|
||||
std::ostream& operator <<(std::ostream & os, const fail::Instruction & i) {
|
||||
os << i.opcode << "\t" << i.instruction << "\t" << i.comment;
|
||||
#ifndef __puma
|
||||
os << std::hex << ((int)(i.address)) << "\t" << i.opcode << "\t" << i.instruction << "\t" << i.comment;
|
||||
#endif
|
||||
return os;
|
||||
}
|
||||
|
||||
@ -63,7 +65,7 @@ namespace fail {
|
||||
// Code lines start with a leading whitespace! (hopefully in each objdump implementation!)
|
||||
if(line.size() > 0 && isspace(line[0])){
|
||||
// a line looks like: 800156c:\tdd14 \tble.n 8001598 <_ZN2hw3hal7T32Term8PutBlockEPci+0x30>
|
||||
boost::regex expr("\\s+([A-Fa-f0-9]+):((?:\\s+[A-Fa-f0-9]+)+)\\s+(.+?)(;.*)?$");
|
||||
boost::regex expr("\\s+([A-Fa-f0-9]+):\\t(.*?)\\t(.+?)(;.*)?$");
|
||||
boost::smatch res;
|
||||
if(boost::regex_search(line, res, expr)){
|
||||
std::string address = res[1];
|
||||
@ -71,22 +73,31 @@ namespace fail {
|
||||
ss << std::hex << address;
|
||||
address_t addr = 0;
|
||||
ss >> addr;
|
||||
ss.clear();
|
||||
ss.str("");
|
||||
|
||||
std::string opcode = res[2];
|
||||
// delete trailing/leading whitespaces
|
||||
boost::trim(opcode);
|
||||
// delete inner whitespaces and merge nibbles
|
||||
opcode.erase(std::remove(opcode.begin(), opcode.end(), ' '), opcode.end());
|
||||
ss << std::hex << opcode;
|
||||
unsigned opc = 0;
|
||||
ss >> opc;
|
||||
|
||||
std::string instruction = res[3];
|
||||
boost::trim(instruction);
|
||||
std::string comment = res[4];
|
||||
boost::trim(comment);
|
||||
|
||||
m_code.insert(std::make_pair(addr, Instruction(opcode, instruction, comment)));
|
||||
m_code.insert(std::make_pair(addr, Instruction(addr, opc, instruction, comment)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static Instruction g_InstructionNotFound;
|
||||
|
||||
const Instruction& Disassembler::disassemble(address_t address){
|
||||
const Instruction & Disassembler::disassemble(address_t address) const {
|
||||
InstructionMap_t::const_iterator it = m_code.find(address);
|
||||
if(it == m_code.end()){
|
||||
return g_InstructionNotFound;
|
||||
|
||||
@ -19,11 +19,12 @@ namespace fail {
|
||||
* @brief An Instruction represents an disassembled opcode
|
||||
*/
|
||||
struct Instruction {
|
||||
std::string opcode; // TODO convert to integer, size?
|
||||
address_t address; //!< The instruction address
|
||||
regdata_t opcode; //!< The opcode itself
|
||||
std::string instruction; //!< The disassembled instruction
|
||||
std::string comment; //!< Comment (rest of line after ; )
|
||||
Instruction(std::string opcode = "", const std::string& instr = DISASSEMBLER::FAILED, const std::string& comment = "")
|
||||
: opcode(opcode), instruction(instr), comment(comment) { };
|
||||
Instruction(address_t address = ADDR_INV, regdata_t opcode = 0, const std::string& instr = DISASSEMBLER::FAILED, const std::string& comment = "")
|
||||
: address(address), opcode(opcode), instruction(instr), comment(comment) { };
|
||||
};
|
||||
//<! This allows to print an Instruction via Logger or cout
|
||||
std::ostream& operator <<(std::ostream & os, const fail::Instruction & i);
|
||||
@ -41,7 +42,16 @@ namespace fail {
|
||||
* @param address The instruction address
|
||||
* @return The according disassembled instruction if found, else DISASSEMBLER:FAILED
|
||||
*/
|
||||
const Instruction& disassemble(address_t address);
|
||||
const Instruction & disassemble(address_t address) const;
|
||||
|
||||
/**
|
||||
* Test if there is an instruction at a given address
|
||||
* @param address The address to test
|
||||
* @return true if found, else false
|
||||
*/
|
||||
bool hasInstructionAt(address_t address) const {
|
||||
return m_code.find(address) != m_code.end();;
|
||||
};
|
||||
|
||||
/**
|
||||
* Evaluate new ELF file
|
||||
|
||||
@ -216,7 +216,7 @@ const ElfSymbol& ElfReader::getSection( const std::string& name ){
|
||||
return g_SymbolNotFound;
|
||||
}
|
||||
|
||||
// "Pretty" Print
|
||||
// "Pretty" Print
|
||||
void ElfReader::printDemangled(){
|
||||
m_log << "Demangled: " << std::endl;
|
||||
for(container_t::const_iterator it = m_symboltable.begin(); it !=m_symboltable.end(); ++it){
|
||||
@ -230,7 +230,7 @@ void ElfReader::printDemangled(){
|
||||
|
||||
void ElfReader::printMangled(){
|
||||
for(container_t::const_iterator it = m_symboltable.begin(); it !=m_symboltable.end(); ++it){
|
||||
m_log << "0x" << it->getAddress() << "\t" << it->getName().c_str() << "\t" << it->getSize() << std::endl;
|
||||
m_log << "0x" << std::hex << it->getAddress() << "\t" << it->getName().c_str() << "\t" << it->getSize() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ unsigned KESOrefs::injectBitFlip(address_t data_address, unsigned bitpos){
|
||||
unsigned value, injectedval;
|
||||
|
||||
mm.getBytes(data_address, 4, (void*)&value);
|
||||
injectedval = value ^ bitpos;
|
||||
injectedval = value ^ (1<<bitpos);
|
||||
mm.setBytes(data_address, 4, (void*)&injectedval);
|
||||
|
||||
m_log << "INJECTION at: 0x" << hex << setw(8) << setfill('0') << data_address;
|
||||
|
||||
@ -20,7 +20,7 @@ using namespace fail;
|
||||
|
||||
bool VEZSExperiment::run()
|
||||
{
|
||||
MemoryManager& mm = simulator.getMemoryManager();
|
||||
//MemoryManager& mm = simulator.getMemoryManager();
|
||||
|
||||
//m_elf.printDemangled();
|
||||
m_log << "STARTING EXPERIMENT" << endl;
|
||||
@ -40,17 +40,18 @@ bool VEZSExperiment::run()
|
||||
|
||||
address_t pfoo = m_elf.getSymbol("foo").getAddress();
|
||||
//BPSingleListener bp(address);
|
||||
BPRangeListener bp(address-32, address + 32);
|
||||
MemWriteListener l_foo( pfoo );
|
||||
simulator.addListener(&l_foo);
|
||||
//BPRangeListener bp(address-32, address + 32);
|
||||
//MemWriteListener l_foo( pfoo );
|
||||
MemAccessListener l_foo( 0x20002018 ); l_foo.setWatchWidth(0x20);
|
||||
reg = simulator.getCPU(0).getRegister(RI_R4);
|
||||
|
||||
unsigned foo = 23;
|
||||
for(int i = 0; i < 15; i++){
|
||||
simulator.addListenerAndResume(&bp);
|
||||
if(i == 0) mm.setBytes(pfoo, 4, (void*)&foo);
|
||||
simulator.addListenerAndResume(&l_foo);
|
||||
//if(i == 0) mm.setBytes(pfoo, 4, (void*)&foo);
|
||||
m_log << " Breakpoint hit! @ 0x" << std::hex << simulator.getCPU(0).getInstructionPointer() << std::endl;
|
||||
m_log << " Register R3: 0x" << hex << simulator.getCPU(0).getRegisterContent(reg) << endl;
|
||||
mm.getBytes(pfoo, 4, (void*)&foo);
|
||||
//m_log << " Register R3: 0x" << hex << simulator.getCPU(0).getRegisterContent(reg) << endl;
|
||||
//mm.getBytes(pfoo, 4, (void*)&foo);
|
||||
m_log << " foo @ 0x"<< std::hex << pfoo << " = " << foo << std::endl;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user