Process::cb_ret_t Backend::handleLibraryEvent(ProcControlAPI::Event::const_ptr ev) { vector<Probe*> roots = ProbeTree::getPendingRoots(); EventLibrary::const_ptr evLib = ev->getEventLibrary(); set<Library::ptr>::iterator iter; string msg; msg = "libs added: "; for (iter = evLib->libsAdded().begin(); iter != evLib->libsAdded().end(); iter++) { msg += (*iter)->getName() + ", "; } msg += "libs removed: "; for (iter = evLib->libsRemoved().begin(); iter != evLib->libsRemoved().end(); iter++) { msg += (*iter)->getName() + ", "; } DYSECTVERBOSE(true, "Library event captured, %d pending probes, %s", roots.size(), msg.c_str()); if(roots.size() > 0) prepareProbes(NULL, true); return Process::cbDefault; }
bool PCEventHandler::handleLibrary(EventLibrary::const_ptr ev, PCProcess *evProc) const { const fileDescriptor &execFd = evProc->getAOut()->getFileDesc(); if( ev->libsAdded().size() == 0 && ev->libsRemoved().size() == 0 ) { proccontrol_printf("%s[%d]: library event contains no changes to library state\n", FILE__, __LINE__); return true; } // Create new mapped objects for all the new loaded libraries const set<Library::ptr> &added = ev->libsAdded(); for(set<Library::ptr>::const_iterator i = added.begin(); i != added.end(); ++i) { Address dataAddress = (*i)->getLoadAddress(); if( evProc->usesDataLoadAddress() ) dataAddress = (*i)->getDataLoadAddress(); fileDescriptor tmpDesc((*i)->getAbsoluteName(), (*i)->getLoadAddress(), dataAddress, true); if( execFd == tmpDesc ) { proccontrol_printf("%s[%d]: ignoring Library event for executable %s\n", FILE__, __LINE__, (*i)->getAbsoluteName().c_str()); continue; } mapped_object *newObj = mapped_object::createMappedObject(tmpDesc, evProc, evProc->getHybridMode()); if( newObj == NULL ) { proccontrol_printf("%s[%d]: failed to create mapped object for library %s\n", FILE__, __LINE__, (*i)->getAbsoluteName().c_str()); return false; } proccontrol_printf("%s[%d]: new mapped object: %s\n", FILE__, __LINE__, newObj->debugString().c_str()); evProc->addASharedObject(newObj); // TODO special handling for libc on Linux (breakpoint at __libc_start_main if cannot find main) // special handling for the RT library dataAddress = (*i)->getLoadAddress(); if( evProc->usesDataLoadAddress() ) dataAddress = (*i)->getDataLoadAddress(); fileDescriptor rtLibDesc(evProc->dyninstRT_name, (*i)->getLoadAddress(), dataAddress, true); if( rtLibDesc == tmpDesc ) { proccontrol_printf("%s[%d]: library event contains RT library load\n", FILE__, __LINE__); // In the dynamic case, we can only work with dynamic binaries at // this point and thus the RT library is a shared library, so the // runtime_lib structure should be empty if (evProc->runtime_lib.size() == 0) evProc->runtime_lib.insert(newObj); // Don't register the runtime library with the BPatch layer } else { assert(tmpDesc.file() != rtLibDesc.file()); BPatch::bpatch->registerLoadedModule(evProc, newObj); } } // Create descriptors for all the deleted objects and find the corresponding // mapped objects using these descriptors vector<fileDescriptor> deletedDescriptors; const set<Library::ptr> &deleted = ev->libsRemoved(); for(set<Library::ptr>::const_iterator i = deleted.begin(); i != deleted.end(); ++i) { Address dataAddress = (*i)->getLoadAddress(); if( evProc->usesDataLoadAddress() ) dataAddress = (*i)->getDataLoadAddress(); deletedDescriptors.push_back(fileDescriptor((*i)->getAbsoluteName(), (*i)->getLoadAddress(), dataAddress, true)); } const pdvector<mapped_object *> &currList = evProc->mappedObjects(); pdvector<mapped_object *> toDelete; for(unsigned i = 0; i < currList.size(); ++i) { for(unsigned j = 0; j < deletedDescriptors.size(); ++j) { if( deletedDescriptors[j] == currList[i]->getFileDesc() ) { toDelete.push_back(currList[i]); } } } // Register the deletion with the BPatch layer before removing the modules // from the address space for(unsigned i = 0; i < toDelete.size(); ++i) { proccontrol_printf("%s[%d]: removed map object: %s\n", FILE__, __LINE__, toDelete[i]->debugString().c_str()); BPatch::bpatch->registerUnloadedModule(evProc, toDelete[i]); evProc->removeASharedObject(toDelete[i]); } // A thread library may have been loaded -- mt_cache state needs to be re-evaluated evProc->invalidateMTCache(); return true; }
Process::cb_ret_t on_library(Event::const_ptr ev) { EventLibrary::const_ptr evlib = ev->getEventLibrary(); if (!evlib) { logerror("error, received non library event\n"); myerror = true; return Process::cbDefault; } proc_info_lib &pi = proclibs[ev->getProcess()]; const LibraryPool& libpool = ev->getProcess()->libraries(); std::set<Library::ptr>::const_iterator i; for (i = evlib->libsAdded().begin(); i != evlib->libsAdded().end(); i++) { Library::ptr lib = *i; // FIXME //cerr << hex << "Callback library " << lib << dec << endl; if (lib->getName().find("testA") != string::npos) { pi.loaded_libtesta = pi.order++; } if (lib->getName().find("testB") != string::npos) { pi.loaded_libtestb = pi.order++; } bool found_lib = false; find_by_pointer F = find_by_pointer(lib); for(LibraryPool::const_iterator i = libpool.begin(); i != libpool.end(); ++i) { F(*i); } found_lib = F.found_it; if (!found_lib) { logerror("New library was not in library list\n"); myerror = true; } } for (i = evlib->libsRemoved().begin(); i != evlib->libsRemoved().end(); i++) { Library::ptr lib = *i; // Reduce these to "testA/testB" because Windows standard is for DLLs not to be "lib" prefixed if (lib->getName().find("testA") != string::npos) { pi.unloaded_libtesta = pi.order++; } if (lib->getName().find("testB") != string::npos) { pi.unloaded_libtestb = pi.order++; } find_by_pointer f(lib); for(LibraryPool::const_iterator i = libpool.begin(); i != libpool.end(); ++i) { f(*i); } if(f.found_it) { logerror("Removed library was still in library list\n"); myerror = true; } /* for (LibraryPool::const_iterator j = libpool.begin(); j != libpool.end(); j++) { if (*j == lib) { logerror("Removed library was still in library list\n"); myerror = true; } } */ } return Process::cbDefault; }