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; }
BPatch_variableExpr *BPatch_addressSpace::createVariable( Dyninst::Address at_addr, BPatch_type *type, std::string var_name, BPatch_module *in_module) { BPatch_binaryEdit *binEdit = dynamic_cast<BPatch_binaryEdit *>(this); if (binEdit && !in_module) { //Address alone isn't unique when binary rewriting return NULL; } if (!type) { //Required for size information. return NULL; } AddressSpace *ll_addressSpace = NULL; std::vector<AddressSpace *> as; getAS(as); if (binEdit) { std::vector<AddressSpace *>::iterator as_i; for (as_i = as.begin(); as_i != as.end(); as_i++) { BinaryEdit *b = dynamic_cast<BinaryEdit *>(*as_i); assert(b); if (in_module->mod->obj() == b->getMappedObject()) { ll_addressSpace = *as_i; break; } } } else { assert(as.size() == 1); ll_addressSpace = as[0]; } if (!ll_addressSpace) { //in_module doesn't belong to 'this' return NULL; } if (!var_name.size()) { std::stringstream namestream; namestream << "dyninst_var_" << std::hex << at_addr; var_name = namestream.str(); } return BPatch_variableExpr::makeVariableExpr(this, ll_addressSpace, var_name, (void *) at_addr, type); }
mapped_object *BinaryEdit::openResolvedLibraryName(std::string filename, std::map<std::string, BinaryEdit *> &allOpened) { /* * Note: this does not actually do any library name resolution, as that is OS-dependent * If resolution is required, it should be implemented in an OS-dependent file * (see linux.C for an example) * * However, this version allows the RT library to be opened with this function regardless * if library name resolution has been implemented on a platform. */ std::map<std::string, BinaryEdit *> retMap; assert(mgr()); BinaryEdit *temp = BinaryEdit::openFile(filename, mgr(), patcher()); if( temp && temp->getAddressWidth() == getAddressWidth() ) { allOpened.insert(std::make_pair(filename, temp)); return temp->getMappedObject(); } return NULL; }
mapped_object *BinaryEdit::openResolvedLibraryName(std::string filename, std::map<std::string, BinaryEdit*> &retMap) { std::vector<std::string> paths; std::vector<std::string>::iterator pathIter; // First, find the specified library file bool resolved = getResolvedLibraryPath(filename, paths); // Second, create a set of BinaryEdits for the found library if ( resolved ) { startup_printf("[%s:%u] - Opening dependent file %s\n", FILE__, __LINE__, filename.c_str()); Symtab *origSymtab = getMappedObject()->parse_img()->getObject(); assert(mgr()); // Dynamic case if ( !origSymtab->isStaticBinary() ) { for(pathIter = paths.begin(); pathIter != paths.end(); ++pathIter) { BinaryEdit *temp = BinaryEdit::openFile(*pathIter, mgr(), patcher()); if (temp && temp->getAddressWidth() == getAddressWidth()) { retMap.insert(std::make_pair(*pathIter, temp)); return temp->getMappedObject(); } delete temp; } } else { // Static executable case /* * Alright, this is a kludge, but even though the Archive is opened * twice (once here and once by the image class later on), it is * only parsed once because the Archive class keeps track of all * open Archives. * * This is partly due to the fact that Archives are collections of * Symtab objects and their is one Symtab for each BinaryEdit. In * some sense, an Archive is a collection of BinaryEdits. */ for(pathIter = paths.begin(); pathIter != paths.end(); ++pathIter) { Archive *library; Symtab *singleObject; if (Archive::openArchive(library, *pathIter)) { std::vector<Symtab *> members; if (library->getAllMembers(members)) { std::vector <Symtab *>::iterator member_it; for (member_it = members.begin(); member_it != members.end(); ++member_it) { BinaryEdit *temp = BinaryEdit::openFile(*pathIter, mgr(), patcher(), (*member_it)->memberName()); if (temp && temp->getAddressWidth() == getAddressWidth()) { std::string mapName = *pathIter + string(":") + (*member_it)->memberName(); retMap.insert(std::make_pair(mapName, temp)); }else{ if(temp) delete temp; retMap.clear(); break; } } if (retMap.size() > 0) { origSymtab->addLinkingResource(library); // So we tried loading "libc.a", and got back a swarm of individual members. // Lovely. // Just return the first thing... return retMap.begin()->second->getMappedObject(); } //if( library ) delete library; } } else if (Symtab::openFile(singleObject, *pathIter)) { BinaryEdit *temp = BinaryEdit::openFile(*pathIter, mgr(), patcher()); if (temp && temp->getAddressWidth() == getAddressWidth()) { if( singleObject->getObjectType() == obj_SharedLib || singleObject->getObjectType() == obj_Executable ) { startup_printf("%s[%d]: cannot load dynamic object(%s) when rewriting a static binary\n", FILE__, __LINE__, pathIter->c_str()); std::string msg = std::string("Cannot load a dynamic object when rewriting a static binary"); showErrorCallback(71, msg.c_str()); delete singleObject; }else{ retMap.insert(std::make_pair(*pathIter, temp)); return temp->getMappedObject(); } } if(temp) delete temp; } } } } startup_printf("[%s:%u] - Creation error opening %s\n", FILE__, __LINE__, filename.c_str()); // If the only thing we could find was a dynamic lib for a static executable, we can reach here; caller should handle this. return NULL; }