/// \brief Swap two elements in the array. /// void swap(std::size_t IndexA, std::size_t IndexB) { assert((IndexA < ElementCount) && (IndexB < ElementCount)); if (IndexA == IndexB) return; auto const ElemA = getElement(IndexA); auto const ElemB = getElement(IndexB); char TempValue[ElementSize]; memcpy(TempValue, ElemA, ElementSize); memcpy(ElemA, ElemB, ElementSize); memcpy(ElemB, TempValue, ElementSize); // Copy all in-memory pointer object tracking, in case the elements we are // moving are pointers (or contain pointers). auto const AddrOfA = reinterpret_cast<uintptr_t>(ElemA); auto const AddrOfB = reinterpret_cast<uintptr_t>(ElemB); auto const AddrOfT = reinterpret_cast<uintptr_t>(TempValue); ProcessListener.copyInMemoryPointerObjects(AddrOfA, AddrOfT, ElementSize); ProcessListener.copyInMemoryPointerObjects(AddrOfB, AddrOfA, ElementSize); ProcessListener.copyInMemoryPointerObjects(AddrOfT, AddrOfB, ElementSize); ProcessListener.clearInMemoryPointerObjects(MemoryArea(AddrOfT, ElementSize)); // Create a new thread time for this "step" of the sort, and record the // updated memory states. ThreadListener.incrementThreadTime(); ThreadListener.recordUntypedState(ElemA, ElementSize); ThreadListener.recordUntypedState(ElemB, ElementSize); }
TraceMemoryAllocation const & TraceMemoryState::getAllocationContaining(uintptr_t const Address, std::size_t const Length) const { auto AllocPtr = getAllocationAtOrPreceding(Address); assert(AllocPtr->getArea().contains(MemoryArea(Address, Length))); return *AllocPtr; }
/// \brief Find the Alloca that covers the given address, or nullptr if none /// exists. /// AllocaState const *getAllocaContaining(stateptr_ty Address) const { for (auto const &Alloca : Allocas) { auto const Area = MemoryArea(Alloca.getAddress(), Alloca.getTotalSize()); if (Area.contains(Address)) return &Alloca; } return nullptr; }
void FunctionState::addByValArea(unsigned ArgumentNumber, stateptr_ty Address, std::size_t Size) { auto const Fn = getFunction(); assert(ArgumentNumber < Fn->arg_size()); auto ArgIt = Fn->arg_begin(); std::advance(ArgIt, ArgumentNumber); ParamByVals.emplace_back(&*ArgIt, MemoryArea(Address, Size)); }
seec::Maybe<MemoryArea> FunctionState::getContainingMemoryArea(stateptr_ty Address) const { auto const Alloca = getAllocaContaining(Address); if (Alloca) return MemoryArea(Alloca->getAddress(), Alloca->getTotalSize()); for (auto const &ParamByVal : ParamByVals) if (ParamByVal.getArea().contains(Address)) return ParamByVal.getArea(); return seec::Maybe<MemoryArea>(); }
typename std::enable_if <std::is_pointer<T>::value && !std::is_void<typename std::remove_pointer<T>::type>::value, seec::Maybe<MemoryArea>>::type getArgumentPointee(detect_calls::VarArgList<TraceThreadListener> const &Args, unsigned ArgIndex) const { if (ArgIndex < Args.size()) { auto MaybeArg = Args.getAs<T>(ArgIndex); if (MaybeArg.assigned()) { auto const Ptr = MaybeArg.template get<0>(); return MemoryArea(Ptr, sizeof(*Ptr)); } } return seec::Maybe<MemoryArea>(); }
/// \brief Get a copy of this MemoryArea with a new Length. MemoryArea withLength(std::size_t Length) const { return MemoryArea(start(), Length, Access); }
MemoryArea Process::memory(void* address, SIZE_T size) { return MemoryArea(*this, address, size, false); }
MemoryStateRegion AllocaState::getMemoryRegion() const { auto &Thread = Parent->getParent(); auto &Process = Thread.getParent(); auto &Memory = Process.getMemory(); return Memory.getRegion(MemoryArea(Address, getTotalSize())); }
/// Get the memory area occupied by this function's stack-allocated variables. /// This method is thread safe. MemoryArea getStackArea() const { std::lock_guard<std::mutex> Lock(StackMutex); return MemoryArea(StackLow, (StackHigh - StackLow) + 1); }
/// Get the memory area occupied by this alloca. MemoryArea area() const { return MemoryArea(Address, ElementSize * ElementCount); }