diff --git a/debuggers/t32/src/main.cc b/debuggers/t32/src/main.cc index 22c86f75..476a23ff 100644 --- a/debuggers/t32/src/main.cc +++ b/debuggers/t32/src/main.cc @@ -98,7 +98,6 @@ 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; // Enable T32 Tracer (if available) @@ -117,11 +116,26 @@ int main(int argc, char** argv){ // Evaluate tracing result, handle memory access event.. if((tr.evaluate() > 0) && (tr.wasDataAccess())){ - // TODO: step back in trace and find program counter of the according instruction. - // ip = XXX; - fail::simulator.onMemoryAccess(&fail::simulator.getCPU(0), tr.getLatestRecord().getAddress(), /* TODO access width: */ 4, tr.getLatestRecord().isDataWrite(), ip ); + MemoryInstruction mem; + T32Tracer::const_record_iterator it = tr.begin(); - tr.dump(); + // step back to current PC + for( ; it != tr.end(); ++it) { + if(it->isProgram() && (it->getAddress() == ip)){ + break; + } + } + // find latest memory access + for( ; it != tr.end(); ++it){ + // iterate records till there is a memory access.. + if(it->isProgram() && meminstruction.eval(it->getAddress(), mem)){ // skip data access in between + ip = it->getAddress(); // store PC of the mem access. + break; // yay, we found a memory access. + } + } + if(mem.isValid()){ // mem is not valid, if we did not leave the for loop via the break statement.. -> no mem access found :( XXX this should not happen. + fail::simulator.onMemoryAccess(&fail::simulator.getCPU(0), tr.getLatestRecord().getAddress(), mem.getWidth(), tr.getLatestRecord().isDataWrite(), ip ); + } } } diff --git a/src/core/sal/arm/ArmMemoryInstruction.cc b/src/core/sal/arm/ArmMemoryInstruction.cc index 69979e0f..ca95b65a 100644 --- a/src/core/sal/arm/ArmMemoryInstruction.cc +++ b/src/core/sal/arm/ArmMemoryInstruction.cc @@ -8,10 +8,10 @@ namespace fail { MemoryInstructionAnalyzer & meminstruction = anal; address_t ArmMemoryInstructionAnalyzer::findPrevious(address_t address){ - if(m_dis.hasInstructionAt(address-2)) { + if(m_dis.hasInstructionAt(address)) { + return address; + } else if (m_dis.hasInstructionAt(address - 2)) { return address - 2; - } else if (m_dis.hasInstructionAt(address - 4)) { - return address - 4; } else { return ADDR_INV; } @@ -29,6 +29,23 @@ namespace fail { // 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); + 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{ + return false; + } + +#if 0 arm_instruction inst; uint32_t opcode =0; address = findPrevious(address); // Cortex M3: memory access is at the previous instruction @@ -66,6 +83,7 @@ namespace fail { // This can happen if we came here from anywhere, e.g. by ldr pc, [r4] } return false; +#endif } bool ArmMemoryInstructionAnalyzer::eval_ca9(address_t address, MemoryInstruction& result){ @@ -81,6 +99,7 @@ namespace fail { #define CORTEXM3 + bool ArmMemoryInstructionAnalyzer::eval(address_t address, MemoryInstruction & result){ #ifdef CORTEXM3 #warning "Memory Accesses cannot be evaluated completely!" diff --git a/src/experiments/vezs-example/experiment.cc b/src/experiments/vezs-example/experiment.cc index db65e159..37b7e14b 100644 --- a/src/experiments/vezs-example/experiment.cc +++ b/src/experiments/vezs-example/experiment.cc @@ -50,6 +50,7 @@ bool VEZSExperiment::run() 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 << " Trigger PC: 0x" << std::hex << l_foo.getTriggerInstructionPointer() << std::endl; //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;