diff --git a/parseAPI/src/IA_powerDetails.C b/parseAPI/src/IA_powerDetails.C
index de756a5d97..387cab2c5e 100644
--- a/parseAPI/src/IA_powerDetails.C
+++ b/parseAPI/src/IA_powerDetails.C
@@ -50,323 +50,323 @@ using namespace Dyninst::ParseAPI;
namespace Dyninst
{
- namespace InsnAdapter
- {
- namespace detail
+ namespace InsnAdapter
{
- class TOCandOffsetExtractor : public Dyninst::InstructionAPI::Visitor
- {
- public:
- TOCandOffsetExtractor(Address TOCvalue) : result(0), toc_contents(TOCvalue) {}
- virtual ~TOCandOffsetExtractor() {}
- virtual void visit(BinaryFunction* b) {
- Address arg1 = m_stack.front();
- m_stack.pop_front();
- Address arg2 = m_stack.front();
- m_stack.pop_front();
- if(b->isAdd()) {
- result = arg1 + arg2;
- } else if(b->isMultiply()) {
- result = arg1 * arg2;
- } else {
- assert(!"unexpected binary function!");
- result = 0;
- }
- parsing_printf("\tTOC visitor visiting binary function, result is 0x%lx\n",
- result);
- m_stack.push_front(result);
- }
- virtual void visit(Immediate* i) {
- Address tmp = i->eval().convert
();
- result = tmp;
- parsing_printf("\tTOC visitor visiting immediate, result is 0x%lx\n",
- result);
- m_stack.push_front(tmp);
- }
- virtual void visit(RegisterAST* r) {
- if(r->getID() == toc_reg->getID()) {
- m_stack.push_front(toc_contents);
- } else {
- m_stack.push_front(0);
- }
- result = m_stack.front();
- parsing_printf("\tTOC visitor visiting register, result is 0x%lx\n",
- result);
- }
- virtual void visit(Dereference*) {}
- void clear() {
- m_stack.clear();
- result = 0;
- }
- std::deque m_stack;
- Address result;
- Address toc_contents;
- RegisterAST::Ptr toc_reg;
- };
+ namespace detail
+ {
+ class TOCandOffsetExtractor : public Dyninst::InstructionAPI::Visitor
+ {
+ public:
+ TOCandOffsetExtractor(Address TOCvalue) : result(0), toc_contents(TOCvalue) {}
+ virtual ~TOCandOffsetExtractor() {}
+ virtual void visit(BinaryFunction* b) {
+ Address arg1 = m_stack.front();
+ m_stack.pop_front();
+ Address arg2 = m_stack.front();
+ m_stack.pop_front();
+ if(b->isAdd()) {
+ result = arg1 + arg2;
+ } else if(b->isMultiply()) {
+ result = arg1 * arg2;
+ } else {
+ assert(!"unexpected binary function!");
+ result = 0;
+ }
+ parsing_printf("\tTOC visitor visiting binary function, result is 0x%lx\n",
+ result);
+ m_stack.push_front(result);
+ }
+ virtual void visit(Immediate* i) {
+ Address tmp = i->eval().convert();
+ result = tmp;
+ parsing_printf("\tTOC visitor visiting immediate, result is 0x%lx\n",
+ result);
+ m_stack.push_front(tmp);
+ }
+ virtual void visit(RegisterAST* r) {
+ if(r->getID() == toc_reg->getID()) {
+ m_stack.push_front(toc_contents);
+ } else {
+ m_stack.push_front(0);
+ }
+ result = m_stack.front();
+ parsing_printf("\tTOC visitor visiting register, result is 0x%lx\n",
+ result);
+ }
+ virtual void visit(Dereference*) {}
+ void clear() {
+ m_stack.clear();
+ result = 0;
+ }
+ std::deque m_stack;
+ Address result;
+ Address toc_contents;
+ RegisterAST::Ptr toc_reg;
+ };
+ }
}
- }
};
bool IA_powerDetails::findTableAddrNoTOC(const IA_IAPI* blockToCheck)
{
- std::set regs;
- std::set writeregs, readregs;
- RegisterAST::Ptr writereg, readreg;
- int dfgreg;
- std::set::iterator itw, itr;
- std::set::iterator itd;
- toc_visitor->clear();
- bool foundAddis = false;
- bool foundAddi = false;
- bool foundDep = false;
- while(patternIter != blockToCheck->allInsns.begin())
+ std::set regs;
+ std::set writeregs, readregs;
+ RegisterAST::Ptr writereg, readreg;
+ int dfgreg;
+ std::set::iterator itw, itr;
+ std::set::iterator itd;
+ toc_visitor->clear();
+ bool foundAddis = false;
+ bool foundAddi = false;
+ bool foundDep = false;
+ while(patternIter != blockToCheck->allInsns.begin())
{
- patternIter--;
- // Do backward dataflow analysis to match the registers that compute the jump table address
- parsing_printf("\tchecking insn %s at 0x%lx\n", patternIter->second->format().c_str(),
- patternIter->first);
- // Ignore rlwinm instruction since its used for the index and not the table start.
- // Also, remove it from the backwards DFG
- if(patternIter->second->getOperation().getID() == power_op_rlwinm){
- patternIter->second->getWriteSet(writeregs);
- for(itw=writeregs.begin(); itw!= writeregs.end(); itw++){
- writereg=*(itw);
- for(itd=dfgregs.begin(); itd!= dfgregs.end(); itd++){
- dfgreg = *itd;
- if (writereg->getID() == dfgreg) {
- parsing_printf("found Match - erasing rlwinm \n");
- dfgregs.erase(*itd);
- }
- }
- }
- continue;
- }
-
- writeregs.clear();
- patternIter->second->getWriteSet(writeregs);
- foundDep =false;
-
- for(itw=writeregs.begin(); itw!= writeregs.end(); itw++){
- writereg=*(itw);
- parsing_printf("Register Written %s \n", writereg->format().c_str());
- for(itd=dfgregs.begin(); itd!= dfgregs.end(); itd++){
- dfgreg = *itd;
- parsing_printf("DFG has %d \n", dfgreg);
- if (writereg->getID() == dfgreg) {
- parsing_printf("found Match \n");
- dfgregs.erase(*itd);
- readregs.clear();
- patternIter->second->getReadSet(readregs);
- for(itr=readregs.begin(); itr!= readregs.end(); itr++){
- readreg=*(itr);
- dfgregs.insert(readreg->getID());
- parsing_printf("Reading %s \n", readreg->format().c_str());
- }
- foundDep = true;
- break;
- }
- }
- }
- // We look for addi-addis combination.
- // These instruction can occur in any order and in any block before the indirect branch.
- // Also, there may be more than one addi instruction.
- // Hence, we use adjustTableStartAddress to keep track of immediate values from addi instructions.
- if(foundDep && !foundAddis &&
- (patternIter->second->getOperation().getID() == power_op_addi ||
- patternIter->second->getOperation().getID() == power_op_addic))
+ patternIter--;
+ // Do backward dataflow analysis to match the registers that compute the jump table address
+ parsing_printf("\tchecking insn %s at 0x%lx\n", patternIter->second->format().c_str(),
+ patternIter->first);
+ // Ignore rlwinm instruction since its used for the index and not the table start.
+ // Also, remove it from the backwards DFG
+ if(patternIter->second->getOperation().getID() == power_op_rlwinm){
+ patternIter->second->getWriteSet(writeregs);
+ for(itw=writeregs.begin(); itw!= writeregs.end(); itw++){
+ writereg=*(itw);
+ for(itd=dfgregs.begin(); itd!= dfgregs.end(); itd++){
+ dfgreg = *itd;
+ if (writereg->getID() == dfgreg) {
+ parsing_printf("found Match - erasing rlwinm \n");
+ dfgregs.erase(*itd);
+ }
+ }
+ }
+ continue;
+ }
+
+ writeregs.clear();
+ patternIter->second->getWriteSet(writeregs);
+ foundDep =false;
+
+ for(itw=writeregs.begin(); itw!= writeregs.end(); itw++){
+ writereg=*(itw);
+ parsing_printf("Register Written %s \n", writereg->format().c_str());
+ for(itd=dfgregs.begin(); itd!= dfgregs.end(); itd++){
+ dfgreg = *itd;
+ parsing_printf("DFG has %d \n", dfgreg);
+ if (writereg->getID() == dfgreg) {
+ parsing_printf("found Match \n");
+ dfgregs.erase(*itd);
+ readregs.clear();
+ patternIter->second->getReadSet(readregs);
+ for(itr=readregs.begin(); itr!= readregs.end(); itr++){
+ readreg=*(itr);
+ dfgregs.insert(readreg->getID());
+ parsing_printf("Reading %s \n", readreg->format().c_str());
+ }
+ foundDep = true;
+ break;
+ }
+ }
+ }
+ // We look for addi-addis combination.
+ // These instruction can occur in any order and in any block before the indirect branch.
+ // Also, there may be more than one addi instruction.
+ // Hence, we use adjustTableStartAddress to keep track of immediate values from addi instructions.
+ if(foundDep && !foundAddis &&
+ (patternIter->second->getOperation().getID() == power_op_addi ||
+ patternIter->second->getOperation().getID() == power_op_addic))
{
- std::set tmpregs;
- patternIter->second->getReadSet(tmpregs);
- if(tmpregs.size() != 1) {
- continue;
- }
- regs.clear();
- patternIter->second->getReadSet(regs);
- if(regs.size() != 1) {
- continue;
- }
- parsing_printf("\tfound 0x%lx: %s, checking for addis previous\n",
- patternIter->first,
- patternIter->second->format().c_str());
- foundAddi = true;
- toc_visitor->clear();
- patternIter->second->getOperand(2).getValue()->apply(toc_visitor.get());
- adjustTableStartAddress += toc_visitor->result;
- }
- else if(foundDep && !foundAddi && patternIter->second->getOperation().getID() == power_op_addis)
- {
- std::set tmpregs;
- patternIter->second->getReadSet(tmpregs);
- if(tmpregs.size() != 1) {
- continue;
- }
- regs.clear();
- patternIter->second->getReadSet(regs);
- if(regs.size() != 1) {
- continue;
- }
- parsing_printf("\tfound 0x%lx: %s, checking for addi previous\n",
- patternIter->first,
- patternIter->second->format().c_str());
- foundAddis = true;
- toc_visitor->clear();
- patternIter->second->getOperand(2).getValue()->apply(toc_visitor.get());
- tableStartAddress = toc_visitor->result;
- tableStartAddress *= 10000;
- tableStartAddress &= 0xFFFF0000;
-
- } else if( foundDep && foundAddi &&
- patternIter->second &&
- (patternIter->second->getOperation().getID() == power_op_addis) &&
- patternIter->second->isWritten(*(regs.begin())))
- {
- foundAddis = true;
- parsing_printf("\tfound 0x%lx: %s, setting tableStartAddress\n",
- patternIter->first,
- patternIter->second->format().c_str());
- toc_visitor->clear();
- patternIter->second->getOperand(2).getValue()->apply(toc_visitor.get());
- tableStartAddress += (toc_visitor->result * 0x10000) & 0xFFFF0000;
- parsing_printf("\ttableStartAddress = 0x%lx\n",
- tableStartAddress);
- break;
- } else if( foundDep && foundAddis &&
- patternIter->second &&
- ((patternIter->second->getOperation().getID() == power_op_addi) ||
- (patternIter->second->getOperation().getID() == power_op_addic)) &&
- patternIter->second->isWritten(*(regs.begin())))
- {
- foundAddi = true;
- parsing_printf("\tfound 0x%lx: %s, setting tableStartAddress\n",
- patternIter->first,
- patternIter->second->format().c_str());
- toc_visitor->clear();
- patternIter->second->getOperand(2).getValue()->apply(toc_visitor.get());
- tableStartAddress += toc_visitor->result;
- parsing_printf("\ttableStartAddress = 0x%lx\n", tableStartAddress);
- break;
- }
+ std::set tmpregs;
+ patternIter->second->getReadSet(tmpregs);
+ if(tmpregs.size() != 1) {
+ continue;
+ }
+ regs.clear();
+ patternIter->second->getReadSet(regs);
+ if(regs.size() != 1) {
+ continue;
+ }
+ parsing_printf("\tfound 0x%lx: %s, checking for addis previous\n",
+ patternIter->first,
+ patternIter->second->format().c_str());
+ foundAddi = true;
+ toc_visitor->clear();
+ patternIter->second->getOperand(2).getValue()->apply(toc_visitor.get());
+ adjustTableStartAddress += toc_visitor->result;
+ }
+ else if(foundDep && !foundAddi && patternIter->second->getOperation().getID() == power_op_addis)
+ {
+ std::set tmpregs;
+ patternIter->second->getReadSet(tmpregs);
+ if(tmpregs.size() != 1) {
+ continue;
+ }
+ regs.clear();
+ patternIter->second->getReadSet(regs);
+ if(regs.size() != 1) {
+ continue;
+ }
+ parsing_printf("\tfound 0x%lx: %s, checking for addi previous\n",
+ patternIter->first,
+ patternIter->second->format().c_str());
+ foundAddis = true;
+ toc_visitor->clear();
+ patternIter->second->getOperand(2).getValue()->apply(toc_visitor.get());
+ tableStartAddress = toc_visitor->result;
+ tableStartAddress *= 10000;
+ tableStartAddress &= 0xFFFF0000;
+
+ } else if( foundDep && foundAddi &&
+ patternIter->second &&
+ (patternIter->second->getOperation().getID() == power_op_addis) &&
+ patternIter->second->isWritten(*(regs.begin())))
+ {
+ foundAddis = true;
+ parsing_printf("\tfound 0x%lx: %s, setting tableStartAddress\n",
+ patternIter->first,
+ patternIter->second->format().c_str());
+ toc_visitor->clear();
+ patternIter->second->getOperand(2).getValue()->apply(toc_visitor.get());
+ tableStartAddress += (toc_visitor->result * 0x10000) & 0xFFFF0000;
+ parsing_printf("\ttableStartAddress = 0x%lx\n",
+ tableStartAddress);
+ break;
+ } else if( foundDep && foundAddis &&
+ patternIter->second &&
+ ((patternIter->second->getOperation().getID() == power_op_addi) ||
+ (patternIter->second->getOperation().getID() == power_op_addic)) &&
+ patternIter->second->isWritten(*(regs.begin())))
+ {
+ foundAddi = true;
+ parsing_printf("\tfound 0x%lx: %s, setting tableStartAddress\n",
+ patternIter->first,
+ patternIter->second->format().c_str());
+ toc_visitor->clear();
+ patternIter->second->getOperand(2).getValue()->apply(toc_visitor.get());
+ tableStartAddress += toc_visitor->result;
+ parsing_printf("\ttableStartAddress = 0x%lx\n", tableStartAddress);
+ break;
+ }
}
- if (!foundAddi || !foundAddis)
- tableStartAddress = 0;
- else
- tableStartAddress += adjustTableStartAddress;
+ if (!foundAddi || !foundAddis)
+ tableStartAddress = 0;
+ else
+ tableStartAddress += adjustTableStartAddress;
- parsing_printf(" TABLE START 0x%lx 0x%lx %ld\n", tableStartAddress, adjustTableStartAddress, adjustTableStartAddress);
+ parsing_printf(" TABLE START 0x%lx 0x%lx %ld\n", tableStartAddress, adjustTableStartAddress, adjustTableStartAddress);
- // If we've found an addi/addis combination and it's a relative table, look for a mfspr/thunk combination that
- // feeds that...
- if(tableStartAddress && tableIsRelative)
+ // If we've found an addi/addis combination and it's a relative table, look for a mfspr/thunk combination that
+ // feeds that...
+ if(tableStartAddress && tableIsRelative)
{
- parsing_printf("\ttableStartAddress non-zero, tableIsRelative true\n");
- bool foundThunk = false;
- bool foundMFSPR = false;
- Address GOTaddress = 0;
- while(patternIter != blockToCheck->allInsns.begin())
+ parsing_printf("\ttableStartAddress non-zero, tableIsRelative true\n");
+ bool foundThunk = false;
+ bool foundMFSPR = false;
+ Address GOTaddress = 0;
+ while(patternIter != blockToCheck->allInsns.begin())
{
- patternIter--;
- if(patternIter->second->getOperation().getID() == power_op_mfspr &&
- patternIter->second->isWritten(*(regs.begin())))
+ patternIter--;
+ if(patternIter->second->getOperation().getID() == power_op_mfspr &&
+ patternIter->second->isWritten(*(regs.begin())))
{
- foundMFSPR = true;
- break;
+ foundMFSPR = true;
+ break;
}
}
- while(patternIter != blockToCheck->allInsns.begin())
+ while(patternIter != blockToCheck->allInsns.begin())
{
- patternIter--;
- if(patternIter->second->getCategory() == c_CallInsn) // mid-block call, must be a thunk
+ patternIter--;
+ if(patternIter->second->getCategory() == c_CallInsn) // mid-block call, must be a thunk
{
- patternIter++;
- parsing_printf("\tfound thunk/mfspr combo, adjusting tableStartAddress by 0x%lx\n", patternIter->first);
- GOTaddress = tableStartAddress + patternIter->first;
- foundThunk = true;
- break;
+ patternIter++;
+ parsing_printf("\tfound thunk/mfspr combo, adjusting tableStartAddress by 0x%lx\n", patternIter->first);
+ GOTaddress = tableStartAddress + patternIter->first;
+ foundThunk = true;
+ break;
}
}
- if(foundThunk && foundMFSPR)
+ if(foundThunk && foundMFSPR)
{
- toc_visitor->toc_reg = *(regs.begin());
- toc_reg = toc_visitor->toc_reg;
- toc_visitor->toc_contents = GOTaddress;
- tableStartAddress = 0;
- patternIter = currentBlock->curInsnIter;
- parsing_printf("\t calling parseRelativeTableIdiom with toc_reg %s\n", toc_visitor->toc_reg->format().c_str());
- return parseRelativeTableIdiom();
+ toc_visitor->toc_reg = *(regs.begin());
+ toc_reg = toc_visitor->toc_reg;
+ toc_visitor->toc_contents = GOTaddress;
+ tableStartAddress = 0;
+ patternIter = currentBlock->curInsnIter;
+ parsing_printf("\t calling parseRelativeTableIdiom with toc_reg %s\n", toc_visitor->toc_reg->format().c_str());
+ return parseRelativeTableIdiom();
}
}
- else
+ else
{
- parsing_printf("\ttableStartAddress = 0x%lx, tableIsRelative = %s\n", tableStartAddress,
- tableIsRelative ? "true" : "false");
+ parsing_printf("\ttableStartAddress = 0x%lx, tableIsRelative = %s\n", tableStartAddress,
+ tableIsRelative ? "true" : "false");
}
- return tableStartAddress == 0;
+ return tableStartAddress == 0;
}
bool IA_powerDetails::parseRelativeTableIdiom()
{
- bool foundAddress = false;
- while(patternIter != currentBlock->allInsns.begin())
+ bool foundAddress = false;
+ while(patternIter != currentBlock->allInsns.begin())
{
- patternIter--;
- parsing_printf("\t checking 0x%lx: %s for lwz/ld\n", patternIter->first, patternIter->second->format().c_str());
- if((patternIter->second->getOperation().getID() == power_op_lwz ||
- patternIter->second->getOperation().getID() == power_op_ld) &&
- patternIter->second->isRead(toc_reg))
+ patternIter--;
+ parsing_printf("\t checking 0x%lx: %s for lwz/ld\n", patternIter->first, patternIter->second->format().c_str());
+ if((patternIter->second->getOperation().getID() == power_op_lwz ||
+ patternIter->second->getOperation().getID() == power_op_ld) &&
+ patternIter->second->isRead(toc_reg))
{
- toc_visitor->clear();
- patternIter->second->getOperand(1).getValue()->apply(toc_visitor.get());
- parsing_printf("%s[%d]: setting jumpStartAddress to 0x%lx, insn %s, TOC 0x%lx\n", FILE__, __LINE__,
- toc_visitor->result, patternIter->second->format().c_str(), toc_visitor->toc_contents);
- jumpStartAddress = toc_visitor->result;
- foundAddress = true;
- tableStartAddress = jumpStartAddress;
- adjustEntry = 0;
- break;
+ toc_visitor->clear();
+ patternIter->second->getOperand(1).getValue()->apply(toc_visitor.get());
+ parsing_printf("%s[%d]: setting jumpStartAddress to 0x%lx, insn %s, TOC 0x%lx\n", FILE__, __LINE__,
+ toc_visitor->result, patternIter->second->format().c_str(), toc_visitor->toc_contents);
+ jumpStartAddress = toc_visitor->result;
+ foundAddress = true;
+ tableStartAddress = jumpStartAddress;
+ adjustEntry = 0;
+ break;
}
}
- if(patternIter == currentBlock->allInsns.begin())
+ if(patternIter == currentBlock->allInsns.begin())
{
- if (foundAddress) {
- return true;
- } else {
-
- // If we've already backed up to the beginning, we're not going to find a legit table
- // start address; bail now.
- parsing_printf("%s[%d]: jumpStartAddress insn was first in block w/relative table, ret false\n",
- FILE__, __LINE__);
- return false;
- }
+ if (foundAddress) {
+ return true;
+ } else {
+
+ // If we've already backed up to the beginning, we're not going to find a legit table
+ // start address; bail now.
+ parsing_printf("%s[%d]: jumpStartAddress insn was first in block w/relative table, ret false\n",
+ FILE__, __LINE__);
+ return false;
+ }
}
- // Anyone know what this does?
- patternIter--;
- if((patternIter->second->getOperation().getID() == power_op_lwz ||
- patternIter->second->getOperation().getID() == power_op_ld))
+ // Anyone know what this does?
+ patternIter--;
+ if((patternIter->second->getOperation().getID() == power_op_lwz ||
+ patternIter->second->getOperation().getID() == power_op_ld))
{
- toc_visitor->clear();
- patternIter->second->getOperand(1).getValue()->apply(toc_visitor.get());
- adjustEntry = toc_visitor->result;
- foundAdjustEntry = true;
- parsing_printf("%s[%d]: setting adjustEntry to 0x%lx, insn %s, TOC 0x%lx\n", FILE__, __LINE__,
- toc_visitor->result, patternIter->second->format().c_str(), toc_visitor->toc_contents);
+ toc_visitor->clear();
+ patternIter->second->getOperand(1).getValue()->apply(toc_visitor.get());
+ adjustEntry = toc_visitor->result;
+ foundAdjustEntry = true;
+ parsing_printf("%s[%d]: setting adjustEntry to 0x%lx, insn %s, TOC 0x%lx\n", FILE__, __LINE__,
+ toc_visitor->result, patternIter->second->format().c_str(), toc_visitor->toc_contents);
}
- while(patternIter != currentBlock->allInsns.begin()){
- patternIter--;
- if((patternIter->second->getOperation().getID() == power_op_lwz ||
- patternIter->second->getOperation().getID() == power_op_ld) &&
- patternIter->second->isRead(toc_reg))
- {
- toc_visitor->clear();
- patternIter->second->getOperand(1).getValue()->apply(toc_visitor.get());
- tableStartAddress = toc_visitor->result;
- parsing_printf("%s[%d]: setting tableStartAddress to 0x%lx, insn %s, TOC 0x%lx\n", FILE__, __LINE__,
- toc_visitor->result, patternIter->second->format().c_str(), toc_visitor->toc_contents);
- break;
- }
- }
- return true;
+ while(patternIter != currentBlock->allInsns.begin()){
+ patternIter--;
+ if((patternIter->second->getOperation().getID() == power_op_lwz ||
+ patternIter->second->getOperation().getID() == power_op_ld) &&
+ patternIter->second->isRead(toc_reg))
+ {
+ toc_visitor->clear();
+ patternIter->second->getOperand(1).getValue()->apply(toc_visitor.get());
+ tableStartAddress = toc_visitor->result;
+ parsing_printf("%s[%d]: setting tableStartAddress to 0x%lx, insn %s, TOC 0x%lx\n", FILE__, __LINE__,
+ toc_visitor->result, patternIter->second->format().c_str(), toc_visitor->toc_contents);
+ break;
+ }
+ }
+ return true;
}
namespace detail_ppc
@@ -380,108 +380,109 @@ namespace detail_ppc
Block* src = e->src();
return visited.find(src) != visited.end();
}
- void processPredecessor(Edge* e, std::set& visited, std::deque& worklist)
- {
- parsing_printf("\t\tblock %x, edge type %s\n",
- e->src()->start(),
- format(e->type()).c_str());
-
- // FIXME debugging assert
- assert(isNonCallEdge(e));
-
- // FIXME check this algorithm... O(log n) lookup in visited
- if(!leadsToVisitedBlock(e, visited))
+ void processPredecessor(Edge* e, std::set& visited, std::deque& worklist)
{
- worklist.push_back(e->src());
- visited.insert(e->src());
- }
- }
+ parsing_printf("\t\tblock %x, edge type %s\n",
+ e->src()->start(),
+ format(e->type()).c_str());
+
+ // FIXME debugging assert
+ assert(isNonCallEdge(e));
+
+ // FIXME check this algorithm... O(log n) lookup in visited
+ if(!leadsToVisitedBlock(e, visited))
+ {
+ worklist.push_back(e->src());
+ visited.insert(e->src());
+ }
+ }
};
bool IA_powerDetails::scanForAdjustOrBase(IA_IAPI::allInsns_t::const_iterator start,
- IA_IAPI::allInsns_t::const_iterator end,
- RegisterAST::Ptr &jumpAddrReg) {
- std::set scratchRegs;
- std::set loadRegs;
- loadRegs.insert(jumpAddrReg);
- for (; start != end; --start) {
- InstructionAPI::Instruction::Ptr insn = start->second;
- parsing_printf("\t\t Examining 0x%lx / %s\n",
- start->first, start->second->format().c_str());
-
- if ((insn->getOperation().getID() == power_op_ld ||
- insn->getOperation().getID() == power_op_ldx) &&
- insn->isWritten(jumpAddrReg)) {
- scratchRegs.clear();
- insn->getReadSet(scratchRegs);
- loadRegs.insert(scratchRegs.begin(), scratchRegs.end());
- parsing_printf("Found a load; now have %d load regs\n", loadRegs.size());
- }
- else if(insn->getOperation().getID() == power_op_addi &&
- !foundAdjustEntry) {
- parsing_printf("Found add immediate (%d load regs)...\n", loadRegs.size());
- scratchRegs.clear();
- insn->getWriteSet(scratchRegs);
-
- bool found = false;
- // This is apparently broken
- for (std::set::iterator iter = loadRegs.begin(); iter != loadRegs.end(); ++iter) {
- RegisterAST *tmp = (*iter).get();
- RegisterAST *cmp = (*(scratchRegs.begin())).get();
- if (*tmp == *cmp) {
- found = true;
- break;
- }
- }
- if (!found) continue;
-
- parsing_printf("... that adds to a load reg\n");
- foundAdjustEntry = true;
- toc_visitor->clear();
- parsing_printf("... with operand %s\n", insn->getOperand(1).format(insn->getArch(), start->first).c_str());
- insn->getOperand(1).getValue()->apply(toc_visitor.get());
- adjustEntry = toc_visitor->result;
- if (!adjustEntry)
- insn->getOperand(2).getValue()->apply(toc_visitor.get());
- adjustEntry = toc_visitor->result;
+ IA_IAPI::allInsns_t::const_iterator end,
+ RegisterAST::Ptr &jumpAddrReg) {
+ std::set scratchRegs;
+ std::set loadRegs;
+ loadRegs.insert(jumpAddrReg);
+ for (; start != end; --start) {
+ InstructionAPI::Instruction::Ptr insn = start->second;
+ parsing_printf("\t\t Examining 0x%lx / %s\n",
+ start->first, start->second->format().c_str());
+
+ if ((insn->getOperation().getID() == power_op_ld ||
+ insn->getOperation().getID() == power_op_ldx) &&
+ insn->isWritten(jumpAddrReg)) {
+ scratchRegs.clear();
+ insn->getReadSet(scratchRegs);
+ loadRegs.insert(scratchRegs.begin(), scratchRegs.end());
+ parsing_printf("Found a load; now have %d load regs\n", loadRegs.size());
+ }
+ else if(insn->getOperation().getID() == power_op_addi &&
+ !foundAdjustEntry) {
+ parsing_printf("Found add immediate (%d load regs)...\n", loadRegs.size());
+ scratchRegs.clear();
+ insn->getWriteSet(scratchRegs);
+
+ bool found = false;
+ // This is apparently broken
+ for (std::set::iterator iter = loadRegs.begin(); iter != loadRegs.end(); ++iter) {
+ RegisterAST *tmp = (*iter).get();
+ RegisterAST *cmp = (*(scratchRegs.begin())).get();
+ if (*tmp == *cmp) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) continue;
+
+ parsing_printf("... that adds to a load reg\n");
+ foundAdjustEntry = true;
+ toc_visitor->clear();
+ parsing_printf("... with operand %s\n", insn->getOperand(1).format(insn->getArch(), start->first).c_str());
+ insn->getOperand(1).getValue()->apply(toc_visitor.get());
+ adjustEntry = toc_visitor->result;
+ if (!adjustEntry)
+ insn->getOperand(2).getValue()->apply(toc_visitor.get());
+ adjustEntry = toc_visitor->result;
+ }
+ else if((insn->getOperation().getID() == power_op_lwz ||
+ insn->getOperation().getID() == power_op_ld) &&
+ insn->isRead(toc_reg) &&
+ insn->isWritten(jumpAddrReg))
+ {
+ parsing_printf("\t found TOC load at %s\n", insn->format().c_str());
+ toc_visitor->clear();
+ insn->getOperand(1).getValue()->apply(toc_visitor.get());
+ tableStartAddress = toc_visitor->result;
+ break;
+ }
}
- else if((insn->getOperation().getID() == power_op_lwz ||
- insn->getOperation().getID() == power_op_ld) &&
- insn->isRead(toc_reg) &&
- insn->isWritten(jumpAddrReg))
- {
- parsing_printf("\t found TOC load at %s\n", insn->format().c_str());
- toc_visitor->clear();
- insn->getOperand(1).getValue()->apply(toc_visitor.get());
- tableStartAddress = toc_visitor->result;
- break;
- }
- }
- return true;
+ return true;
}
// Like the above, but a wider net
bool IA_powerDetails::findTableBase(IA_IAPI::allInsns_t::const_iterator start,
- IA_IAPI::allInsns_t::const_iterator end) {
- for (; start != end; --start) {
- parsing_printf("\t\t Examining 0x%lx / %s\n",
- start->first, start->second->format().c_str());
- if((start->second->getOperation().getID() == power_op_lwz ||
- start->second->getOperation().getID() == power_op_ld) &&
- start->second->isRead(toc_reg)) {
- parsing_printf("\t found TOC load at %s\n", start->second->format().c_str());
- toc_visitor->clear();
- start->second->getOperand(1).getValue()->apply(toc_visitor.get());
- tableStartAddress = toc_visitor->result;
- break;
+ IA_IAPI::allInsns_t::const_iterator end) {
+ for (; start != end; --start) {
+ if(!start->second) continue;
+ parsing_printf("\t\t Examining 0x%lx / %s\n",
+ start->first, start->second->format().c_str());
+ if((start->second->getOperation().getID() == power_op_lwz ||
+ start->second->getOperation().getID() == power_op_ld) &&
+ start->second->isRead(toc_reg)) {
+ parsing_printf("\t found TOC load at %s\n", start->second->format().c_str());
+ toc_visitor->clear();
+ start->second->getOperand(1).getValue()->apply(toc_visitor.get());
+ tableStartAddress = toc_visitor->result;
+ break;
+ }
}
- }
- return true;
+ return true;
}
bool IA_powerDetails::parseJumpTable(Function *,
Block* currBlk,
- std::vector >& outEdges)
+ std::vector >& outEdges)
{
return parseJumpTable(currBlk, outEdges);
}
@@ -490,392 +491,392 @@ bool IA_powerDetails::parseJumpTable(Function *,
// This should only be called on a known indirect branch...
bool IA_powerDetails::parseJumpTable(Block* currBlk,
- std::vector >& outEdges)
+ std::vector >& outEdges)
{
- Address initialAddress = currentBlock->current;
- toc_reg.reset(new RegisterAST(ppc32::r2));
-
- TOC_address = currentBlock->_obj->cs()->getTOC();
- toc_visitor.reset(new detail::TOCandOffsetExtractor(TOC_address));
- toc_visitor->toc_reg = toc_reg;
-
- // If there are no prior instructions then we can't be looking at a
- // jump through a jump table.
- if(currentBlock->allInsns.size() < 2) {
- parsing_printf("%s[%d]: allInsns.size() == %d, ret false", FILE__, __LINE__, currentBlock->allInsns.size());
- return false;
- }
-
-
- // Check if the previous instruction is a move to CTR or LR;
- // if it is, then this is the pattern we're familiar with. The
- // register being moved into CTR or LR has the address to jump to.
- patternIter = currentBlock->curInsnIter;
- patternIter--;
- RegisterAST::Ptr jumpAddrReg;
- std::set regs;
- if(patternIter->second->getOperation().getID() == power_op_mtspr)
+ Address initialAddress = currentBlock->current;
+ toc_reg.reset(new RegisterAST(ppc32::r2));
+
+ TOC_address = currentBlock->_obj->cs()->getTOC();
+ toc_visitor.reset(new detail::TOCandOffsetExtractor(TOC_address));
+ toc_visitor->toc_reg = toc_reg;
+
+ // If there are no prior instructions then we can't be looking at a
+ // jump through a jump table.
+ if(currentBlock->allInsns.size() < 2) {
+ parsing_printf("%s[%d]: allInsns.size() == %d, ret false", FILE__, __LINE__, currentBlock->allInsns.size());
+ return false;
+ }
+
+
+ // Check if the previous instruction is a move to CTR or LR;
+ // if it is, then this is the pattern we're familiar with. The
+ // register being moved into CTR or LR has the address to jump to.
+ patternIter = currentBlock->curInsnIter;
+ patternIter--;
+ RegisterAST::Ptr jumpAddrReg;
+ std::set regs;
+ if(patternIter->second->getOperation().getID() == power_op_mtspr)
{
- regs.clear();
- patternIter->second->getReadSet(regs);
- if(regs.size() != 1) {
- parsing_printf("expected mtspr to read 1 register, insn is %s\n", patternIter->second->format().c_str());
- return false;
- }
- jumpAddrReg = *(regs.begin());
- parsing_printf("%s[%d]: JUMPREG %s mtspr at prev insn %s \n", FILE__, __LINE__, jumpAddrReg->format().c_str(), patternIter->second->format().c_str());
- dfgregs.insert(jumpAddrReg->getID());
+ regs.clear();
+ patternIter->second->getReadSet(regs);
+ if(regs.size() != 1) {
+ parsing_printf("expected mtspr to read 1 register, insn is %s\n", patternIter->second->format().c_str());
+ return false;
+ }
+ jumpAddrReg = *(regs.begin());
+ parsing_printf("%s[%d]: JUMPREG %s mtspr at prev insn %s \n", FILE__, __LINE__, jumpAddrReg->format().c_str(), patternIter->second->format().c_str());
+ dfgregs.insert(jumpAddrReg->getID());
}
- else
+ else
{
- parsing_printf("%s[%d]: couldn't find mtspr at prev insn %s, ret false", FILE__, __LINE__,
- patternIter->second->format().c_str());
- return false;
+ parsing_printf("%s[%d]: couldn't find mtspr at prev insn %s, ret false", FILE__, __LINE__,
+ patternIter->second->format().c_str());
+ return false;
}
- assert(jumpAddrReg);
- // In the pattern we've seen, if the instruction previous to this is
- // an add with a result that ends up being used as the jump address,
- // then we're adding a relative value we got from the table to a base
- // address to get the jump address; in other words, the contents of
- // the jump table are relative.
- tableIsRelative = false;
- if(patternIter != currentBlock->allInsns.begin())
+ assert(jumpAddrReg);
+ // In the pattern we've seen, if the instruction previous to this is
+ // an add with a result that ends up being used as the jump address,
+ // then we're adding a relative value we got from the table to a base
+ // address to get the jump address; in other words, the contents of
+ // the jump table are relative.
+ tableIsRelative = false;
+ if(patternIter != currentBlock->allInsns.begin())
{
- patternIter--;
- if(patternIter->second->getOperation().getID() == power_op_add &&
- patternIter->second->isWritten(*(regs.begin())))
+ patternIter--;
+ if(patternIter->second->getOperation().getID() == power_op_add &&
+ patternIter->second->isWritten(*(regs.begin())))
{
- tableIsRelative = true;
+ tableIsRelative = true;
}
}
- parsing_printf(" TableIsRelative %d\n", tableIsRelative);
-
- patternIter = currentBlock->curInsnIter;
-
- jumpStartAddress = 0;
- adjustEntry = 0;
- tableStartAddress = 0;
- adjustTableStartAddress = 0;
- foundAdjustEntry = false;
-
- parsing_printf("\t TOC_address 0x%lx\n", TOC_address);
- if(!TOC_address)
+ parsing_printf(" TableIsRelative %d\n", tableIsRelative);
+
+ patternIter = currentBlock->curInsnIter;
+
+ jumpStartAddress = 0;
+ adjustEntry = 0;
+ tableStartAddress = 0;
+ adjustTableStartAddress = 0;
+ foundAdjustEntry = false;
+
+ parsing_printf("\t TOC_address 0x%lx\n", TOC_address);
+ if(!TOC_address)
{
- // Find addi-addis instructions to determine the jump table start address.
- // These instructions can be anywhere in the function before the
- // indirect jump.Hence parse through the current block and previous block
- // till we reach the function entry.
- Block* worklistBlock = currBlk;
- std::set visited;
- std::deque worklist;
- worklist.insert(worklist.begin(), worklistBlock);
- visited.insert(worklistBlock);
- Intraproc epred;
- parsing_printf("Looking for table start address over blocks to function entry\n");
- while(!worklist.empty())
+ // Find addi-addis instructions to determine the jump table start address.
+ // These instructions can be anywhere in the function before the
+ // indirect jump.Hence parse through the current block and previous block
+ // till we reach the function entry.
+ Block* worklistBlock = currBlk;
+ std::set visited;
+ std::deque worklist;
+ worklist.insert(worklist.begin(), worklistBlock);
+ visited.insert(worklistBlock);
+ Intraproc epred;
+ parsing_printf("Looking for table start address over blocks to function entry\n");
+ while(!worklist.empty())
{
- worklistBlock= worklist.front();
- worklist.pop_front();
- parsing_printf("\tAddress low 0x%lx high 0x%lx current block 0x%lx low 0x%lx high 0x%lx \n", worklistBlock->low(), worklistBlock->high(), currentBlock->current, currBlk->low(), currBlk->high());
- Address blockStart = worklistBlock->start();
- const unsigned char* b = (const unsigned char*)(currentBlock->_isrc->getPtrToInstruction(blockStart));
- parsing_printf(" Block start 0x%lx \n", blockStart);
- InstructionDecoder dec(b, worklistBlock->size(), currentBlock->_isrc->getArch());
- IA_IAPI IABlock(dec, blockStart, currentBlock->_obj, currentBlock->_cr, currentBlock->_isrc, worklistBlock);
-
- while(IABlock.getInstruction() && !IABlock.hasCFT()) {
- IABlock.advance();
- }
-
- patternIter = IABlock.curInsnIter;
- findTableAddrNoTOC(&IABlock);
- if(!jumpStartAddress)
- {
- jumpStartAddress = tableStartAddress;
- }
- if (tableStartAddress != 0) {
- jumpStartAddress = tableStartAddress;
- parsing_printf("\t\tjumpStartAddress 0x%lx \n", jumpStartAddress);
- break;
- }
- std::for_each(boost::make_filter_iterator(epred, worklistBlock->sources().begin(), worklistBlock->sources().end()),
- boost::make_filter_iterator(epred, worklistBlock->sources().end(), worklistBlock->sources().end()),
- boost::bind(detail_ppc::processPredecessor, _1, boost::ref(visited), boost::ref(worklist)));
+ worklistBlock= worklist.front();
+ worklist.pop_front();
+ parsing_printf("\tAddress low 0x%lx high 0x%lx current block 0x%lx low 0x%lx high 0x%lx \n", worklistBlock->low(), worklistBlock->high(), currentBlock->current, currBlk->low(), currBlk->high());
+ Address blockStart = worklistBlock->start();
+ const unsigned char* b = (const unsigned char*)(currentBlock->_isrc->getPtrToInstruction(blockStart));
+ parsing_printf(" Block start 0x%lx \n", blockStart);
+ InstructionDecoder dec(b, worklistBlock->size(), currentBlock->_isrc->getArch());
+ IA_IAPI IABlock(dec, blockStart, currentBlock->_obj, currentBlock->_cr, currentBlock->_isrc, worklistBlock);
+
+ while(IABlock.getInstruction() && !IABlock.hasCFT()) {
+ IABlock.advance();
+ }
+
+ patternIter = IABlock.curInsnIter;
+ findTableAddrNoTOC(&IABlock);
+ if(!jumpStartAddress)
+ {
+ jumpStartAddress = tableStartAddress;
+ }
+ if (tableStartAddress != 0) {
+ jumpStartAddress = tableStartAddress;
+ parsing_printf("\t\tjumpStartAddress 0x%lx \n", jumpStartAddress);
+ break;
+ }
+ std::for_each(boost::make_filter_iterator(epred, worklistBlock->sources().begin(), worklistBlock->sources().end()),
+ boost::make_filter_iterator(epred, worklistBlock->sources().end(), worklistBlock->sources().end()),
+ boost::bind(detail_ppc::processPredecessor, _1, boost::ref(visited), boost::ref(worklist)));
}
}
- else if (tableIsRelative) {
- if(!parseRelativeTableIdiom())
- {
- return false;
- }
- } else {
- parsing_printf("\t Table is not relative and we know the TOC is 0x%lx, searching for table base\n",
- TOC_address);
- foundAdjustEntry = false;
-
- scanForAdjustOrBase(patternIter, currentBlock->allInsns.begin(), jumpAddrReg);
-
- if (!tableStartAddress) {
- // Keep looking in the immediate predecessor - XLC
- for (Block::edgelist::const_iterator e_iter = currBlk->sources().begin();
- e_iter != currBlk->sources().end(); ++e_iter) {
- Address blockStart = (*e_iter)->src()->start();
- const unsigned char* b = (const unsigned char*)(currentBlock->_isrc->getPtrToInstruction(blockStart));
- InstructionDecoder dec(b, (*e_iter)->src()->size(), currentBlock->_isrc->getArch());
- IA_IAPI IABlock(dec, blockStart, currentBlock->_obj, currentBlock->_cr, currentBlock->_isrc, (*e_iter)->src());
-
- // Cache instructions
- while(IABlock.getInstruction() && !IABlock.hasCFT()) {
- IABlock.advance();
- }
-
- IA_IAPI::allInsns_t::const_iterator localIter = IABlock.curInsnIter;
- findTableBase(localIter, IABlock.allInsns.begin());
- }
- }
- }
-
- const Block::edgelist & sourceEdges = currBlk->sources();
- if(sourceEdges.size() != 1 || (*sourceEdges.begin())->type() == CALL) {
- parsing_printf("%s[%d]: jump table not properly guarded, ret false\n", FILE__, __LINE__);
- return false;
- }
-
-
-
- // We could also set this = jumpStartAddress...
- if (tableStartAddress == 0) {
- parsing_printf("%s[%d]: couldn't find table start addr, ret false\n", FILE__, __LINE__);
- return false;
-
- }
-
- parsing_printf("%s[%d]: table start addr is 0x%x\n", FILE__, __LINE__, tableStartAddress);
- int maxSwitch = 0;
-
- Block* sourceBlock = (*sourceEdges.begin())->src();
- Address blockStart = sourceBlock->start();
- const unsigned char* b = (const unsigned char*)(currentBlock->_isrc->getPtrToInstruction(blockStart));
- InstructionDecoder dec(b, sourceBlock->size(), currentBlock->_isrc->getArch());
- IA_IAPI prevBlock(dec, blockStart,currentBlock->_obj,currentBlock->_cr,currentBlock->_isrc, sourceBlock);
- while(!prevBlock.hasCFT() && prevBlock.getInstruction()) {
- prevBlock.advance();
- }
-
- parsing_printf("%s[%d]: checking for max switch...\n", FILE__, __LINE__);
- bool foundBranch = false;
- IA_IAPI::allInsns_t::reverse_iterator iter;
- for(iter = prevBlock.allInsns.rbegin(); iter != prevBlock.allInsns.rend(); iter++)
+ else if (tableIsRelative) {
+ if(!parseRelativeTableIdiom())
+ {
+ return false;
+ }
+ } else {
+ parsing_printf("\t Table is not relative and we know the TOC is 0x%lx, searching for table base\n",
+ TOC_address);
+ foundAdjustEntry = false;
+
+ scanForAdjustOrBase(patternIter, currentBlock->allInsns.begin(), jumpAddrReg);
+
+ if (!tableStartAddress) {
+ // Keep looking in the immediate predecessor - XLC
+ for (Block::edgelist::const_iterator e_iter = currBlk->sources().begin();
+ e_iter != currBlk->sources().end(); ++e_iter) {
+ Address blockStart = (*e_iter)->src()->start();
+ const unsigned char* b = (const unsigned char*)(currentBlock->_isrc->getPtrToInstruction(blockStart));
+ InstructionDecoder dec(b, (*e_iter)->src()->size(), currentBlock->_isrc->getArch());
+ IA_IAPI IABlock(dec, blockStart, currentBlock->_obj, currentBlock->_cr, currentBlock->_isrc, (*e_iter)->src());
+
+ // Cache instructions
+ while(IABlock.getInstruction() && !IABlock.hasCFT()) {
+ IABlock.advance();
+ }
+
+ IA_IAPI::allInsns_t::const_iterator localIter = IABlock.curInsnIter;
+ findTableBase(localIter, IABlock.allInsns.begin());
+ }
+ }
+ }
+
+ const Block::edgelist & sourceEdges = currBlk->sources();
+ if(sourceEdges.size() != 1 || (*sourceEdges.begin())->type() == CALL) {
+ parsing_printf("%s[%d]: jump table not properly guarded, ret false\n", FILE__, __LINE__);
+ return false;
+ }
+
+
+
+ // We could also set this = jumpStartAddress...
+ if (tableStartAddress == 0) {
+ parsing_printf("%s[%d]: couldn't find table start addr, ret false\n", FILE__, __LINE__);
+ return false;
+
+ }
+
+ parsing_printf("%s[%d]: table start addr is 0x%x\n", FILE__, __LINE__, tableStartAddress);
+ int maxSwitch = 0;
+
+ Block* sourceBlock = (*sourceEdges.begin())->src();
+ Address blockStart = sourceBlock->start();
+ const unsigned char* b = (const unsigned char*)(currentBlock->_isrc->getPtrToInstruction(blockStart));
+ InstructionDecoder dec(b, sourceBlock->size(), currentBlock->_isrc->getArch());
+ IA_IAPI prevBlock(dec, blockStart,currentBlock->_obj,currentBlock->_cr,currentBlock->_isrc, sourceBlock);
+ while(!prevBlock.hasCFT() && prevBlock.getInstruction()) {
+ prevBlock.advance();
+ }
+
+ parsing_printf("%s[%d]: checking for max switch...\n", FILE__, __LINE__);
+ bool foundBranch = false;
+ IA_IAPI::allInsns_t::reverse_iterator iter;
+ for(iter = prevBlock.allInsns.rbegin(); iter != prevBlock.allInsns.rend(); iter++)
{
- parsing_printf("\t\tchecking insn 0x%x: %s for cond branch + compare\n", iter->first,
- iter->second->format().c_str());
- if(iter->second->getOperation().getID() == power_op_bc) // make this a true cond. branch check
+ parsing_printf("\t\tchecking insn 0x%x: %s for cond branch + compare\n", iter->first,
+ iter->second->format().c_str());
+ if(iter->second->getOperation().getID() == power_op_bc) // make this a true cond. branch check
{
- foundBranch = true;
- } else if(foundBranch &&
- (iter->second->getOperation().getID() == power_op_cmpi ||
+ foundBranch = true;
+ } else if(foundBranch &&
+ (iter->second->getOperation().getID() == power_op_cmpi ||
iter->second->getOperation().getID() == power_op_cmpli))
{
- maxSwitch = iter->second->getOperand(2).getValue()->eval().convert() + 1;
- break;
-
+ maxSwitch = iter->second->getOperand(2).getValue()->eval().convert() + 1;
+ break;
+
}
- }
+ }
- parsing_printf("%s[%d]: After checking: max switch %d\n", FILE__, __LINE__, maxSwitch);
- if(!maxSwitch){
- return false;
- }
+ parsing_printf("%s[%d]: After checking: max switch %d\n", FILE__, __LINE__, maxSwitch);
+ if(!maxSwitch){
+ return false;
+ }
- Address jumpStart = 0;
- Address tableStart = 0;
- bool is64 = (currentBlock->_isrc->getAddressWidth() == 8);
- std::vector > edges;
+ Address jumpStart = 0;
+ Address tableStart = 0;
+ bool is64 = (currentBlock->_isrc->getAddressWidth() == 8);
+ std::vector > edges;
- if(TOC_address)
+ if(TOC_address)
{
- if (tableIsRelative) {
- void *jumpStartPtr = currentBlock->_isrc->getPtrToData(jumpStartAddress);
- parsing_printf("%s[%d]: jumpStartPtr (0x%lx) = %p\n", FILE__, __LINE__, jumpStartAddress, jumpStartPtr);
- if (jumpStartPtr)
- jumpStart = (is64
- ? *((Address *)jumpStartPtr)
- : *((uint32_t *)jumpStartPtr));
- parsing_printf("%s[%d]: jumpStart 0x%lx, initialAddr 0x%lx\n",
- FILE__, __LINE__, jumpStart, initialAddress);
- if (jumpStartPtr == NULL) {
- return false;
- }
- }
- void *tableStartPtr = currentBlock->_isrc->getPtrToData(tableStartAddress);
- parsing_printf("%s[%d]: tableStartPtr (0x%lx) = %p\n", FILE__, __LINE__, tableStartAddress, tableStartPtr);
- tableStart = *((Address *)tableStartPtr);
- if (tableStartPtr)
- tableStart = (is64
- ? *((Address *)tableStartPtr)
- : *((uint32_t *)tableStartPtr));
- else {
- return false;
- }
- parsing_printf("\t... tableStart 0x%lx\n", tableStart);
-
- bool tableData = false;
- for(int i=0;i_isrc->isValidAddress(tableEntry)) {
- int jumpOffset;
- if (tableData) {
- jumpOffset = *((int *)currentBlock->_isrc->getPtrToData(tableEntry));
- }
- else {
- jumpOffset = *((int *)currentBlock->_isrc->getPtrToInstruction(tableEntry));
- }
-
- parsing_printf("\t\t\tjumpOffset 0x%lx\n", jumpOffset);
- Address res = (Address)(jumpStart + jumpOffset);
-
- if (currentBlock->_isrc->isCode(res)) {
- edges.push_back(std::make_pair((Address)(jumpStart+jumpOffset), INDIRECT));
- parsing_printf("\t\t\tEntry of 0x%lx\n", (Address)(jumpStart + jumpOffset));
- }
- }
- else {
- parsing_printf("\t\tAddress not valid!\n");
- }
- }
+ if (tableIsRelative) {
+ void *jumpStartPtr = currentBlock->_isrc->getPtrToData(jumpStartAddress);
+ parsing_printf("%s[%d]: jumpStartPtr (0x%lx) = %p\n", FILE__, __LINE__, jumpStartAddress, jumpStartPtr);
+ if (jumpStartPtr)
+ jumpStart = (is64
+ ? *((Address *)jumpStartPtr)
+ : *((uint32_t *)jumpStartPtr));
+ parsing_printf("%s[%d]: jumpStart 0x%lx, initialAddr 0x%lx\n",
+ FILE__, __LINE__, jumpStart, initialAddress);
+ if (jumpStartPtr == NULL) {
+ return false;
+ }
+ }
+ void *tableStartPtr = currentBlock->_isrc->getPtrToData(tableStartAddress);
+ parsing_printf("%s[%d]: tableStartPtr (0x%lx) = %p\n", FILE__, __LINE__, tableStartAddress, tableStartPtr);
+ tableStart = *((Address *)tableStartPtr);
+ if (tableStartPtr)
+ tableStart = (is64
+ ? *((Address *)tableStartPtr)
+ : *((uint32_t *)tableStartPtr));
+ else {
+ return false;
+ }
+ parsing_printf("\t... tableStart 0x%lx\n", tableStart);
+
+ bool tableData = false;
+ for(int i=0;i_isrc->isValidAddress(tableEntry)) {
+ int jumpOffset;
+ if (tableData) {
+ jumpOffset = *((int *)currentBlock->_isrc->getPtrToData(tableEntry));
+ }
+ else {
+ jumpOffset = *((int *)currentBlock->_isrc->getPtrToInstruction(tableEntry));
+ }
+
+ parsing_printf("\t\t\tjumpOffset 0x%lx\n", jumpOffset);
+ Address res = (Address)(jumpStart + jumpOffset);
+
+ if (currentBlock->_isrc->isCode(res)) {
+ edges.push_back(std::make_pair((Address)(jumpStart+jumpOffset), INDIRECT));
+ parsing_printf("\t\t\tEntry of 0x%lx\n", (Address)(jumpStart + jumpOffset));
+ }
+ }
+ else {
+ parsing_printf("\t\tAddress not valid!\n");
+ }
+ }
}
- // No TOC, so we're on Power32 Linux. Do the ELF thing.
- else
+ // No TOC, so we're on Power32 Linux. Do the ELF thing.
+ else
{
- jumpStart = jumpStartAddress;
- tableStart = tableStartAddress;
- parsing_printf(" jumpStartaddress 0x%lx tableStartAddress 0x%lx \n", jumpStartAddress, tableStartAddress);
- if(toc_visitor->toc_contents)
+ jumpStart = jumpStartAddress;
+ tableStart = tableStartAddress;
+ parsing_printf(" jumpStartaddress 0x%lx tableStartAddress 0x%lx \n", jumpStartAddress, tableStartAddress);
+ if(toc_visitor->toc_contents)
{
- void* tmp = NULL;
- if(currentBlock->_isrc->isValidAddress(jumpStartAddress))
+ void* tmp = NULL;
+ if(currentBlock->_isrc->isValidAddress(jumpStartAddress))
{
- tmp = currentBlock->_isrc->getPtrToData(jumpStartAddress);
- if(!tmp)
+ tmp = currentBlock->_isrc->getPtrToData(jumpStartAddress);
+ if(!tmp)
{
- tmp = currentBlock->_isrc->getPtrToInstruction(jumpStartAddress);
+ tmp = currentBlock->_isrc->getPtrToInstruction(jumpStartAddress);
}
- if(tmp)
+ if(tmp)
{
- jumpStart = *((Address*)tmp);
- parsing_printf("\t\tjumpStart adjusted to 0x%lx\n", jumpStart);
+ jumpStart = *((Address*)tmp);
+ parsing_printf("\t\tjumpStart adjusted to 0x%lx\n", jumpStart);
}
}
- if(currentBlock->_isrc->isValidAddress(tableStartAddress))
+ if(currentBlock->_isrc->isValidAddress(tableStartAddress))
{
- tmp = currentBlock->_isrc->getPtrToData(tableStartAddress);
- if(!tmp)
+ tmp = currentBlock->_isrc->getPtrToData(tableStartAddress);
+ if(!tmp)
{
- tmp = currentBlock->_isrc->getPtrToInstruction(tableStartAddress);
+ tmp = currentBlock->_isrc->getPtrToInstruction(tableStartAddress);
}
- if(tmp)
+ if(tmp)
{
- tableStart = *((Address*)tmp);
- parsing_printf("\t\ttableStart adjusted to 0x%lx\n", jumpStart);
+ tableStart = *((Address*)tmp);
+ parsing_printf("\t\ttableStart adjusted to 0x%lx\n", jumpStart);
}
}
}
- if (jumpStart == 0) {
+ if (jumpStart == 0) {
#if defined(WITH_SYMTAB_API)
- // If jump table address is a relocation entry, this will be filled by the loader
- // This case is common in shared library where the table address is in the GOT section which is filled by the loader
- // Find the relocation entry for this address and look up its value
-
- Block* sourceBlock = (*sourceEdges.begin())->src();
- Address blockStart = sourceBlock->start();
- const unsigned char* b = (const unsigned char*)(currentBlock->_isrc->getPtrToInstruction(blockStart));
- InstructionDecoder dec(b, sourceBlock->size(), currentBlock->_isrc->getArch());
- IA_IAPI IABlock(dec, blockStart,currentBlock->_obj,currentBlock->_cr,currentBlock->_isrc, sourceBlock);
-
- SymtabCodeSource *scs = dynamic_cast(IABlock._obj->cs());
- SymtabAPI::Symtab * symtab = scs->getSymtabObject();
- std::vector regions;
- symtab->getAllRegions(regions);
- for (unsigned index = 0 ; index < regions.size(); index++) {
- if (regions[index]->getRegionType() == SymtabAPI::Region::RT_RELA ||
- regions[index]->getRegionType() == SymtabAPI::Region::RT_REL) {
- std::vector relocs =
- regions[index]->getRelocations();
- parsing_printf(" \t\trelocation size %d looking for 0x%lx\n", relocs.size(), jumpStartAddress);
- for (unsigned i = 0; i < relocs.size(); ++i) {
- parsing_printf(" \t 0x%lx => 0x%lx addend 0x%lx \n", relocs[i].rel_addr(),relocs[i].target_addr(), relocs[i].addend());
- if (relocs[i].rel_addr() == jumpStartAddress) {
- jumpStart = relocs[i].addend();
- break;
- }
- }
- break;
- }
- }
+ // If jump table address is a relocation entry, this will be filled by the loader
+ // This case is common in shared library where the table address is in the GOT section which is filled by the loader
+ // Find the relocation entry for this address and look up its value
+
+ Block* sourceBlock = (*sourceEdges.begin())->src();
+ Address blockStart = sourceBlock->start();
+ const unsigned char* b = (const unsigned char*)(currentBlock->_isrc->getPtrToInstruction(blockStart));
+ InstructionDecoder dec(b, sourceBlock->size(), currentBlock->_isrc->getArch());
+ IA_IAPI IABlock(dec, blockStart,currentBlock->_obj,currentBlock->_cr,currentBlock->_isrc, sourceBlock);
+
+ SymtabCodeSource *scs = dynamic_cast(IABlock._obj->cs());
+ SymtabAPI::Symtab * symtab = scs->getSymtabObject();
+ std::vector regions;
+ symtab->getAllRegions(regions);
+ for (unsigned index = 0 ; index < regions.size(); index++) {
+ if (regions[index]->getRegionType() == SymtabAPI::Region::RT_RELA ||
+ regions[index]->getRegionType() == SymtabAPI::Region::RT_REL) {
+ std::vector relocs =
+ regions[index]->getRelocations();
+ parsing_printf(" \t\trelocation size %d looking for 0x%lx\n", relocs.size(), jumpStartAddress);
+ for (unsigned i = 0; i < relocs.size(); ++i) {
+ parsing_printf(" \t 0x%lx => 0x%lx addend 0x%lx \n", relocs[i].rel_addr(),relocs[i].target_addr(), relocs[i].addend());
+ if (relocs[i].rel_addr() == jumpStartAddress) {
+ jumpStart = relocs[i].addend();
+ break;
+ }
+ }
+ break;
+ }
+ }
#else
- // Can't parse relocation entries without Symtab
+ // Can't parse relocation entries without Symtab
return false;
#endif
- }
- if (tableStart == 0) tableStart = jumpStart;
+ }
+ if (tableStart == 0) tableStart = jumpStart;
- if (!tableIsRelative) {
- jumpStart = 0;
- }
- parsing_printf(" jumpStartaddress 0x%lx tableStartAddress 0x%lx \n", jumpStart, tableStart);
+ if (!tableIsRelative) {
+ jumpStart = 0;
+ }
+ parsing_printf(" jumpStartaddress 0x%lx tableStartAddress 0x%lx \n", jumpStart, tableStart);
- int entriesAdded = 0;
- for(int i = 0; i < maxSwitch; i++)
+ int entriesAdded = 0;
+ for(int i = 0; i < maxSwitch; i++)
{
- void* ptr = NULL;
- Address tableEntry = tableStart + i*4; // instruction::size();
- if(currentBlock->_isrc->isValidAddress(tableEntry))
+ void* ptr = NULL;
+ Address tableEntry = tableStart + i*4; // instruction::size();
+ if(currentBlock->_isrc->isValidAddress(tableEntry))
{
- ptr = currentBlock->_isrc->getPtrToInstruction(tableEntry);
+ ptr = currentBlock->_isrc->getPtrToInstruction(tableEntry);
}
- if(ptr)
+ if(ptr)
{
- int jumpOffset = *((int *)ptr);
- edges.push_back(std::make_pair((Address)(jumpStart+jumpOffset), INDIRECT));
- parsing_printf("\t\t\t[0x%lx] -> 0x%lx (0x%lx in table)\n", tableEntry,
- jumpStart+jumpOffset,
- jumpOffset);
- ++entriesAdded;
+ int jumpOffset = *((int *)ptr);
+ edges.push_back(std::make_pair((Address)(jumpStart+jumpOffset), INDIRECT));
+ parsing_printf("\t\t\t[0x%lx] -> 0x%lx (0x%lx in table)\n", tableEntry,
+ jumpStart+jumpOffset,
+ jumpOffset);
+ ++entriesAdded;
}
- else
+ else
{
- parsing_printf("\t\t\t[0x%lx] -> [INVALID]\n", tableEntry);
+ parsing_printf("\t\t\t[0x%lx] -> [INVALID]\n", tableEntry);
}
}
- if(!entriesAdded)
+ if(!entriesAdded)
{
- parsing_printf("%s[%d]: no entries added from jump table, returning false\n", FILE__, __LINE__);
- return false;
+ parsing_printf("%s[%d]: no entries added from jump table, returning false\n", FILE__, __LINE__);
+ return false;
}
- parsing_printf("%s[%d]: Found %d entries in jump table, returning success\n", FILE__, __LINE__, entriesAdded);
+ parsing_printf("%s[%d]: Found %d entries in jump table, returning success\n", FILE__, __LINE__, entriesAdded);
}
- // Sanity check entries in res
- for (std::vector >::iterator iter = edges.begin();
- iter != edges.end(); iter++) {
- if ((iter->first) % 4) {
- parsing_printf("Warning: found unaligned jump table destination 0x%lx for jump at 0x%lx, disregarding table\n",
- iter->first, initialAddress);
- return false;
+ // Sanity check entries in res
+ for (std::vector >::iterator iter = edges.begin();
+ iter != edges.end(); iter++) {
+ if ((iter->first) % 4) {
+ parsing_printf("Warning: found unaligned jump table destination 0x%lx for jump at 0x%lx, disregarding table\n",
+ iter->first, initialAddress);
+ return false;
+ }
+ }
+ // If we have found a jump table, add the targets to outEdges
+ for (std::vector >::iterator iter = edges.begin();
+ iter != edges.end(); iter++) {
+ parsing_printf("Adding out edge %d/0x%lx\n", iter->second, iter->first);
+ outEdges.push_back(*iter);
}
- }
- // If we have found a jump table, add the targets to outEdges
- for (std::vector >::iterator iter = edges.begin();
- iter != edges.end(); iter++) {
- parsing_printf("Adding out edge %d/0x%lx\n", iter->second, iter->first);
- outEdges.push_back(*iter);
- }
- return true;
+ return true;
}
diff --git a/symtabAPI/src/Object-elf.C b/symtabAPI/src/Object-elf.C
index d7a2a89230..90a6f9de64 100644
--- a/symtabAPI/src/Object-elf.C
+++ b/symtabAPI/src/Object-elf.C
@@ -2543,8 +2543,8 @@ bool Object::fix_global_symbol_modules_static_dwarf()
}
}
- cout << "Adding range [" << hex << low << ", " << high << ") to " << dec <<
- m->fileName() << " based on statements" << endl;
+// cout << "Adding range [" << hex << low << ", " << high << ") to " << dec <<
+// m->fileName() << " based on statements" << endl;
m->addRange(low, high);
}
}
@@ -4311,17 +4311,17 @@ void Object::parseStabFileLineInfo()
// haveParsedFileMap[ key ] = true;
} /* end parseStabFileLineInfo() */
+struct open_statement {
+ Dwarf_Unsigned string_table_index;
+ Dwarf_Addr start_addr;
+ Dwarf_Addr end_addr;
+ Dwarf_Unsigned line_number;
+ Dwarf_Signed column_number;
+};
void Object::parseLineInfoForCU(Dwarf_Die cuDIE, LineInformation* li_for_module)
{
- struct open_statement {
- Dwarf_Unsigned string_table_index;
- Dwarf_Addr start_addr;
- Dwarf_Addr end_addr;
- Dwarf_Unsigned line_number;
- Dwarf_Signed column_number;
- };
std::vector open_statements;
Dwarf_Debug *dbg_ptr = dwarf->line_dbg();
if (!dbg_ptr)
diff --git a/symtabAPI/src/dwarfWalker.C b/symtabAPI/src/dwarfWalker.C
index 2f26b6e6af..58165b32ee 100644
--- a/symtabAPI/src/dwarfWalker.C
+++ b/symtabAPI/src/dwarfWalker.C
@@ -1628,15 +1628,16 @@ bool DwarfWalker::getLineInformation(Dwarf_Unsigned &variableLineNo,
fileName = "";
}
else if (status == DW_DLV_OK) {
+ StringTablePtr files = srcFiles();
Dwarf_Unsigned fileNameDeclVal;
DWARF_FAIL_RET(dwarf_formudata(fileDeclAttribute, &fileNameDeclVal, NULL));
dwarf_dealloc( dbg(), fileDeclAttribute, DW_DLA_ATTR );
- if (fileNameDeclVal > srcFiles()->size() || fileNameDeclVal <= 0) {
+ if (fileNameDeclVal >= files->size() || fileNameDeclVal <= 0) {
dwarf_printf("Dwarf error reading line index %d from srcFiles of size %lu\n",
- fileNameDeclVal, srcFiles()->size());
+ fileNameDeclVal, files->size());
return false;
}
- fileName = (*srcFiles())[fileNameDeclVal].str;
+ fileName = ((files->get<0>())[fileNameDeclVal]).str;
}
else {
return true;