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:
Martin Hoffmann
2013-03-06 18:34:20 +01:00
parent 1fe1dbb3ed
commit f586351e79
13 changed files with 5016 additions and 23 deletions

View File

@ -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;

View File

@ -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

View 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;
}
}