diff --git a/dyninstAPI/CMakeLists.txt b/dyninstAPI/CMakeLists.txt index 58bf0f82e1..12f602bd63 100644 --- a/dyninstAPI/CMakeLists.txt +++ b/dyninstAPI/CMakeLists.txt @@ -192,7 +192,7 @@ set (SRC_LIST ${SRC_LIST} src/cpuid-x86.S) set_source_files_properties(src/cpuid-x86.S PROPERTIES LANGUAGE C) endif () -dyninst_library(dyninstAPI common instructionAPI stackwalk pcontrol patchAPI parseAPI symtabAPI) +dyninst_library(dyninstAPI common instructionAPI stackwalk pcontrol patchAPI parseAPI symtabAPI symLite) target_link_private_libraries(dyninstAPI ${Boost_LIBRARIES}) if (UNIX) diff --git a/dyninstAPI/src/BPatch.C b/dyninstAPI/src/BPatch.C index f12e521d6f..00568c62e8 100644 --- a/dyninstAPI/src/BPatch.C +++ b/dyninstAPI/src/BPatch.C @@ -51,6 +51,7 @@ #include "instPoint.h" #include "hybridAnalysis.h" #include "BPatch_object.h" +#include "os.h" // ProcControlAPI interface #include "dynProcess.h" diff --git a/dyninstAPI/src/BPatch_binaryEdit.C b/dyninstAPI/src/BPatch_binaryEdit.C index f45a95eb89..85822463b0 100644 --- a/dyninstAPI/src/BPatch_binaryEdit.C +++ b/dyninstAPI/src/BPatch_binaryEdit.C @@ -185,7 +185,7 @@ BPatch_binaryEdit::~BPatch_binaryEdit() delete (*i).second; } llBinEdits.clear(); - origBinEdit = NULL; + assert(BPatch::bpatch != NULL); } diff --git a/dyninstAPI/src/BPatch_object.C b/dyninstAPI/src/BPatch_object.C index ca413bc04b..f75733cfda 100644 --- a/dyninstAPI/src/BPatch_object.C +++ b/dyninstAPI/src/BPatch_object.C @@ -183,7 +183,7 @@ std::string BPatch_object::Region::format() { Dyninst::ParseAPI::CodeObject *Dyninst::ParseAPI::convert(const BPatch_object *o) { if (!o->obj) return NULL; - return o->obj->parse_img()->codeObject(); + return o->obj->parse_img()->codeObject().get(); } Dyninst::PatchAPI::PatchObject *Dyninst::PatchAPI::convert(const BPatch_object *o) { diff --git a/dyninstAPI/src/Parsing.h b/dyninstAPI/src/Parsing.h index 1bec5b1061..4c48584f7c 100644 --- a/dyninstAPI/src/Parsing.h +++ b/dyninstAPI/src/Parsing.h @@ -54,7 +54,7 @@ namespace ParseAPI { class DynCFGFactory : public Dyninst::ParseAPI::CFGFactory { public: DynCFGFactory(image * im); - ~DynCFGFactory() {}; + virtual ~DynCFGFactory() {}; ParseAPI::Function * mkfunc(Address addr, FuncSource src, std::string name, ParseAPI::CodeObject * obj, ParseAPI::CodeRegion * reg, diff --git a/dyninstAPI/src/Relocation/DynCFGMaker.C b/dyninstAPI/src/Relocation/DynCFGMaker.C index 12e9cfb443..b639db7976 100644 --- a/dyninstAPI/src/Relocation/DynCFGMaker.C +++ b/dyninstAPI/src/Relocation/DynCFGMaker.C @@ -94,13 +94,13 @@ PatchEdge* DynCFGMaker::makeEdge(ParseAPI::Edge* e, mapped_object* moS = NULL; mapped_object* moT = NULL; if (!s) { - if (e->src()->obj() == o->co()) + if (e->src()->obj() == o->co().get()) moS = SCAST_MO(o); else moS = SCAST_MO(o)->as()->findObject(e->src()->obj()); } if (!t) { - if (e->trg()->obj() == o->co()) + if (e->trg()->obj() == o->co().get()) moT = SCAST_MO(o); else moT = SCAST_MO(o)->as()->findObject(e->trg()->obj()); diff --git a/dyninstAPI/src/Relocation/DynObject.C b/dyninstAPI/src/Relocation/DynObject.C index 395ffd34fe..6a92fca23d 100644 --- a/dyninstAPI/src/Relocation/DynObject.C +++ b/dyninstAPI/src/Relocation/DynObject.C @@ -41,7 +41,7 @@ using Dyninst::PatchAPI::InstancePtr; using Dyninst::PatchAPI::DynCFGMakerPtr; using Dyninst::PatchAPI::DynCFGMaker; -DynObject::DynObject(ParseAPI::CodeObject* co, AddressSpace* as, Address base) +DynObject::DynObject(boost::shared_ptr co, AddressSpace* as, Address base) : PatchObject(co, base, new DynCFGMaker, new DynPatchCallback), diff --git a/dyninstAPI/src/Relocation/DynObject.h b/dyninstAPI/src/Relocation/DynObject.h index d6bfc2c1a9..c7eb825767 100644 --- a/dyninstAPI/src/Relocation/DynObject.h +++ b/dyninstAPI/src/Relocation/DynObject.h @@ -42,12 +42,12 @@ namespace PatchAPI { class DynObject : public PatchObject { public: - static DynObject* create(ParseAPI::CodeObject* co, + static DynObject* create(boost::shared_ptr co, AddressSpace* as, Address base) { return (new DynObject(co, as, base)); } - DynObject(ParseAPI::CodeObject* co, AddressSpace* as, Address base); + DynObject(boost::shared_ptr co, AddressSpace* as, Address base); DynObject(const DynObject *par_obj, AddressSpace* child, Address base); ~DynObject(); diff --git a/dyninstAPI/src/addressSpace.C b/dyninstAPI/src/addressSpace.C index d87cda3835..2f91ad3b3d 100644 --- a/dyninstAPI/src/addressSpace.C +++ b/dyninstAPI/src/addressSpace.C @@ -28,6 +28,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "os.h" + + #include "addressSpace.h" #include "codeRange.h" #include "dynProcess.h" @@ -63,6 +66,10 @@ #include +#include "dynThread.h" +#include "pcEventHandler.h" + + // Implementations of non-virtual functions in the address space // class. @@ -88,8 +95,7 @@ AddressSpace::AddressSpace () : memEmulator_(NULL), emulateMem_(false), emulatePC_(false), - delayRelocation_(false), - patcher_(NULL) + delayRelocation_(false) { #if 0 // Disabled for now; used by defensive mode @@ -103,10 +109,8 @@ AddressSpace::AddressSpace () : } AddressSpace::~AddressSpace() { - if (memEmulator_) - delete memEmulator_; - if (mgr_) - static_cast(mgr_->as())->removeAddrSpace(this); + cerr << "Destroying AddressSpace " << hex << this << dec << " for " << getAOut()->fileName() << endl; + deleteAddressSpace(); } PCProcess *AddressSpace::proc() { @@ -252,7 +256,6 @@ void AddressSpace::deleteAddressSpace() { // bool heapInitialized_ // inferiorHeap heap_ - heapInitialized_ = false; heap_.clear(); for (unsigned i = 0; i < mapped_objects.size(); i++) @@ -877,7 +880,7 @@ mapped_object *AddressSpace::findObject(Address addr) const { mapped_object *AddressSpace::findObject(const ParseAPI::CodeObject *co) const { mapped_object *obj = - findObject(static_cast(co->cs())-> + findObject(static_cast(co->cs().get())-> getSymtabObject()->file()); return obj; } @@ -2321,3 +2324,12 @@ bool uninstrument(Dyninst::PatchAPI::Instance::Ptr inst) { return true; } + + +unsigned AddressSpace::getAddressWidth() const { + if( mapped_objects.size() > 0 ) { + return mapped_objects[0]->parse_img()->codeObject()->cs()->getAddressWidth(); + } + // We can call this before we've attached...best effort guess + return sizeof(Address); +} \ No newline at end of file diff --git a/dyninstAPI/src/addressSpace.h b/dyninstAPI/src/addressSpace.h index 5c63ce980f..353951c916 100644 --- a/dyninstAPI/src/addressSpace.h +++ b/dyninstAPI/src/addressSpace.h @@ -192,7 +192,7 @@ class AddressSpace : public InstructionSource { virtual bool isValidAddress(const Address) const; virtual void *getPtrToInstruction(const Address) const; virtual void *getPtrToData(const Address a) const { return getPtrToInstruction(a); } - virtual unsigned getAddressWidth() const = 0; + bool usesDataLoadAddress() const; // OS-specific virtual bool isCode(const Address) const; virtual bool isData(const Address) const; @@ -373,7 +373,11 @@ class AddressSpace : public InstructionSource { ////////////////////////////////////////////////////// // Callbacks for higher level code (like BPatch) to learn about new // functions and InstPoints. - private: + /* AddressSpace pure virtual implementation */ + unsigned getAddressWidth() const; + + +private: BPatch_function *(*new_func_cb)(AddressSpace *a, Dyninst::PatchAPI::PatchFunction *f); BPatch_point *(*new_instp_cb)(AddressSpace *a, Dyninst::PatchAPI::PatchFunction *f, Dyninst::PatchAPI::Point *ip, @@ -565,14 +569,14 @@ class AddressSpace : public InstructionSource { public: Dyninst::PatchAPI::PatchMgrPtr mgr() const { assert(mgr_); return mgr_; } void setMgr(Dyninst::PatchAPI::PatchMgrPtr m) { mgr_ = m; } - void setPatcher(Dyninst::PatchAPI::Patcher* p) { patcher_ = p; } + void setPatcher(Dyninst::PatchAPI::Patcher::Ptr p) { patcher_ = p; } void initPatchAPI(); void addMappedObject(mapped_object* obj); - Dyninst::PatchAPI::Patcher* patcher() { return patcher_; } + Dyninst::PatchAPI::Patcher::Ptr patcher() { return patcher_; } static bool patch(AddressSpace*); protected: Dyninst::PatchAPI::PatchMgrPtr mgr_; - Dyninst::PatchAPI::Patcher* patcher_; + Dyninst::PatchAPI::Patcher::Ptr patcher_; }; diff --git a/dyninstAPI/src/binaryEdit.C b/dyninstAPI/src/binaryEdit.C index 2f634908ce..4119928b27 100644 --- a/dyninstAPI/src/binaryEdit.C +++ b/dyninstAPI/src/binaryEdit.C @@ -255,10 +255,6 @@ Architecture BinaryEdit::getArch() const { return mapped_objects[0]->parse_img()->codeObject()->cs()->getArch(); } -unsigned BinaryEdit::getAddressWidth() const { - assert(!mapped_objects.empty()); - return mapped_objects[0]->parse_img()->codeObject()->cs()->getAddressWidth(); -} Address BinaryEdit::offset() const { fprintf(stderr,"error BinaryEdit::offset() unimpl\n"); return 0; @@ -290,26 +286,27 @@ BinaryEdit::BinaryEdit() : BinaryEdit::~BinaryEdit() { -} - -void BinaryEdit::deleteBinaryEdit() { - deleteAddressSpace(); highWaterMark_ = 0; lowWaterMark_ = 0; - // TODO: is this cleanup necessary? - depRelocation *rel; - while (dependentRelocations.size() > 0) { - rel = dependentRelocations[0]; - dependentRelocations.erase(dependentRelocations.begin()); - delete rel; + for(auto i = dependentRelocations.begin(); + i != dependentRelocations.end(); + ++i) + { + delete (*i); + } + for (auto mt = trackerFreeList.begin(); + mt != trackerFreeList.end(); + ++mt) + { + delete (*mt); } delete memoryTracker_; } -BinaryEdit *BinaryEdit::openFile(const std::string &file, +BinaryEdit *BinaryEdit::openFile(const std::string &file, PatchMgrPtr mgr, - Dyninst::PatchAPI::Patcher *patch, + Dyninst::PatchAPI::Patcher::Ptr patch, const std::string &member) { if (!OS::executableExists(file)) { startup_printf("%s[%d]: failed to read file %s\n", FILE__, __LINE__, file.c_str()); @@ -762,13 +759,11 @@ bool BinaryEdit::createMemoryBackingStore(mapped_object *obj) { { continue; } - else { - newTracker = new memoryTracker(regs[i]->getMemOffset(), - regs[i]->getMemSize(), - regs[i]->getPtrToRawData()); - - } + newTracker = new memoryTracker(regs[i]->getMemOffset(), + regs[i]->getMemSize(), + regs[i]->getPtrToRawData()); newTracker->alloced = false; + trackerFreeList.push_back(newTracker); if (!memoryTracker_) memoryTracker_ = new codeRangeTree(); memoryTracker_->insert(newTracker); diff --git a/dyninstAPI/src/binaryEdit.h b/dyninstAPI/src/binaryEdit.h index fc6d06192c..39409914a3 100644 --- a/dyninstAPI/src/binaryEdit.h +++ b/dyninstAPI/src/binaryEdit.h @@ -100,8 +100,6 @@ class BinaryEdit : public AddressSpace { virtual void inferiorFree(Address item); virtual bool inferiorRealloc(Address item, unsigned newSize); - /* AddressSpace pure virtual implementation */ - unsigned getAddressWidth() const; Address offset() const; Address length() const; Architecture getArch() const; @@ -138,13 +136,10 @@ class BinaryEdit : public AddressSpace { BinaryEdit(); ~BinaryEdit(); - // Same usage pattern as process - void deleteBinaryEdit(); - // And the "open" factory method. static BinaryEdit *openFile(const std::string &file, Dyninst::PatchAPI::PatchMgrPtr mgr = Dyninst::PatchAPI::PatchMgrPtr(), - Dyninst::PatchAPI::Patcher *patch = NULL, + Dyninst::PatchAPI::Patcher::Ptr patch = Dyninst::PatchAPI::Patcher::Ptr(), const std::string &member = ""); bool writeFile(const std::string &newFileName); @@ -191,7 +186,7 @@ class BinaryEdit : public AddressSpace { virtual void addTrap(Address from, Address to, codeGen &gen); virtual void removeTrap(Address /*from*/) {}; - static bool getResolvedLibraryPath(const std::string &filename, std::vector &paths); + static bool getResolvedLibraryPath(const std::string &filename, set &paths); private: Address highWaterMark_; @@ -218,7 +213,7 @@ class BinaryEdit : public AddressSpace { bool doStaticBinarySpecialCases(); codeRangeTree* memoryTracker_; - + std::vector trackerFreeList; mapped_object * addSharedObject(const std::string *fullPath); std::vector dependentRelocations; @@ -234,6 +229,7 @@ class BinaryEdit : public AddressSpace { // Symbols that other people (e.g., functions) want us to add std::vector newDyninstSyms_; + bool isCompatibleBinary(std::string pathname); }; @@ -252,16 +248,16 @@ class memoryTracker : public codeRange { public: memoryTracker(Address a, unsigned s) : alloced(false), dirty(false), a_(a), s_(s) { - b_ = malloc(s_); + b_ = calloc(s_, 1); } memoryTracker(Address a, unsigned s, void *b) : alloced(false), dirty(false), a_(a), s_(s) { - b_ = malloc(s_); + b_ = calloc(s_, 1); memcpy(b_, b, s_); } - ~memoryTracker() { free(b_); } + virtual ~memoryTracker() { free(b_); } Address get_address() const { return a_; } unsigned get_size() const { return s_; } diff --git a/dyninstAPI/src/codeRange.C b/dyninstAPI/src/codeRange.C index 928e374a43..27a449e1f3 100644 --- a/dyninstAPI/src/codeRange.C +++ b/dyninstAPI/src/codeRange.C @@ -498,7 +498,7 @@ void codeRange::print_range(Address) { if (func_ptr && !mapped_ptr) mapped_ptr = func_ptr->obj(); if (mapped_ptr && !img_ptr) - img_ptr = mapped_ptr->parse_img(); + img_ptr = mapped_ptr->parse_img().get(); fprintf(stderr, "["); diff --git a/dyninstAPI/src/dynProcess.C b/dyninstAPI/src/dynProcess.C index a6fe098fb2..e0b5dbabb7 100644 --- a/dyninstAPI/src/dynProcess.C +++ b/dyninstAPI/src/dynProcess.C @@ -1503,15 +1503,6 @@ int PCProcess::incrementThreadIndex() { return ret; } -unsigned PCProcess::getAddressWidth() const { - if( mapped_objects.size() > 0 ) { - return mapped_objects[0]->parse_img()->codeObject()->cs()->getAddressWidth(); - } - - // We can call this before we've attached...best effort guess - return sizeof(Address); -} - PCEventHandler * PCProcess::getPCEventHandler() const { return eventHandler_; } diff --git a/dyninstAPI/src/dynProcess.h b/dyninstAPI/src/dynProcess.h index c6d1433637..aa3daed882 100644 --- a/dyninstAPI/src/dynProcess.h +++ b/dyninstAPI/src/dynProcess.h @@ -41,14 +41,11 @@ #include #include "addressSpace.h" -#include "dynThread.h" -#include "pcEventHandler.h" #include "inst.h" #include "codeRange.h" #include "infHeap.h" #include "ast.h" #include "syscallNotification.h" -#include "os.h" #include "baseTramp.h" #include "Symtab.h" @@ -59,6 +56,8 @@ #include "stackwalk/h/walker.h" #include "stackwalk/h/framestepper.h" #include "stackwalk/h/symlookup.h" +#include "pcEventHandler.h" +#include "frame.h" #define RPC_LEAVE_AS_IS 0 #define RPC_RUN_WHEN_DONE 1 @@ -154,7 +153,7 @@ class PCProcess : public AddressSpace { bool removeThread(dynthread_t tid); int getPid() const; - unsigned getAddressWidth() const; + bool wasRunningWhenAttached() const; bool wasCreatedViaAttach() const; bool wasCreatedViaFork() const; diff --git a/dyninstAPI/src/function.h b/dyninstAPI/src/function.h index db987270b3..71ee878ef6 100644 --- a/dyninstAPI/src/function.h +++ b/dyninstAPI/src/function.h @@ -58,7 +58,7 @@ #include "StackMod/StackLocation.h" #include "StackMod/TMap.h" #endif - +#include "Relocation/DynCommon.h" class PCProcess; class mapped_module; class mapped_object; diff --git a/dyninstAPI/src/hybridCallbacks.C b/dyninstAPI/src/hybridCallbacks.C index d28349edb7..18326942d7 100644 --- a/dyninstAPI/src/hybridCallbacks.C +++ b/dyninstAPI/src/hybridCallbacks.C @@ -39,7 +39,7 @@ #include "dynProcess.h" #include "MemoryEmulator/memEmulator.h" #include "PatchModifier.h" - +#include "BPatch_image.h" #include "mapped_object.h" extern pdvector allImages; diff --git a/dyninstAPI/src/image.C b/dyninstAPI/src/image.C index dd166a9a3a..74b2ffe32e 100644 --- a/dyninstAPI/src/image.C +++ b/dyninstAPI/src/image.C @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include "image.h" #include "common/src/arch.h" @@ -83,7 +85,7 @@ AnnotationClass ImageVariableUpPtrAnno("ImageVariableUpPtrAnno", NULL); AnnotationClass ImageFuncUpPtrAnno("ImageFuncUpPtrAnno", NULL); -pdvector allImages; +std::vector > allImages; using namespace std; using namespace Dyninst; @@ -644,8 +646,8 @@ int image::findMain() // We're going to throw it away when we're done so that we can re-sync // with the new symbols we're going to add shortly. bool parseInAllLoadableRegions = (BPatch_normalMode != mode_); - SymtabCodeSource scs(linkedFile, filt, parseInAllLoadableRegions); - CodeObject co(&scs); + auto scs = boost::make_shared(linkedFile, filt, parseInAllLoadableRegions); + CodeObject co(scs); #if !defined(os_freebsd) /* Find the entry point, where we start our analysis */ @@ -653,7 +655,7 @@ int image::findMain() /* Get the code regions we are looking at */ std::set regions; - scs.findRegions(entry_point, regions); + scs->findRegions(entry_point, regions); /* We should only get one region */ if(regions.size() != 1) @@ -778,7 +780,7 @@ int image::findMain() } #endif - if(!mainAddress || !scs.isValidAddress(mainAddress)) { + if(!mainAddress || !scs->isValidAddress(mainAddress)) { startup_printf("%s[%u]: invalid main address 0x%lx\n", FILE__, __LINE__, mainAddress); } else { @@ -1179,7 +1181,7 @@ unsigned int int_addrHash(const Address& addr) { * physical offset. */ -image *image::parseImage(fileDescriptor &desc, +boost::shared_ptr image::parseImage(fileDescriptor &desc, BPatch_hybridMode mode, bool parseGaps) { @@ -1195,12 +1197,11 @@ image *image::parseImage(fileDescriptor &desc, // about it. If so, yank the old one out of the images vector -- replace // it, basically. for (unsigned u=0; udesc())) { - if (allImages[u]->getObject()->canBeShared()) { - // We reference count... - startup_printf("%s[%d]: returning pre-parsed image\n", FILE__, __LINE__); - return allImages[u]->clone(); - } + auto img = allImages[u]; + if(img && desc.isSameFile(img->desc()) && img->getObject()->canBeShared()) { + // We reference count... + startup_printf("%s[%d]: returning pre-parsed image\n", FILE__, __LINE__); + return img; } } @@ -1218,7 +1219,7 @@ image *image::parseImage(fileDescriptor &desc, #endif startup_printf("%s[%d]: about to create image\n", FILE__, __LINE__); - image *ret = new image(desc, err, mode, parseGaps); + boost::shared_ptr ret(new image(desc, err, mode, parseGaps)); startup_printf("%s[%d]: created image\n", FILE__, __LINE__); if(desc.isSharedObject()) @@ -1241,17 +1242,19 @@ image *image::parseImage(fileDescriptor &desc, if (ret) { startup_printf("%s[%d]: error in processing, deleting image and returning\n", FILE__, __LINE__); - delete ret; + ret.reset(); } else { fprintf(stderr, "Failed to allocate memory for parsing %s!\n", desc.file().c_str()); } stats_parse.stopTimer(PARSE_SYMTAB_TIMER); - return NULL; + return boost::shared_ptr(); } - allImages.push_back(ret); + if(ret->getObject()->canBeShared()) { + allImages.push_back(ret); + } // start tracking new blocks after initial parse if ( BPatch_exploratoryMode == mode || @@ -1268,48 +1271,6 @@ image *image::parseImage(fileDescriptor &desc, return ret; } -/* - * Remove a parsed executable from the global list. Used if the old handle - * is no longer valid. - */ -void image::removeImage(image *img) -{ - - // Here's a question... do we want to actually delete images? - // Pro: free up memory. Con: we'd just have to parse them again... - // I guess the question is "how often do we serially open files". - /* int refCount = */ img->destroy(); - - - /* - // We're not deleting when the refcount hits 0, so we may as well - // keep the vector. It's a time/memory problem. - if (refCount == 0) { - pdvector newImages; - // It's gone... remove from image vector - for (unsigned i = 0; i < allImages.size(); i++) { - if (allImages[i] != img) - newImages.push_back(allImages[i]); - } - allImages = newImages; - } - */ -} - -int image::destroy() { - refCount--; - if (refCount == 0) { - if (!desc().isSharedObject()) { - // a.out... destroy it - //delete this; - return 0; - } - } - if (refCount < 0) - assert(0 && "NEGATIVE REFERENCE COUNT FOR IMAGE!"); - return refCount; -} - void image::analyzeIfNeeded() { if (parseState_ == symtab) { parsing_printf("ANALYZING IMAGE %s\n", @@ -1394,14 +1355,10 @@ image::image(fileDescriptor &desc, #if defined(os_linux) || defined(os_freebsd) archive(NULL), #endif - obj_(NULL), - cs_(NULL), filt(NULL), - img_fact_(NULL), parse_cb_(NULL), cb_arg0_(NULL), nextBlockID_(0), - pltFuncs(NULL), trackNewBlocks_(false), refCount(1), parseState_(unparsed), @@ -1526,12 +1483,12 @@ image::image(fileDescriptor &desc, filt = &nuke_heap; bool parseInAllLoadableRegions = (BPatch_normalMode != mode_); - cs_ = new SymtabCodeSource(linkedFile,filt,parseInAllLoadableRegions); + cs_ = boost::make_shared(linkedFile,filt,parseInAllLoadableRegions); // Continue ParseAPI init - img_fact_ = new DynCFGFactory(this); + img_fact_ = boost::make_shared(this); parse_cb_ = new DynParseCallback(this); - obj_ = new CodeObject(cs_,img_fact_,parse_cb_,BPatch_defensiveMode == mode); + obj_ = boost::make_shared(cs_,img_fact_,parse_cb_,BPatch_defensiveMode == mode); string msg; // give user some feedback.... @@ -1555,40 +1512,24 @@ image::image(fileDescriptor &desc, image::~image() { - unsigned i; - + cerr << hex << "Destroying image " << this << " for " << file() << dec << endl; for (map::iterator iter = mods_.begin(); iter != mods_.end(); iter++) { delete (iter->second); } - for (i = 0; i < everyUniqueVariable.size(); i++) { - delete everyUniqueVariable[i]; + for (auto v = everyUniqueVariable.begin(); v != everyUniqueVariable.end(); v++) { + delete *v; } everyUniqueVariable.clear(); createdVariables.clear(); exportedVariables.clear(); - for (i = 0; i < parallelRegions.size(); i++) - delete parallelRegions[i]; + for (auto p = parallelRegions.begin(); p != parallelRegions.end(); p++) + delete *p; parallelRegions.clear(); - // Finally, remove us from the image list. - for (i = 0; i < allImages.size(); i++) { - if (allImages[i] == this) - VECTOR_ERASE(allImages,i,i); - } - - if (pltFuncs) { - delete pltFuncs; - pltFuncs = NULL; - } - - if(obj_) delete obj_; - if(cs_) delete cs_; - if(img_fact_) delete img_fact_; - if(parse_cb_) delete parse_cb_; if (linkedFile) { SymtabAPI::Symtab::closeSymtab(linkedFile); } } @@ -1990,7 +1931,12 @@ bool pdmodule::getVariables(pdvector &vars) { } return (vars.size() > curVarSize); -} /* end getFunctions() */ +} + +pdmodule::~pdmodule() { + +} +/* end getFunctions() */ /* void *image::getPtrToDataInText( Address offset ) const { @@ -2061,32 +2007,6 @@ bool image::findSymByPrefix(const std::string &prefix, pdvector &ret) return true; } -std::unordered_map *image::getPltFuncs() -{ - bool result; - if (pltFuncs) - return pltFuncs; - - - vector fbt; - result = getObject()->getFuncBindingTable(fbt); - if (!result) - return NULL; - - pltFuncs = new std::unordered_map; - assert(pltFuncs); - for(unsigned k = 0; k < fbt.size(); k++) { -#if defined(os_vxworks) - if (fbt[k].target_addr() == 0) { - (*pltFuncs)[fbt[k].rel_addr()] = fbt[k].name().c_str(); - } -#else - (*pltFuncs)[fbt[k].target_addr()] = fbt[k].name().c_str(); -#endif - } - return pltFuncs; -} - void image::getPltFuncs(std::map &out) { out.clear(); diff --git a/dyninstAPI/src/image.h b/dyninstAPI/src/image.h index 17ec4daeb1..d8f2a87529 100644 --- a/dyninstAPI/src/image.h +++ b/dyninstAPI/src/image.h @@ -237,6 +237,8 @@ class image_variable { image_variable(SymtabAPI::Variable *var, pdmodule *mod); + virtual ~image_variable(); + Address getOffset() const; string symTabName() const { return var_->getFirstSymbol()->getMangledName(); } @@ -256,18 +258,6 @@ class image_variable { }; -/* Stores source code to address in text association for modules */ -class lineDict { - public: - lineDict() { } - ~lineDict() { /* TODO */ } - void setLineAddr (unsigned line, Address addr) { lineMap[line] = addr; } - inline bool getLineAddr (const unsigned line, Address &adr); - - private: - std::unordered_map lineMap; -}; - std::string getModuleName(std::string constraint); std::string getFunctionName(std::string constraint); @@ -281,20 +271,11 @@ class image : public codeRange { friend class image_variable; friend class DynCFGFactory; public: - static image *parseImage(fileDescriptor &desc, - BPatch_hybridMode mode, - bool parseGaps); - - // And to get rid of them if we need to re-parse - static void removeImage(image *img); - - // "I need another handle!" - image *clone() { - refCount++; - return this; - } + static boost::shared_ptr parseImage(fileDescriptor &desc, + BPatch_hybridMode mode, + bool parseGaps); - image(fileDescriptor &desc, bool &err, + image(fileDescriptor &desc, bool &err, BPatch_hybridMode mode, bool parseGaps); @@ -305,12 +286,9 @@ class image : public codeRange { // creates the module if it does not exist pdmodule *getOrCreateModule (SymtabAPI::Module *mod); - protected: ~image(); - // 7JAN05: go through the removeImage call! - int destroy(); - public: +public: // find the named module pdmodule *findModule(const string &name, bool wildcard = false); @@ -326,9 +304,6 @@ class image : public codeRange { pdvector *findFuncVectorByPretty(functionNameSieve_t bpsieve, void *user_data, pdvector *found); - pdvector *findFuncVectorByMangled(functionNameSieve_t bpsieve, - void *user_data, - pdvector *found); /*********************************************************************/ /**** Function lookup (by name or address) routines ****/ @@ -350,8 +325,6 @@ class image : public codeRange { // variable and adds to appropriate data structures. image_variable* createImageVariable(Address offset, std::string name, int size, pdmodule *mod); - bool symbolExists(const std::string &); /* Check symbol existence */ - void postProcess(const std::string); /* Load .pif file */ // data member access @@ -371,7 +344,7 @@ class image : public codeRange { unsigned get_size() const { return imageLength(); } SymtabAPI::Symtab *getObject() const { return linkedFile; } - ParseAPI::CodeObject *codeObject() const { return obj_; } + boost::shared_ptr codeObject() const { return obj_; } bool isDyninstRTLib() const { return is_libdyninstRT; } bool isAOut() const { return is_a_out; } @@ -424,8 +397,7 @@ class image : public codeRange { void * getErrFunc() const { return (void *) dyninst_log_perror; } - std::unordered_map *getPltFuncs(); - void getPltFuncs(std::map &out); + void getPltFuncs(std::map &out); #if defined(arch_power) bool updatePltFunc(parse_func *caller_func, Address stub_targ); #endif @@ -446,20 +418,15 @@ class image : public codeRange { // // Platform-specific discovery of the "main" function - // FIXME There is a minor but fundamental design flaw that - // needs to be resolved wrt findMain returning void. int findMain(); bool determineImageType(); bool addSymtabVariables(); void getModuleLanguageInfo(std::unordered_map *mod_langs); - void setModuleLanguages(std::unordered_map *mod_langs); // We have a _lot_ of lookup types; this handles proper entry - void enterFunctionInTables(parse_func *func); - bool buildFunctionLists(pdvector &raw_funcs); void analyzeImage(); // @@ -499,10 +466,10 @@ class image : public codeRange { #endif // ParseAPI - Dyninst::ParseAPI::CodeObject * obj_; - Dyninst::ParseAPI::SymtabCodeSource * cs_; + boost::shared_ptr obj_; + boost::shared_ptr cs_; Dyninst::ParseAPI::SymtabCodeSource::hint_filt *filt; - DynCFGFactory * img_fact_; + boost::shared_ptr img_fact_; DynParseCallback * parse_cb_; void *cb_arg0_; // argument for mapped_object callback @@ -529,11 +496,7 @@ class image : public codeRange { dyn_hash_map modsByFileName; dyn_hash_map modsByFullName; - // "Function" symbol names that are PLT entries or the equivalent - // FIXME remove - std::unordered_map *pltFuncs; - - std::unordered_map varsByAddr; + std::unordered_map varsByAddr; vector > codeHeaps_; vector > dataHeaps_; @@ -556,7 +519,6 @@ class pdmodule { pdmodule(SymtabAPI::Module *mod, image *e) : mod_(mod), exec_(e) {} - void cleanProcessSpecific(PCProcess *p); bool getFunctions(pdvector &funcs); @@ -585,20 +547,15 @@ class pdmodule { SymtabAPI::Module *mod(); - image *imExec() const { return exec_; } - - private: + image * imExec() const { return exec_; } + + virtual ~pdmodule(); + +private: SymtabAPI::Module *mod_; - image *exec_; + image* exec_; }; -inline bool lineDict::getLineAddr (const unsigned line, Address &adr) { - auto iter = lineMap.find(line); - if (iter == lineMap.end()) return false; - adr = iter->second; - return true; -} - class BPatch_basicBlock; int instPointCompare( instPoint*& ip1, instPoint*& ip2 ); diff --git a/dyninstAPI/src/linux-x86.C b/dyninstAPI/src/linux-x86.C index 12be9b6dbe..181960ed1e 100644 --- a/dyninstAPI/src/linux-x86.C +++ b/dyninstAPI/src/linux-x86.C @@ -47,7 +47,6 @@ #include "dyninstAPI/src/function.h" #include "dyninstAPI/src/instPoint.h" #include "common/src/headers.h" -#include "dyninstAPI/src/os.h" #include "common/src/stats.h" #include "common/src/Types.h" #include "dyninstAPI/src/debug.h" @@ -66,12 +65,12 @@ #include "dyninstAPI/src/ast.h" #include "dyninstAPI/src/binaryEdit.h" -#include "dyninstAPI/src/dynThread.h" #include "dyninstAPI/src/dynProcess.h" #include "common/src/linuxKludges.h" #include "instructionAPI/h/InstructionDecoder.h" #include "instructionAPI/h/Instruction.h" +#include "dynThread.h" using namespace Dyninst; using namespace Dyninst::SymtabAPI; diff --git a/dyninstAPI/src/linux.C b/dyninstAPI/src/linux.C index 8101ac6957..fa88a8a613 100644 --- a/dyninstAPI/src/linux.C +++ b/dyninstAPI/src/linux.C @@ -51,6 +51,7 @@ #include "common/src/linuxKludges.h" #include "symtabAPI/h/Symtab.h" + using namespace Dyninst::SymtabAPI; using namespace Dyninst::ProcControlAPI; @@ -174,7 +175,7 @@ bool PCEventMuxer::useCallback(Dyninst::ProcControlAPI::EventType et) return false; } -bool BinaryEdit::getResolvedLibraryPath(const string &filename, std::vector &paths) { +bool BinaryEdit::getResolvedLibraryPath(const string &filename, set &paths) { char *libPathStr, *libPath; std::vector libPaths; struct stat dummy; @@ -183,7 +184,7 @@ bool BinaryEdit::getResolvedLibraryPath(const string &filename, std::vectorimExec() == obj->parse_img()); + assert(pdmod->imExec() == obj->parse_img().get()); mapped_module *mod = new mapped_module(obj, pdmod); // Do things? diff --git a/dyninstAPI/src/mapped_object.C b/dyninstAPI/src/mapped_object.C index 893068a8e9..b40d2b7e0b 100644 --- a/dyninstAPI/src/mapped_object.C +++ b/dyninstAPI/src/mapped_object.C @@ -48,7 +48,7 @@ #include "instPoint.h" #include "MemoryEmulator/memEmulator.h" #include - +#include "BPatch_image.h" #include "PatchCFG.h" #include "PCProcess.h" @@ -71,9 +71,9 @@ bool codeBytesUpdateCB(void *objCB, Address targ) } mapped_object::mapped_object(fileDescriptor fileDesc, - image *img, - AddressSpace *proc, - BPatch_hybridMode mode): + boost::shared_ptr img, + AddressSpace *proc, + BPatch_hybridMode mode): DynObject(img->codeObject(), proc, fileDesc.code()), desc_(fileDesc), fullName_(img->getObject()->file()), @@ -151,7 +151,7 @@ mapped_object *mapped_object::createMappedObject(fileDescriptor &desc, startup_printf("%s[%d]: about to parseImage\n", FILE__, __LINE__); startup_printf("%s[%d]: name %s, codeBase 0x%lx, dataBase 0x%lx\n", FILE__, __LINE__, desc.file().c_str(), desc.code(), desc.data()); - image *img = image::parseImage( desc, analysisMode, parseGaps); + boost::shared_ptr img(image::parseImage( desc, analysisMode, parseGaps)); if (!img) { startup_printf("%s[%d]: failed to parseImage\n", FILE__, __LINE__); return NULL; @@ -249,7 +249,7 @@ mapped_object::mapped_object(const mapped_object *s, AddressSpace *child) : assert(BPatch_defensiveMode != analysisMode_); - image_ = s->image_->clone(); + image_ = s->image_; } @@ -271,33 +271,12 @@ mapped_object::~mapped_object() } everyUniqueVariable.clear(); - for (auto fm_iter = allFunctionsByMangledName.begin(); - fm_iter != allFunctionsByMangledName.end(); ++fm_iter) { - delete fm_iter->second; - } - allFunctionsByMangledName.clear(); - - for (auto fp_iter = allFunctionsByPrettyName.begin(); - fp_iter != allFunctionsByPrettyName.end(); ++fp_iter) { - delete fp_iter->second; - } - allFunctionsByPrettyName.clear(); - - for (auto vm_iter = allVarsByMangledName.begin(); - vm_iter != allVarsByMangledName.end(); ++vm_iter) { - delete vm_iter->second; - } - allVarsByMangledName.clear(); - - for (auto vp_iter = allVarsByPrettyName.begin(); - vp_iter != allVarsByPrettyName.end(); ++vp_iter) { - delete vp_iter->second; - } - allVarsByPrettyName.clear(); + // functions etc are cleaned up when we kill the CFG factory during image destruction // codeRangesByAddr_ is static // Remainder are static - image::removeImage(image_); + image_.reset(); + co_.reset(); } Address mapped_object::codeAbs() const { @@ -400,7 +379,7 @@ mapped_module *mapped_object::findModule(pdmodule *pdmod) assert(pdmod); - if (pdmod->imExec() != parse_img()) { + if (pdmod->imExec() != parse_img().get()) { fprintf(stderr, "%s[%d]: WARNING: lookup for module in wrong mapped object! %p != %p\n", FILE__, __LINE__, pdmod->imExec(), parse_img()); fprintf(stderr, "%s[%d]: \t\t %s \n", FILE__, __LINE__, parse_img()->name().c_str()); fprintf(stderr, "%s[%d]: \t %s != \n", FILE__, __LINE__, pdmod->imExec()->name().c_str()); @@ -1329,7 +1308,7 @@ void mapped_object::expandCodeBytes(SymtabAPI::Region *reg) void *mappedPtr = reg->getPtrToRawData(); Address regStart = reg->getMemOffset(); ParseAPI::Block *cur = NULL; - ParseAPI::CodeObject *cObj = parse_img()->codeObject(); + auto cObj = parse_img()->codeObject(); ParseAPI::CodeRegion *parseReg = NULL; Address copySize = reg->getMemSize(); void* regBuf = malloc(copySize); @@ -1403,7 +1382,7 @@ void mapped_object::expandCodeBytes(SymtabAPI::Region *reg) } // swap out rawDataPtr for the mapped file - static_cast(cObj->cs())-> + static_cast(cObj->cs().get())-> resizeRegion( reg, reg->getMemSize() ); reg->setPtrToRawData( regBuf , copySize ); @@ -1502,7 +1481,7 @@ void mapped_object::updateCodeBytes(SymtabAPI::Region * symReg) assert(NULL != symReg); Address base = codeBase(); - ParseAPI::CodeObject *cObj = parse_img()->codeObject(); + auto cObj = parse_img()->codeObject(); std::vector regions; Block *curB = NULL; @@ -1609,7 +1588,7 @@ bool mapped_object::isUpdateNeeded(Address entry) assert( BPatch_defensiveMode == hybridMode() ); set cregs; - CodeObject *co = parse_img()->codeObject(); + auto co = parse_img()->codeObject(); co->cs()->findRegions(entry-base, cregs); assert( ! co->cs()->regionsOverlap() ); if (0 == cregs.size()) { diff --git a/dyninstAPI/src/mapped_object.h b/dyninstAPI/src/mapped_object.h index 89869a31ba..cef2323926 100644 --- a/dyninstAPI/src/mapped_object.h +++ b/dyninstAPI/src/mapped_object.h @@ -143,7 +143,7 @@ class mapped_object : public codeRange, public Dyninst::PatchAPI::DynObject { private: mapped_object(); mapped_object(fileDescriptor fileDesc, - image *img, + boost::shared_ptr img, AddressSpace *proc, BPatch_hybridMode mode = BPatch_normalMode); @@ -191,7 +191,7 @@ class mapped_object : public codeRange, public Dyninst::PatchAPI::DynObject { Address dataOffset() const { return parse_img()->dataOffset(); } unsigned dataSize() const { return parse_img()->dataLength(); } - image *parse_img() const { return image_; } + boost::shared_ptr parse_img() const { return image_; } bool isSharedLib() const; bool isStaticExec() const; static bool isSystemLib(const std::string &name); @@ -374,7 +374,7 @@ class mapped_object : public codeRange, public Dyninst::PatchAPI::DynObject { bool dirty_; // marks the shared object as dirty bool dirtyCalled_;//see comment for setDirtyCalled - image *image_; // pointer to image if processed is true + boost::shared_ptr image_; // pointer to image if processed is true bool dlopenUsed; //mark this shared object as opened by dlopen AddressSpace *proc_; // Parent process diff --git a/dyninstAPI/src/parRegion.C b/dyninstAPI/src/parRegion.C index 207bbbd624..6ffb9681ad 100644 --- a/dyninstAPI/src/parRegion.C +++ b/dyninstAPI/src/parRegion.C @@ -190,6 +190,10 @@ Address image_parRegion::getClauseLoc(const char * key) return 0; } +image_parRegion::~image_parRegion() { + +} + int int_parRegion::replaceOMPParameter(const char * key, int value) { diff --git a/dyninstAPI/src/parRegion.h b/dyninstAPI/src/parRegion.h index 859e37fbe5..eb1dc1e09e 100644 --- a/dyninstAPI/src/parRegion.h +++ b/dyninstAPI/src/parRegion.h @@ -69,8 +69,10 @@ class image_parRegion : public codeRange { public: image_parRegion(parse_func * imageFunc); image_parRegion(Address firstOffset, parse_func * imageFunc); - - Address firstInsnOffset() const { return firstInsnOffset_; } + + virtual ~image_parRegion(); + + Address firstInsnOffset() const { return firstInsnOffset_; } void setLastInsn(Address last) { lastInsnOffset_ = last;} Address lastInsnOffset() const { return lastInsnOffset_; } diff --git a/dyninstAPI/src/parse-cfg.h b/dyninstAPI/src/parse-cfg.h index d29a9ced82..2936a47600 100644 --- a/dyninstAPI/src/parse-cfg.h +++ b/dyninstAPI/src/parse-cfg.h @@ -228,7 +228,7 @@ class parse_func : public ParseAPI::Function InstructionSource * isrc, FuncSource src); - ~parse_func(); + virtual ~parse_func(); SymtabAPI::Function* getSymtabFunction() const{ return func_; diff --git a/dyninstAPI/src/pcEventHandler.C b/dyninstAPI/src/pcEventHandler.C index 349d7d84fd..bdc70e1cca 100644 --- a/dyninstAPI/src/pcEventHandler.C +++ b/dyninstAPI/src/pcEventHandler.C @@ -41,9 +41,11 @@ #include "Mailbox.h" #include "PCErrors.h" #include "pcEventMuxer.h" +#include "addressSpace.h" #include #include -#include +#include "dynThread.h" + using std::vector; using std::queue; using std::set; diff --git a/dyninstAPI/src/unix.C b/dyninstAPI/src/unix.C index 4df53f04aa..6b0996af3d 100644 --- a/dyninstAPI/src/unix.C +++ b/dyninstAPI/src/unix.C @@ -306,22 +306,22 @@ bool PCProcess::getDyninstRTLibName() use_abi_rt = (getAddressWidth() == 4); #endif - std::vector rt_paths; + std::set rt_paths; std::string rt_base = "libdyninstAPI_RT"; if(use_abi_rt) rt_base += "_m32"; rt_base += ".so"; if(!BinaryEdit::getResolvedLibraryPath(rt_base, rt_paths) || rt_paths.empty()) { - startup_printf("%s[%d]: Could not find libdyninstAPI_RT.so in search path\n", FILE__, __LINE__); - return false; + startup_printf("%s[%d]: Could not find libdyninstAPI_RT.so in search path\n", FILE__, __LINE__); + return false; } for(auto i = rt_paths.begin(); i != rt_paths.end(); ++i) { - startup_printf("%s[%d]: Candidate RTLib is %s\n", FILE__, __LINE__, i->c_str()); + startup_printf("%s[%d]: Candidate RTLib is %s\n", FILE__, __LINE__, i->c_str()); } - dyninstRT_name = rt_paths[0]; + dyninstRT_name = *(rt_paths.begin()); return true; } @@ -337,7 +337,7 @@ bool PCProcess::setEnvPreload(std::vector &envp, std::string fileNa use_abi_rt = (symt_obj->getAddressWidth() == 4); #endif - std::vector rt_paths; + std::set rt_paths; std::string rt_base = "libdyninstAPI_RT"; if(use_abi_rt) rt_base += "_m32"; rt_base += ".so"; @@ -350,9 +350,9 @@ bool PCProcess::setEnvPreload(std::vector &envp, std::string fileNa i != rt_paths.end(); ++i) { - startup_printf("%s[%d]: Candidate RTLib is %s\n", FILE__, __LINE__, i->c_str()); + startup_printf("%s[%d]: Candidate RTLib is %s\n", FILE__, __LINE__, i->c_str()); } - std::string rt_lib_name = rt_paths[0]; + std::string rt_lib_name = *(rt_paths.begin()); // Check to see if the library given exists. if (access(rt_lib_name.c_str(), R_OK)) { @@ -538,14 +538,30 @@ bool PCProcess::startDebugger() { #include "dyninstAPI/src/binaryEdit.h" #include "symtabAPI/h/Archive.h" +#include "symlite/h/SymLite-elf.h" using namespace Dyninst::SymtabAPI; +struct CloseReader +{ + CloseReader(SymElfFactory* f) : fact(f) {}; + void operator()(SymReader* s) { + fact->closeSymbolReader(s); + } + SymElfFactory* fact; +}; +bool BinaryEdit::isCompatibleBinary(std::string pathname) +{ + SymElfFactory f; + boost::shared_ptr reader(f.openSymbolReader(pathname), CloseReader(&f)); + return reader && reader->getAddressWidth() == getAddressWidth(); +} + mapped_object *BinaryEdit::openResolvedLibraryName(std::string filename, std::map &retMap) { - std::vector paths; - std::vector::iterator pathIter; + std::set paths; + std::set::iterator pathIter; // First, find the specified library file bool resolved = getResolvedLibraryPath(filename, paths); @@ -555,17 +571,16 @@ mapped_object *BinaryEdit::openResolvedLibraryName(std::string filename, FILE__, __LINE__, filename.c_str()); Symtab *origSymtab = getMappedObject()->parse_img()->getObject(); - assert(mgr()); + 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()) { + if(isCompatibleBinary(*pathIter)) + { + BinaryEdit *temp = BinaryEdit::openFile(*pathIter, mgr(), patcher()); retMap.insert(std::make_pair(*pathIter, temp)); return temp->getMappedObject(); } - delete temp; } } else { // Static executable case @@ -588,19 +603,15 @@ mapped_object *BinaryEdit::openResolvedLibraryName(std::string filename, if (library->getAllMembers(members)) { std::vector ::iterator member_it; for (member_it = members.begin(); member_it != members.end(); - ++member_it) + ++member_it) { - BinaryEdit *temp = BinaryEdit::openFile(*pathIter, - mgr(), patcher(), (*member_it)->memberName()); - - if (temp && temp->getAddressWidth() == getAddressWidth()) { + if(isCompatibleBinary(*pathIter)) + { + BinaryEdit *temp = BinaryEdit::openFile(*pathIter, + mgr(), patcher(), (*member_it)->memberName()); std::string mapName = *pathIter + string(":") + - (*member_it)->memberName(); + (*member_it)->memberName(); retMap.insert(std::make_pair(mapName, temp)); - }else{ - if(temp) delete temp; - retMap.clear(); - break; } } @@ -614,25 +625,24 @@ mapped_object *BinaryEdit::openResolvedLibraryName(std::string filename, //if( library ) delete library; } } else if (Symtab::openFile(singleObject, *pathIter)) { - BinaryEdit *temp = BinaryEdit::openFile(*pathIter, mgr(), patcher()); - if (temp && temp->getAddressWidth() == getAddressWidth()) { + if (isCompatibleBinary(*pathIter)) { if( singleObject->getObjectType() == obj_SharedLib || - singleObject->getObjectType() == obj_Executable ) + 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{ + 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()); + + Symtab::closeSymtab(singleObject); + } else{ + BinaryEdit *temp = BinaryEdit::openFile(*pathIter, mgr(), patcher()); retMap.insert(std::make_pair(*pathIter, temp)); return temp->getMappedObject(); } } - if(temp) delete temp; } } } @@ -661,6 +671,7 @@ mapped_object *BinaryEdit::openResolvedLibraryName(std::string filename, #if defined(os_linux) #include "dyninstAPI/src/linux.h" + #else #include "dyninstAPI/src/freebsd.h" #endif diff --git a/dyninstAPI/src/variable.C b/dyninstAPI/src/variable.C index 69c3d96ce8..2b12e3e91e 100644 --- a/dyninstAPI/src/variable.C +++ b/dyninstAPI/src/variable.C @@ -84,9 +84,12 @@ SymtabAPI::Aggregate::name_iter image_variable::pretty_names_end() const return var_->pretty_names_end(); } +image_variable::~image_variable() { + +} -int_variable::int_variable(image_variable *var, +int_variable::int_variable(image_variable *var, Address base, mapped_module *mod) : addr_(base + var->getOffset()), diff --git a/parseAPI/h/CFGFactory.h b/parseAPI/h/CFGFactory.h index d9d31a34b3..fdc6d89d8c 100644 --- a/parseAPI/h/CFGFactory.h +++ b/parseAPI/h/CFGFactory.h @@ -132,9 +132,7 @@ class PARSER_EXPORT CFGFactory { void destroy_block(Block *b); void destroy_edge(Edge *e); - void destroy_all(); - - protected: +protected: virtual Function * mkfunc(Address addr, FuncSource src, std::string name, CodeObject * obj, CodeRegion * region, Dyninst::InstructionSource * isrc); diff --git a/parseAPI/h/CFGModifier.h b/parseAPI/h/CFGModifier.h index 896836d234..51a344a578 100644 --- a/parseAPI/h/CFGModifier.h +++ b/parseAPI/h/CFGModifier.h @@ -67,7 +67,7 @@ class CFGModifier { // The void * becomes "owned" by the CodeObject, as it's used // as a backing store; it cannot be ephemeral. // Returns the new entry block. - PARSER_EXPORT static InsertedRegion *insert(CodeObject *obj, + PARSER_EXPORT static InsertedRegion *insert(boost::shared_ptr obj, Address base, void *data, unsigned size); diff --git a/parseAPI/h/CodeObject.h b/parseAPI/h/CodeObject.h index c8af4d7908..d08f03fd31 100644 --- a/parseAPI/h/CodeObject.h +++ b/parseAPI/h/CodeObject.h @@ -32,6 +32,7 @@ #define CODE_OBJECT_H #include +#include #include "Symtab.h" #include "IBSTree.h" @@ -44,6 +45,8 @@ namespace Dyninst { namespace ParseAPI { + + /** A CodeObject defines a collection of binary code, for example a binary, dynamic library, archive, memory snapshot, etc. In the context of Dyninst, it maps to an image object. @@ -61,14 +64,33 @@ typedef enum { class CodeObject { friend class CFGModifier; + PARSER_EXPORT void initialize(ParseCallback* cb = NULL); public: PARSER_EXPORT static void version(int& major, int& minor, int& maintenance); typedef std::set funclist; - PARSER_EXPORT CodeObject(CodeSource * cs, - CFGFactory * fact = NULL, + template + PARSER_EXPORT CodeObject(CSPtr cs, + FactPtr fact, + ParseCallback * cb = NULL, + bool defensiveMode = false) : + _cs(cs), + _fact(fact), + defensive(defensiveMode) + { + initialize(cb); + } + template + PARSER_EXPORT CodeObject(CSPtr cs, + void* dummy = NULL, ParseCallback * cb = NULL, - bool defensiveMode = false); + bool defensiveMode = false) : + _cs(boost::shared_ptr(cs)), + _fact(boost::make_shared()), + defensive(defensiveMode) + { + initialize(cb); + } PARSER_EXPORT ~CodeObject(); /** Parsing interface **/ @@ -108,7 +130,7 @@ class CodeObject { PARSER_EXPORT int findFuncs(CodeRegion * cr, Address start, Address end, std::set & funcs); - PARSER_EXPORT const funclist & funcs() { return flist; } + PARSER_EXPORT const funclist & funcs() { return *flist; } // blocks PARSER_EXPORT Block * findBlockByEntry(CodeRegion * cr, Address entry); @@ -120,8 +142,8 @@ class CodeObject { PARSER_EXPORT Block * findNextBlock(CodeRegion * cr, Address addr); /* Misc */ - PARSER_EXPORT CodeSource * cs() const { return _cs; } - PARSER_EXPORT CFGFactory * fact() const { return _fact; } + PARSER_EXPORT boost::shared_ptr cs() const { return _cs; } + PARSER_EXPORT boost::shared_ptr fact() const { return _fact; } PARSER_EXPORT bool defensiveMode() { return defensive; } PARSER_EXPORT bool isIATcall(Address insn, std::string &calleeName); @@ -166,15 +188,14 @@ class CodeObject { friend void Function::setEntryBlock(Block *); private: - CodeSource * _cs; - CFGFactory * _fact; + boost::shared_ptr _cs; + boost::shared_ptr _fact; ParseCallbackManager * _pcb; Parser * parser; // parser implementation - bool owns_factory; bool defensive; - funclist& flist; + boost::shared_ptr flist; }; // We need CFG.h, which is included by this diff --git a/parseAPI/h/CodeSource.h b/parseAPI/h/CodeSource.h index e7e7651e36..bcadd71055 100644 --- a/parseAPI/h/CodeSource.h +++ b/parseAPI/h/CodeSource.h @@ -195,11 +195,11 @@ class PARSER_EXPORT CodeSource : public Dyninst::InstructionSource { virtual void decrementCounter(const std::string& /*name*/) const { return; } virtual void startTimer(const std::string& /*name*/) const { return; } virtual void stopTimer(const std::string& /*name*/) const { return; } - + + virtual ~CodeSource() {} protected: CodeSource() : _regions_overlap(false), _table_of_contents(0) {} - virtual ~CodeSource() {} void addRegion(CodeRegion *); diff --git a/parseAPI/h/ParseCallback.h b/parseAPI/h/ParseCallback.h index ef64b23e6d..19a6a96b03 100644 --- a/parseAPI/h/ParseCallback.h +++ b/parseAPI/h/ParseCallback.h @@ -178,12 +178,12 @@ class ParseCallbackManager { iterator end() { return cbs_.end(); } void batch_begin(); - void batch_end(CFGFactory *fact); // fact provided so we can safely delete + void batch_end(boost::shared_ptr fact); // fact provided so we can safely delete // Batch-compatible methods - void destroy(Block *, CFGFactory *fact); - void destroy(Edge *, CFGFactory *fact); - void destroy(Function *, CFGFactory *fact); + void destroy(Block *b, boost::shared_ptr fact); + void destroy(Edge *e, boost::shared_ptr fact); + void destroy(Function *f, boost::shared_ptr fact); void removeEdge(Block *, Edge *, ParseCallback::edge_type_t); void addEdge(Block *, Edge *, ParseCallback::edge_type_t); void removeBlock(Function *, Block *); diff --git a/parseAPI/src/Block.C b/parseAPI/src/Block.C index bf82dd7c45..9b93aded71 100644 --- a/parseAPI/src/Block.C +++ b/parseAPI/src/Block.C @@ -50,19 +50,23 @@ Block::Block(CodeObject * o, CodeRegion *r, Address start) : _func_cnt(0), _parsed(false) { +#if defined(parsing_block_counts) if (_obj && _obj->cs()) { _obj->cs()->incrementCounter(PARSE_BLOCK_COUNT); _obj->cs()->addCounter(PARSE_BLOCK_SIZE, size()); } +#endif } Block::~Block() { +#if defined(parsing_block_counts) // nothing special if (_obj && _obj->cs()) { _obj->cs()->decrementCounter(PARSE_BLOCK_COUNT); _obj->cs()->addCounter(PARSE_BLOCK_SIZE, -1*size()); } +#endif } bool @@ -70,7 +74,7 @@ Block::consistent(Address addr, Address & prev_insn) { InstructionSource * isrc; if(!_obj->cs()->regionsOverlap()) - isrc = _obj->cs(); + isrc = _obj->cs().get(); else isrc = region(); const unsigned char * buf = diff --git a/parseAPI/src/BoundFactCalculator.C b/parseAPI/src/BoundFactCalculator.C index 6dc8655bf0..5ca283f788 100644 --- a/parseAPI/src/BoundFactCalculator.C +++ b/parseAPI/src/BoundFactCalculator.C @@ -352,8 +352,8 @@ BoundFact* BoundFactsCalculator::Meet(Node::Ptr curNode) { parsing_printf("\t\tThe fact from %lx before applying transfer function\n", srcNode->addr()); prevFact->Print(); if (!srcNode->assign()) { - prevFact = new BoundFact(*prevFact); - newCopy = true; +// prevFact = new BoundFact(*prevFact); +// newCopy = true; parsing_printf("\t\tThe predecessor node is the virtual entry ndoe\n"); if (firstBlock && handleOneByteRead) { // If the indirect jump is in the entry block @@ -370,8 +370,8 @@ BoundFact* BoundFactsCalculator::Meet(Node::Ptr curNode) { prevFact->GenFact(axAST, new BoundValue(StridedInterval(1,0,8)), false); } } else if (srcNode->assign() && IsConditionalJump(srcNode->assign()->insn())) { - prevFact = new BoundFact(*prevFact); - newCopy = true; +// prevFact = new BoundFact(*prevFact); +// newCopy = true; // If the predecessor is a conditional jump, // we can determine bound fact based on the predicate and the edge type parsing_printf("\t\tThe predecessor node is a conditional jump!\n"); diff --git a/parseAPI/src/CFGFactory.C b/parseAPI/src/CFGFactory.C index dbf845d55e..443fc66644 100644 --- a/parseAPI/src/CFGFactory.C +++ b/parseAPI/src/CFGFactory.C @@ -80,7 +80,22 @@ Edge::Edge(Block *source, Block *target, EdgeTypeEnum type) CFGFactory::~CFGFactory() { - destroy_all(); + + auto eit = edges_.begin(); + while(eit != edges_.end()) { + auto cur = eit++; + destroy_edge(&*cur); + } + auto bit = blocks_.begin(); + while(bit != blocks_.end()) { + auto cur = bit++; + destroy_block(&*cur); + } + auto fit = funcs_.begin(); + while(fit != funcs_.end()) { + auto cur = fit++; + destroy_func(&*cur); + } } // ParseAPI call... @@ -177,25 +192,3 @@ CFGFactory::free_edge(Edge *e) { delete e; } -void -CFGFactory::destroy_all() { - // XXX carefully calling free_* routines; could be faster and just - // call delete - - fact_list::iterator eit = edges_.begin(); - while(eit != edges_.end()) { - fact_list::iterator cur = eit++; - destroy_edge(&*cur); - } - fact_list::iterator bit = blocks_.begin(); - while(bit != blocks_.end()) { - fact_list::iterator cur = bit++; - destroy_block(&*cur); - } - fact_list::iterator fit = funcs_.begin(); - while(fit != funcs_.end()) { - fact_list::iterator cur = fit++; - destroy_func(&*cur); - } -} - diff --git a/parseAPI/src/CFGModifier.C b/parseAPI/src/CFGModifier.C index 1b4f99e24f..ad3181b6a7 100644 --- a/parseAPI/src/CFGModifier.C +++ b/parseAPI/src/CFGModifier.C @@ -300,7 +300,7 @@ bool CFGModifier::remove(vector &blks, bool force) { rd->blocksByAddr.erase(b->start()); // 5) - CFGFactory *fact = b->obj()->fact(); + auto fact = b->obj()->fact(); for (vector::iterator eit = deadEdges.begin(); eit != deadEdges.end(); eit++) { pcb->destroy(*eit, fact); } @@ -345,7 +345,7 @@ bool CFGModifier::remove(Function *f) { return true; } -InsertedRegion *CFGModifier::insert(CodeObject *obj, +InsertedRegion *CFGModifier::insert(boost::shared_ptr obj, Address base, void *data, unsigned size) { parsing_cerr << "Inserting new code: " << hex << (unsigned) (*((unsigned *)data)) << dec << endl; @@ -378,7 +378,7 @@ Function *CFGModifier::makeEntry(Block *b) { // functionality. // We want to call ParseData::get_func(CodeRegion *, Address, FuncSource) - ParseData *data = b->obj()->parser->_parse_data; + auto data = b->obj()->parser->_parse_data; return data->get_func(b->region(), b->start(), MODIFICATION); diff --git a/parseAPI/src/CodeObject.C b/parseAPI/src/CodeObject.C index 2ab2e56205..7a94b2efd1 100644 --- a/parseAPI/src/CodeObject.C +++ b/parseAPI/src/CodeObject.C @@ -43,9 +43,16 @@ using namespace Dyninst::ParseAPI; namespace { // initialization help - static inline CFGFactory * __fact_init(CFGFactory * fact) { - if(fact) return fact; - return new CFGFactory(); + template + static inline boost::shared_ptr __fact_init(T fact) { + if(fact) return boost::shared_ptr(fact); + return boost::shared_ptr(new CFGFactory()); + } + template + static inline boost::shared_ptr __fact_init(boost::shared_ptr fact) { + assert(fact); + return fact; + } } @@ -61,20 +68,32 @@ void CodeObject::version(int& major, int& minor, int& maintenance) } -CodeObject::CodeObject(CodeSource *cs, - CFGFactory *fact, - ParseCallback * cb, - bool defMode) : - _cs(cs), - _fact(__fact_init(fact)), - _pcb(new ParseCallbackManager(cb)), - parser(new Parser(*this,*_fact,*_pcb) ), - owns_factory(fact == NULL), - defensive(defMode), - flist(parser->sorted_funcs) -{ - process_hints(); // if any -} +//CodeObject::CodeObject(CodeSource *cs, +// CFGFactory *fact, +// ParseCallback * cb, +// bool defMode) : +// _cs(cs), +// _fact(__fact_init(fact)), +// _pcb(new ParseCallbackManager(cb)), +// parser(new Parser(*this,_fact,_pcb) ), +// defensive(defMode), +// flist(parser->sorted_funcs) +//{ +// process_hints(); // if any +//} +//CodeObject::CodeObject(CodeSource *cs, +// boost::shared_ptr fact, +// ParseCallback * cb, +// bool defMode) : +// _cs(cs), +// _fact(__fact_init(fact)), +// _pcb(new ParseCallbackManager(cb)), +// parser(new Parser(*this,_fact,_pcb) ), +// defensive(defMode), +// flist(parser->sorted_funcs) +//{ +// process_hints(); // if any +//} void CodeObject::process_hints() @@ -87,7 +106,7 @@ CodeObject::process_hints() CodeRegion * cr = (*hit)._reg; if(!cs()->regionsOverlap()) f = parser->factory()._mkfunc( - (*hit)._addr,HINT,(*hit)._name,this,cr,cs()); + (*hit)._addr,HINT,(*hit)._name,this,cr,cs().get()); else f = parser->factory()._mkfunc( (*hit)._addr,HINT,(*hit)._name,this,cr,cr); @@ -99,8 +118,6 @@ CodeObject::process_hints() } CodeObject::~CodeObject() { - if(owns_factory) - delete _fact; delete _pcb; if(parser) delete parser; @@ -298,9 +315,9 @@ CodeObject::parseNewEdges( vector & worklist ) } } - parser->_pcb.batch_begin(); // must batch callbacks and deliver after parsing structures are stable + _pcb->batch_begin(); // must batch callbacks and deliver after parsing structures are stable parser->parse_edges( work_elems ); - parser->_pcb.batch_end(_fact); + _pcb->batch_end(_fact); if (defensiveMode()) { // update tampersStack for modified funcs @@ -343,7 +360,7 @@ bool CodeObject::isIATcall(Address insnAddr, std::string &calleeName) InstructionDecoder dec = InstructionDecoder(bufferBegin, InstructionDecoder::maxInstructionLength, reg->getArch()); InstructionAdapter_t ah = InstructionAdapter_t( - dec, insnAddr, this, reg, cs(), blk); + dec, insnAddr, this, reg, cs().get(), blk); return ah.isIATcall(calleeName); } @@ -395,3 +412,10 @@ Address CodeObject::getFreeAddr() const { } return hi; } + +void CodeObject::initialize(ParseCallback *cb) { + _pcb = new ParseCallbackManager(cb); + parser = new Parser(*this,_fact,_pcb); + flist = parser->sorted_funcs; + process_hints(); // if any +} diff --git a/parseAPI/src/Function.C b/parseAPI/src/Function.C index 8db08a1eb3..a5d2f75e62 100644 --- a/parseAPI/src/Function.C +++ b/parseAPI/src/Function.C @@ -119,9 +119,11 @@ ParseAPI::Edge::~Edge() { Function::~Function() { +#if defined(parsing_block_counts) if (_obj && _obj->cs()) { _obj->cs()->decrementCounter(PARSE_FUNCTION_COUNT); } +#endif vector::iterator eit = _extents.begin(); for( ; eit != _extents.end(); ++eit) { delete *eit; diff --git a/parseAPI/src/IA_powerDetails.C b/parseAPI/src/IA_powerDetails.C index 387cab2c5e..bb3cefd87f 100644 --- a/parseAPI/src/IA_powerDetails.C +++ b/parseAPI/src/IA_powerDetails.C @@ -800,7 +800,7 @@ bool IA_powerDetails::parseJumpTable(Block* currBlk, 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()); + SymtabCodeSource *scs = dynamic_cast(IABlock._obj->cs().get()); SymtabAPI::Symtab * symtab = scs->getSymtabObject(); std::vector regions; symtab->getAllRegions(regions); diff --git a/parseAPI/src/IndirectASTVisitor.C b/parseAPI/src/IndirectASTVisitor.C index 88c9469336..bd650b547f 100644 --- a/parseAPI/src/IndirectASTVisitor.C +++ b/parseAPI/src/IndirectASTVisitor.C @@ -509,7 +509,7 @@ AST::Ptr JumpTableFormatVisitor::visit(DataflowAPI::RoseAST *ast) { return AST::Ptr(); } -bool PerformTableRead(BoundValue &target, set & jumpTargets, CodeSource *cs) { +bool PerformTableRead(BoundValue &target, set & jumpTargets, boost::shared_ptr cs) { Address tableBase = (Address)target.interval.low; Address tableLastEntry = (Address)target.interval.high; diff --git a/parseAPI/src/IndirectASTVisitor.h b/parseAPI/src/IndirectASTVisitor.h index d07a20984d..bf8c9715fa 100644 --- a/parseAPI/src/IndirectASTVisitor.h +++ b/parseAPI/src/IndirectASTVisitor.h @@ -17,7 +17,7 @@ AST::Ptr SimplifyAnAST(AST::Ptr ast, Address addr); AST::Ptr SubstituteAnAST(AST::Ptr ast, const BoundFact::AliasMap &aliasMap); AST::Ptr DeepCopyAnAST(AST::Ptr ast); bool ContainAnAST(AST::Ptr root, AST::Ptr check); -bool PerformTableRead(BoundValue &target, set & jumpTargets, CodeSource*); +bool PerformTableRead(BoundValue &target, set & jumpTargets, boost::shared_ptr); // On x86 and x86-64, the value of PC is post-instruction, diff --git a/parseAPI/src/IndirectAnalyzer.C b/parseAPI/src/IndirectAnalyzer.C index 501a04773c..a709b3e64f 100644 --- a/parseAPI/src/IndirectAnalyzer.C +++ b/parseAPI/src/IndirectAnalyzer.C @@ -120,7 +120,7 @@ void IndirectControlFlowAnalyzer::FindAllThunks() { return; } InstructionDecoder dec(buf, b->end() - b->start(), b->obj()->cs()->getArch()); - InsnAdapter::IA_IAPI block(dec, b->start(), b->obj() , b->region(), b->obj()->cs(), b); + InsnAdapter::IA_IAPI block(dec, b->start(), b->obj() , b->region(), b->obj()->cs().get(), b); Address cur = b->start(); while (cur < b->end()) { if (block.getInstruction()->getCategory() == c_CallInsn && block.isThunk()) { diff --git a/parseAPI/src/ParseCallback.C b/parseAPI/src/ParseCallback.C index 760a017558..151e031320 100644 --- a/parseAPI/src/ParseCallback.C +++ b/parseAPI/src/ParseCallback.C @@ -46,7 +46,7 @@ void ParseCallbackManager::batch_begin() { inBatch_ = true; } -void ParseCallbackManager::batch_end(CFGFactory *fact) { +void ParseCallbackManager::batch_end(boost::shared_ptr fact) { assert(inBatch_); // And now we do work. Hard work. // Collect up all the info we've copied and send it up to the user @@ -115,7 +115,7 @@ void ParseCallbackManager::batch_end(CFGFactory *fact) { inBatch_ = false; } -void ParseCallbackManager::destroy(Block *b, CFGFactory *fact) { +void ParseCallbackManager::destroy(Block *b, boost::shared_ptr fact) { if (inBatch_) destroyedBlocks_.push_back(b); else { destroy_cb(b); @@ -123,7 +123,7 @@ void ParseCallbackManager::destroy(Block *b, CFGFactory *fact) { } } -void ParseCallbackManager::destroy(Edge *e, CFGFactory *fact) { +void ParseCallbackManager::destroy(Edge *e, boost::shared_ptr fact) { if (inBatch_) destroyedEdges_.push_back(e); else { destroy_cb(e); @@ -131,7 +131,7 @@ void ParseCallbackManager::destroy(Edge *e, CFGFactory *fact) { } } -void ParseCallbackManager::destroy(Function *f, CFGFactory *fact) { +void ParseCallbackManager::destroy(Function *f, boost::shared_ptr fact) { if (inBatch_) destroyedFunctions_.push_back(f); else { destroy_cb(f); diff --git a/parseAPI/src/ParseData.C b/parseAPI/src/ParseData.C index f7495f1b1e..da767ed96c 100644 --- a/parseAPI/src/ParseData.C +++ b/parseAPI/src/ParseData.C @@ -144,7 +144,7 @@ StandardParseData::get_func(CodeRegion * cr, Address entry, FuncSource src) } parsing_printf("[%s] new function for target %lx\n",FILE__,entry); ret = _parser->factory()._mkfunc( - entry,src,name,&_parser->obj(),reg,_parser->obj().cs()); + entry,src,name,&_parser->obj(),reg,_parser->obj().cs().get()); _parser->record_func(ret); } } diff --git a/parseAPI/src/ParseData.h b/parseAPI/src/ParseData.h index 1ed4e08665..7129912064 100644 --- a/parseAPI/src/ParseData.h +++ b/parseAPI/src/ParseData.h @@ -124,7 +124,7 @@ class ParseFrame { ParseWorkElem * seed; // stored for cleanup - ParseFrame(Function * f,ParseData *pd) : + ParseFrame(Function * f,boost::shared_ptr pd) : curAddr(0), num_insns(0), call_target(NULL), @@ -142,7 +142,7 @@ class ParseFrame { void set_status(Status); private: Status _status; - ParseData * _pd; + boost::shared_ptr _pd; }; /* per-CodeRegion parsing data */ diff --git a/parseAPI/src/Parser-speculative.C b/parseAPI/src/Parser-speculative.C index 26a3a5a3f6..3146f77981 100644 --- a/parseAPI/src/Parser-speculative.C +++ b/parseAPI/src/Parser-speculative.C @@ -127,7 +127,7 @@ namespace hd { bool compute_gap_new( CodeRegion * cr, Address addr, - set const& funcs, + boost::shared_ptr > funcs, set::const_iterator & beforeGap, Address & gapStart, Address & gapEnd, @@ -138,17 +138,17 @@ namespace hd { Address upperBound = cr->offset() + cr->length(); - if (funcs.empty()) { + if (funcs->empty()) { if (addr >= upperBound) return false; gapStart = addr + 1; if (gapStart < lowerBound) gapStart = lowerBound; gapEnd = upperBound; reset_iterator = true; return true; - } else if (addr < (*funcs.begin())->addr()) { + } else if (addr < (*funcs->begin())->addr()) { gapStart = addr + 1; if (gapStart < lowerBound) gapStart = lowerBound; - gapEnd = (*funcs.begin())->addr(); + gapEnd = (*funcs->begin())->addr(); reset_iterator = true; return true; } else { @@ -157,12 +157,12 @@ namespace hd { ++afterGap; while (true) { gapStart = calc_end(*beforeGap); - if (afterGap == funcs.end() || (*afterGap)->addr() > upperBound) + if (afterGap == funcs->end() || (*afterGap)->addr() > upperBound) gapEnd = upperBound; else gapEnd = (*afterGap)->addr(); if (addr >= gapEnd || (long)(gapEnd - gapStart) <= MIN_GAP_SIZE) { - if (afterGap == funcs.end()) return false; + if (afterGap == funcs->end()) return false; beforeGap = afterGap; ++afterGap; } else { @@ -300,9 +300,9 @@ void Parser::parse_gap_heuristic(CodeRegion * cr) int match = 0; // don't touch this iterator, except when it starts out empty - bool reset_iterator = sorted_funcs.empty(); - set::const_iterator fit = sorted_funcs.begin(); - while(hd::compute_gap(cr,curAddr,sorted_funcs,fit,gapStart,gapEnd)) { + bool reset_iterator = sorted_funcs->empty(); + set::const_iterator fit = sorted_funcs->begin(); + while(hd::compute_gap(cr,curAddr,*sorted_funcs,fit,gapStart,gapEnd)) { parsing_printf("[%s] scanning for prologues in [%lx,%lx)\n", FILE__,gapStart,gapEnd); for(curAddr=gapStart; curAddr < gapEnd; ++curAddr) { @@ -312,7 +312,7 @@ void Parser::parse_gap_heuristic(CodeRegion * cr) parse_at(cr,curAddr,true,GAP); if(reset_iterator) { - fit = sorted_funcs.begin(); + fit = sorted_funcs->begin(); reset_iterator = false; } @@ -350,8 +350,8 @@ void Parser::probabilistic_gap_parsing(CodeRegion *cr) { Address gapEnd = 0; Address curAddr = 0; - bool reset_iterator = sorted_funcs.empty(); - set::const_iterator beforeGap = sorted_funcs.begin(); + bool reset_iterator = sorted_funcs->empty(); + set::const_iterator beforeGap = sorted_funcs->begin(); while(hd::compute_gap_new(cr,curAddr,sorted_funcs,beforeGap,gapStart,gapEnd, reset_iterator)) { parsing_printf("[%s] scanning for FEP in [%lx,%lx)\n", @@ -365,8 +365,8 @@ void Parser::probabilistic_gap_parsing(CodeRegion *cr) { if (parsed) continue; parse_at(cr,curAddr,true,GAP); - if(reset_iterator && !sorted_funcs.empty()) { - beforeGap = sorted_funcs.begin(); + if(reset_iterator && !sorted_funcs->empty()) { + beforeGap = sorted_funcs->begin(); } break; diff --git a/parseAPI/src/Parser.C b/parseAPI/src/Parser.C index eb753c0715..796993eac1 100644 --- a/parseAPI/src/Parser.C +++ b/parseAPI/src/Parser.C @@ -45,7 +45,7 @@ #include "debug_parse.h" #include - +#include using namespace std; using namespace Dyninst; using namespace Dyninst::ParseAPI; @@ -55,7 +55,7 @@ typedef std::pair< Address, EdgeTypeEnum > edge_pair_t; typedef vector< edge_pair_t > Edges_t; #include "common/src/dthread.h" - +#include namespace { struct less_cr { bool operator()(CodeRegion * x, CodeRegion * y) @@ -65,16 +65,16 @@ namespace { }; } -Parser::Parser(CodeObject & obj, CFGFactory & fact, ParseCallbackManager & pcb) : +Parser::Parser(CodeObject &obj, boost::shared_ptr fact, ParseCallbackManager *pcb) : _obj(obj), _cfgfact(fact), _pcb(pcb), - _parse_data(NULL), num_delayedFrames(0), _sink(NULL), _parse_state(UNPARSED), _in_parse(false), - _in_finalize(false) + _in_finalize(false), + sorted_funcs(boost::make_shared >()) { // cache plt entries for fast lookup const map & lm = obj.cs()->linkage(); @@ -98,7 +98,7 @@ Parser::Parser(CodeObject & obj, CFGFactory & fact, ParseCallbackManager & pcb) sort(copy.begin(),copy.end(),less_cr()); // allocate a sink block -- region is arbitrary - _sink = _cfgfact._mksink(&_obj,copy[0]); + _sink = factory()._mksink(&_obj,copy[0]); bool overlap = false; CodeRegion * prev = copy[0], *cur = NULL; @@ -114,9 +114,9 @@ Parser::Parser(CodeObject & obj, CFGFactory & fact, ParseCallbackManager & pcb) } if(overlap) - _parse_data = new OverlappingParseData(this,copy); + _parse_data = boost::make_shared(this,copy); else - _parse_data = new StandardParseData(this); + _parse_data = boost::make_shared (this); } ParseFrame::~ParseFrame() @@ -126,8 +126,6 @@ ParseFrame::~ParseFrame() Parser::~Parser() { - if(_parse_data) - delete _parse_data; vector::iterator fit = frames.begin(); for( ; fit != frames.end(); ++fit) @@ -229,7 +227,7 @@ Parser::parse_at(Address target, bool recursive, FuncSource src) if(_parse_state == UNPARSEABLE) return; - StandardParseData * spd = dynamic_cast(_parse_data); + auto spd = boost::shared_dynamic_cast(_parse_data); if(!spd) { parsing_printf(" parse_at is invalid on overlapping regions\n"); return; @@ -742,7 +740,7 @@ Parser::record_func(Function *f) { else discover_funcs.push_back(f); - sorted_funcs.insert(f); + sorted_funcs->insert(f); _parse_data->record_func(f); } @@ -768,7 +766,7 @@ Parser::init_frame(ParseFrame & frame) return; } if (split) { - _pcb.splitBlock(split,b); + _pcb->splitBlock(split,b); } } @@ -818,7 +816,7 @@ namespace { inline std::pair get_next_block( Address addr, CodeRegion * codereg, - ParseData * _parse_data) + boost::shared_ptr _parse_data) { Block * nextBlock = NULL; Address nextBlockAddr; @@ -1268,7 +1266,7 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { // NB "cur" hasn't ended, so its range may // not look like it overlaps with nextBlock - _pcb.overlapping_blocks(cur,nextBlock); + _pcb->overlapping_blocks(cur,nextBlock); tie(nextBlockAddr,nextBlock) = get_next_block(frame.curAddr, frame.codereg, _parse_data); @@ -1288,8 +1286,8 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { FILE__,__LINE__,func->_is_leaf_function, func->name().c_str()); if (!func->_is_leaf_function) func->_ret_addr = ret_addr; } - - _pcb.instruction_cb(func,cur,curAddr,&insn_det); + + _pcb->instruction_cb(func,cur,curAddr,&insn_det); if (isNopBlock && !ah.isNop()) { ah.retreat(); @@ -1377,15 +1375,15 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { } break; } else if (unlikely(func->obj()->defensiveMode())) { - if (!_pcb.hasWeirdInsns(func) && ah.isGarbageInsn()) { + if (!_pcb->hasWeirdInsns(func) && ah.isGarbageInsn()) { // add instrumentation at this addr so we can // extend the function if this really executes ParseCallback::default_details det( (unsigned char*) cur->region()->getPtrToInstruction(cur->lastInsnAddr()), cur->end() - cur->lastInsnAddr(), true); - _pcb.abruptEnd_cf(cur->lastInsnAddr(),cur,&det); - _pcb.foundWeirdInsns(func); + _pcb->abruptEnd_cf(cur->lastInsnAddr(),cur,&det); + _pcb->foundWeirdInsns(func); end_block(cur,ah); // allow invalid instructions to end up as a sink node. link(cur, _sink, DIRECT, true); @@ -1396,7 +1394,7 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { // as a no-op this time, allowing the subsequent // instruction to be parsed correctly mal_printf("Nop jump at %lx, changing it to nop\n",ah.getAddr()); - _pcb.patch_nop_jump(ah.getAddr()); + _pcb->patch_nop_jump(ah.getAddr()); unsigned bufsize = func->region()->offset() + func->region()->length() - ah.getAddr(); const unsigned char* bufferBegin = (const unsigned char *) @@ -1472,8 +1470,8 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { // calculate this after setting the function to PARSED, so that when // we finalize the function we'll actually save the results and won't // re-finalize it - func->tampersStack(); - _pcb.newfunction_retstatus( func ); + func->tampersStack(); + _pcb->newfunction_retstatus( func ); } } @@ -1569,11 +1567,11 @@ Parser::block_at( } else { ret = factory()._mkblock(owner,cr,addr); record_block(ret); - _pcb.addBlock(owner, ret); + _pcb->addBlock(owner, ret); } if(unlikely(inconsistent)) { - _pcb.overlapping_blocks(ret,inconsistent); + _pcb->overlapping_blocks(ret,inconsistent); } return ret; @@ -1689,7 +1687,7 @@ Parser::split_block( } } // KEVINTODO: study performance impact of this callback - _pcb.splitBlock(b,ret); + _pcb->splitBlock(b,ret); return ret; } @@ -1821,8 +1819,8 @@ Parser::link(Block *src, Block *dst, EdgeTypeEnum et, bool sink) e->_type._sink = sink; src->_trglist.push_back(e); dst->_srclist.push_back(e); - _pcb.addEdge(src, e, ParseCallback::target); - _pcb.addEdge(dst, e, ParseCallback::source); + _pcb->addEdge(src, e, ParseCallback::target); + _pcb->addEdge(dst, e, ParseCallback::source); return e; } @@ -1855,26 +1853,26 @@ Parser::relink(Edge * e, Block *src, Block *dst) bool addSrcAndDest = true; if(src != e->src()) { e->src()->removeTarget(e); - _pcb.removeEdge(e->src(), e, ParseCallback::target); + _pcb->removeEdge(e->src(), e, ParseCallback::target); e->_source = src; src->addTarget(e); - _pcb.addEdge(src, e, ParseCallback::target); + _pcb->addEdge(src, e, ParseCallback::target); addSrcAndDest = false; } if(dst != e->trg()) { if(e->trg() != _sink) { e->trg()->removeSource(e); - _pcb.removeEdge(e->trg(), e, ParseCallback::source); + _pcb->removeEdge(e->trg(), e, ParseCallback::source); addSrcAndDest = false; } e->_target = dst; dst->addSource(e); - _pcb.addEdge(dst, e, ParseCallback::source); + _pcb->addEdge(dst, e, ParseCallback::source); if (addSrcAndDest) { // We're re-linking a sinkEdge to be a non-sink edge; since // we don't inform PatchAPI of temporary sinkEdges, we have // to add both the source AND target edges - _pcb.addEdge(src, e, ParseCallback::target); + _pcb->addEdge(src, e, ParseCallback::target); } } @@ -1892,8 +1890,8 @@ Parser::frame_status(CodeRegion * cr, Address addr) void Parser::remove_func(Function *func) { - if (sorted_funcs.end() != sorted_funcs.find(func)) { - sorted_funcs.erase(func); + if (sorted_funcs->end() != sorted_funcs->find(func)) { + sorted_funcs->erase(func); } if (HINT == func->src()) { for (unsigned fidx=0; fidx < hint_funcs.size(); fidx++) { diff --git a/parseAPI/src/Parser.h b/parseAPI/src/Parser.h index 999b305d42..1acbc0b365 100644 --- a/parseAPI/src/Parser.h +++ b/parseAPI/src/Parser.h @@ -60,7 +60,7 @@ namespace ParseAPI { /** This is the internal parser **/ class Parser { // The CFG modifier needs to manipulate the lookup structures, - // which are internal Parser data. + // which are internal Parser data. friend class CFGModifier; private: Mutex finalize_lock; @@ -69,13 +69,13 @@ class Parser { CodeObject & _obj; // CFG object factory - CFGFactory & _cfgfact; + boost::shared_ptr _cfgfact; // Callback notifications - ParseCallbackManager & _pcb; + ParseCallbackManager * _pcb; // region data store - ParseData * _parse_data; + boost::shared_ptr _parse_data; // All allocated frames vector frames; @@ -89,7 +89,7 @@ class Parser { vector hint_funcs; vector discover_funcs; - set sorted_funcs; + boost::shared_ptr >sorted_funcs; // PLT, IAT entries dyn_hash_map plt_entries; @@ -110,7 +110,7 @@ class Parser { bool _in_finalize; public: - Parser(CodeObject & obj, CFGFactory & fact, ParseCallbackManager & pcb); + Parser(CodeObject &obj, boost::shared_ptr fact, ParseCallbackManager *pcb); ~Parser(); /** Initialization & hints **/ @@ -133,7 +133,7 @@ class Parser { void parse_at(Address addr, bool recursive, FuncSource src); void parse_edges(vector< ParseWorkElem * > & work_elems); - CFGFactory & factory() const { return _cfgfact; } + CFGFactory & factory() const { return *_cfgfact; } CodeObject & obj() { return _obj; } // removal diff --git a/parseAPI/src/ParserDetails.C b/parseAPI/src/ParserDetails.C index 436e848115..6ba003ebad 100644 --- a/parseAPI/src/ParserDetails.C +++ b/parseAPI/src/ParserDetails.C @@ -109,7 +109,7 @@ getBlockInsns(Block &blk, std::set
&addrs) (blk.obj()->cs()->getPtrToInstruction(blk.start())); InstructionDecoder dec = InstructionDecoder (bufferBegin, bufSize, blk.region()->getArch()); - InstructionAdapter_t ah(dec, blk.start(), blk.obj(), blk.region(), blk.obj()->cs(), &blk); + InstructionAdapter_t ah(dec, blk.start(), blk.obj(), blk.region(), blk.obj()->cs().get(), &blk); for (; ah.getAddr() < blk.end(); ah.advance()) { addrs.insert(ah.getAddr()); @@ -126,7 +126,7 @@ Parser::getTamperAbsFrame(Function *tamperFunc) // get the binary's load address and subtract it - CodeSource *cs = tamperFunc->obj()->cs(); + auto cs = tamperFunc->obj()->cs(); set targRegs; Address loadAddr = cs->loadAddress(); @@ -282,7 +282,7 @@ Parser::tamper_post_processing(vector & work, ParseFrame *pf) { Address objLoad = 0; CodeObject *targObj = NULL; - if (_pcb.absAddr(pf->func->_tamper_addr, + if (_pcb->absAddr(pf->func->_tamper_addr, objLoad, targObj)) { @@ -294,7 +294,7 @@ Parser::tamper_post_processing(vector & work, ParseFrame *pf) init_frame(*tf); frames.push_back(tf); _parse_data->record_frame(tf); - _pcb.updateCodeBytes(pf->func->_tamper_addr - objLoad); + _pcb->updateCodeBytes(pf->func->_tamper_addr - objLoad); } if (tf) { mal_printf("adding TAMPER_ABS target %lx frame\n", @@ -348,7 +348,7 @@ void Parser::ProcessUnresBranchEdge( det.data.unres.dynamic = false; det.data.unres.absolute_address = false; } - _pcb.interproc_cf(frame.func,cur,ah.getAddr(),&det); + _pcb->interproc_cf(frame.func,cur,ah.getAddr(),&det); } /* @@ -369,7 +369,7 @@ void Parser::ProcessReturnInsn( det.isize = ah.getSize(); det.type = ParseCallback::interproc_details::ret; - _pcb.interproc_cf(frame.func, cur, ah.getAddr(),&det); + _pcb->interproc_cf(frame.func, cur, ah.getAddr(),&det); } @@ -404,7 +404,7 @@ void Parser::ProcessCallInsn( else det.type = ParseCallback::interproc_details::branch_interproc; - _pcb.interproc_cf(frame.func,cur,ah.getAddr(),&det); + _pcb->interproc_cf(frame.func,cur,ah.getAddr(),&det); } void Parser::ProcessCFInsn( @@ -478,7 +478,7 @@ void Parser::ProcessCFInsn( (unsigned char*) cur->region()->getPtrToInstruction(cur->lastInsnAddr()), cur->end() - cur->lastInsnAddr(), true); - _pcb.abruptEnd_cf(cur->lastInsnAddr(),cur,&det); + _pcb->abruptEnd_cf(cur->lastInsnAddr(),cur,&det); } } @@ -595,7 +595,7 @@ void Parser::ProcessCFInsn( || COND_TAKEN == curEdge->second) { - _pcb.updateCodeBytes(curEdge->first); + _pcb->updateCodeBytes(curEdge->first); } } } diff --git a/parseAPI/src/ProbabilisticParser.C b/parseAPI/src/ProbabilisticParser.C index bf3dfded55..1bd415c04d 100644 --- a/parseAPI/src/ProbabilisticParser.C +++ b/parseAPI/src/ProbabilisticParser.C @@ -309,7 +309,7 @@ const IdiomPrefixTree::ChildrenType* IdiomPrefixTree::getChildrenByEntryID(unsig const IdiomPrefixTree::ChildrenType* IdiomPrefixTree::getWildCardChildren() { return getChildrenByEntryID(WILDCARD_ENTRY_ID); } -ProbabilityCalculator::ProbabilityCalculator(CodeRegion *reg, CodeSource *source, Parser* p, string model_spec): +ProbabilityCalculator::ProbabilityCalculator(CodeRegion *reg, boost::shared_ptr source, Parser* p, string model_spec): model(model_spec), cr(reg), cs(source), parser(p) { } diff --git a/parseAPI/src/ProbabilisticParser.h b/parseAPI/src/ProbabilisticParser.h index a5ea563991..57107753d9 100644 --- a/parseAPI/src/ProbabilisticParser.h +++ b/parseAPI/src/ProbabilisticParser.h @@ -161,7 +161,7 @@ class ProbabilityCalculator { IdiomModel model; CodeRegion* cr; - CodeSource* cs; + boost::shared_ptr cs; Parser* parser; // The probability of each address to be FEP dyn_hash_map FEPProb; @@ -197,7 +197,7 @@ class ProbabilityCalculator { public: - ProbabilityCalculator(CodeRegion *reg, CodeSource *source, Parser *parser, std::string model_spec); + ProbabilityCalculator(CodeRegion *reg, boost::shared_ptr source, Parser *parser, std::string model_spec); virtual ~ProbabilityCalculator() { FEPProb.clear(); reachingProb.clear(); diff --git a/patchAPI/h/PatchObject.h b/patchAPI/h/PatchObject.h index a8a1eadb29..302b81a9b7 100644 --- a/patchAPI/h/PatchObject.h +++ b/patchAPI/h/PatchObject.h @@ -49,7 +49,7 @@ class PATCHAPI_EXPORT PatchObject { friend class PatchParseCallback; public: - static PatchObject* create(ParseAPI::CodeObject* co, Address base, + static PatchObject* create(boost::shared_ptr co, Address base, CFGMaker* cm = NULL, PatchCallback *cb = NULL); @@ -70,7 +70,7 @@ class PATCHAPI_EXPORT PatchObject { Address codeBase() const { return codeBase_; } Address codeOffsetToAddr(Address offset) const; Address addrMask() const; - ParseAPI::CodeObject* co() const { return co_; } + boost::shared_ptr co() const { return co_; } //ParseAPI::CodeSource* cs() const { return cs_; } AddrSpace* addrSpace() const { return addr_space_; } void setAddrSpace(AddrSpace* as); @@ -105,7 +105,7 @@ class PATCHAPI_EXPORT PatchObject { protected: - ParseAPI::CodeObject* co_; + boost::shared_ptr co_; Address codeBase_; AddrSpace* addr_space_; FuncMap funcs_; @@ -113,7 +113,7 @@ class PATCHAPI_EXPORT PatchObject { EdgeMap edges_; CFGMaker* cfg_maker_; - PatchObject(ParseAPI::CodeObject* o, Address a, CFGMaker* cm, PatchCallback *cb = NULL); + PatchObject(boost::shared_ptr o, Address a, CFGMaker* cm, PatchCallback *cb = NULL); PatchObject(const PatchObject* par_obj, Address a, CFGMaker* cm, PatchCallback *cb = NULL); void copyCFG(PatchObject* par_obj); bool splitBlock(PatchBlock *first, ParseAPI::Block *second); diff --git a/patchAPI/src/AddrSpace.C b/patchAPI/src/AddrSpace.C index 05d327b6d4..c46686ac10 100644 --- a/patchAPI/src/AddrSpace.C +++ b/patchAPI/src/AddrSpace.C @@ -59,7 +59,7 @@ AddrSpace::create(PatchObject* obj) { bool AddrSpace::loadObject(PatchObject* obj) { - obj_map_[obj->co()] = obj; + obj_map_[obj->co().get()] = obj; obj->setAddrSpace(this); return true; } diff --git a/patchAPI/src/ParseCallback.C b/patchAPI/src/ParseCallback.C index c6ece25302..053fbf8adb 100644 --- a/patchAPI/src/ParseCallback.C +++ b/patchAPI/src/ParseCallback.C @@ -216,7 +216,7 @@ bool PatchParseCallback::absAddr(Address absolute, AddrSpace::ObjMap::iterator oit = objs.begin(); for (; oit != objs.end(); oit++) { if (absolute > oit->second->codeBase()) { - ParseAPI::CodeSource *cs = oit->first->cs(); + auto cs = oit->first->cs(); set regs; cs->findRegions(absolute - oit->second->codeBase(), regs); if (1 == regs.size()) { diff --git a/patchAPI/src/PatchModifier.C b/patchAPI/src/PatchModifier.C index a126d2aa0b..b1607d68a2 100644 --- a/patchAPI/src/PatchModifier.C +++ b/patchAPI/src/PatchModifier.C @@ -130,7 +130,7 @@ PatchBlock *PatchModifier::split(PatchBlock *block, Address addr, bool trust, Ad } InsertedCode::Ptr PatchModifier::insert(PatchObject *obj, void *start, unsigned size, Address base) { - ParseAPI::CodeObject *co = obj->co(); + auto co = obj->co(); ParseAPI::InsertedRegion *newRegion = ParseAPI::CFGModifier::insert(co, base, start, size); @@ -176,7 +176,7 @@ InsertedCode::Ptr PatchModifier::insert(PatchObject *obj, void *start, unsigned } InsertedCode::Ptr PatchModifier::insert(PatchObject *obj, void *start, unsigned size) { - ParseAPI::CodeObject *co = obj->co(); + auto co = obj->co(); Address base = co->getFreeAddr(); return insert(obj, start, size, base); } @@ -185,7 +185,7 @@ InsertedCode::Ptr PatchModifier::insert(PatchObject *obj, void *start, unsigned InsertedCode::Ptr PatchModifier::insert(PatchObject *obj, SnippetPtr snip, Point *p) { if (!snip) return InsertedCode::Ptr(); - ParseAPI::CodeObject *co = obj->co(); + auto co = obj->co(); Address base = co->getFreeAddr(); Buffer buf(base, 1024); diff --git a/patchAPI/src/PatchObject.C b/patchAPI/src/PatchObject.C index c8230a3bba..aa8e200db8 100644 --- a/patchAPI/src/PatchObject.C +++ b/patchAPI/src/PatchObject.C @@ -42,7 +42,7 @@ using namespace PatchAPI; PatchObject* -PatchObject::create(ParseAPI::CodeObject* co, Address base, CFGMaker* cm, PatchCallback *cb) { +PatchObject::create(boost::shared_ptr co, Address base, CFGMaker* cm, PatchCallback *cb) { patchapi_debug("Create PatchObject at %lx", base); PatchObject* obj = new PatchObject(co, base, cm, cb); return obj; @@ -56,7 +56,7 @@ PatchObject::clone(PatchObject* par_obj, Address base, CFGMaker* cm, PatchCallba return obj; } -PatchObject::PatchObject(ParseAPI::CodeObject* o, Address a, CFGMaker* cm, PatchCallback *cb) +PatchObject::PatchObject(boost::shared_ptr o, Address a, CFGMaker* cm, PatchCallback *cb) : co_(o), codeBase_(a), addr_space_(NULL), cfg_maker_(NULL) @@ -116,7 +116,9 @@ PatchObject::~PatchObject() { for (EdgeMap::iterator iter = edges_.begin(); iter != edges_.end(); ++iter) { delete iter->second; } - co_->unregisterCallback(pcb_); + if(co_) { + co_->unregisterCallback(pcb_); + } delete cfg_maker_; delete cb_; } @@ -143,7 +145,7 @@ PatchFunction* PatchObject::getFunc(ParseAPI::Function *f, bool create) { if (!f) return NULL; - if (co_ != f->obj()) { + if (co_.get() != f->obj()) { cerr << "ERROR: function " << f->name() << " doesn't exist in this object!\n"; assert(0); } @@ -186,7 +188,7 @@ void PatchObject::createBlocks() { PatchBlock* PatchObject::getBlock(ParseAPI::Block* b, bool create) { - if (co_ != b->obj()) { + if (co_.get() != b->obj()) { cerr << "ERROR: block starting at 0x" << b->start() << " doesn't exist in this object!\n"; cerr << "This: " << hex << this << " and our code object: " << co_ << " and block is " << b->obj() << dec << endl; @@ -294,7 +296,7 @@ bool PatchObject::splitBlock(PatchBlock * /*orig*/, ParseAPI::Block *second) { } std::string PatchObject::format() const { - ParseAPI::CodeSource *cs = co()->cs(); + ParseAPI::CodeSource *cs = co()->cs().get(); ParseAPI::SymtabCodeSource *symtab = dynamic_cast(cs); stringstream ret;