bool BPatch_binaryEdit::writeFile(const char * outFile) { assert(pendingInsertions); // This should be a parameter... //bool atomic = false; // Define up here so we don't have gotos causing issues std::set<func_instance *> instrumentedFunctions; // Two loops: first addInst, then generate/install/link pdvector<miniTramp *> workDone; //bool err = false; // Iterate over our AddressSpaces, triggering relocation // in each one. std::vector<AddressSpace *> as; getAS(as); bool ret = true; /* PatchAPI stuffs */ if (as.size() > 0) { ret = AddressSpace::patch(as[0]); } /* end of PatchAPI stuffs */ // Now that we've instrumented we can see if we need to replace the // trap handler. replaceTrapHandler(); for(std::map<std::string, BinaryEdit*>::iterator i = llBinEdits.begin(); i != llBinEdits.end(); i++) { (*i).second->trapMapping.flush(); } if( !origBinEdit->writeFile(outFile) ) return false; std::map<std::string, BinaryEdit *>::iterator curBinEdit; for (curBinEdit = llBinEdits.begin(); curBinEdit != llBinEdits.end(); curBinEdit++) { BinaryEdit *bin = (*curBinEdit).second; if (bin == origBinEdit) continue; if (!bin->isDirty()) continue; std::string newname = bin->getMappedObject()->fileName(); if( !bin->writeFile(newname) ) return false; } return ret; }
bool BPatch_binaryEdit::replaceTrapHandler() { // Did we use a trap? bool usedATrap = false; std::map<std::string, BinaryEdit *>::iterator iter = llBinEdits.begin(); for (; iter != llBinEdits.end(); iter++) { if (iter->second->usedATrap()) { usedATrap = true; break; } } if (!usedATrap) return true; // We used a trap, so go through and set up the replacement instrumentation. // However, don't let this be the first piece of instrumentation put into // a library. bool success = true; iter = llBinEdits.begin(); for (; iter != llBinEdits.end(); iter++) { BinaryEdit *binEd = iter->second; // Did we instrument this already? if (!binEd->isDirty()) { continue; } // Okay, replace trap handler if (!binEd->replaceTrapHandler()) { success = false; } } return success; }