//Groups: @ingroup\s+(API_REF|KNOBS|IMG_BASIC_API|INS_BASIC_API|INS_INST_API|INS_BASIC_API_GEN_IA32|INS_BASIC_API_IA32|INS_MOD_API_GEN_IA32|SEC_BASIC_API|RTN_BASIC_API|REG_BASIC_API|REG_CPU_GENERIC|REG_CPU_IA32|TRACE_BASIC_API|BBL_BASIC_API|SYM_BASIC_API|MISC_PRINT|MISC_PARSE|KNOB_API|KNOB_BASIC|KNOB_PRINT|LOCK|PIN_CONTROL|TRACE_VERSION_API|BUFFER_API|PROTO_API|PIN_PROCESS_API|PIN_THREAD_API|PIN_SYSCALL_API|WINDOWS_SYSCALL_API_UNDOC|DEBUG_API|ERROR_FILE_BASIC|TYPE_BASE|INSTLIB|ALARM|CHILD_PROCESS_API|UTILS|MISC|CONTEXT_API|PHYSICAL_CONTEXT_API|PIN_CALLBACKS|EXCEPTION_API|APPDEBUG_API|STOPPED_THREAD_API|BUFFER_API|PROTO|INST_ARGS|DEPRECATED_PIN_API|INTERNAL_EXCEPTION_PRIVATE_UNDOCUMENTED|PIN_THREAD_PRIVATE|CHILD_PROCESS_INTERNAL|BBL_BASIC|ROGUE_BASIC_API|MESSAGE_TYPE|MESSAGE_BASIC|ERRFILE|MISC_BASIC|ITC_INST_API|CONTEXT_API_UNDOC|EXCEPTION_API_UNDOC|UNDOCUMENTED_PIN_API|OPIN|TRACE_VERSIONS /* PIN API */ /* THIS FILE IS AUTOMAGICALLY GENERATED - DO NOT CHANGE DIRECTLY*/ class COMMAND_LINE_ARGUMENTS { public: /*! * Empty Constructor */ COMMAND_LINE_ARGUMENTS() { Enter(0, NULL, NULL); } /*! * Constructor. Construct an object from argc, argv and delimiter * Example1: argc = 6, argv = {ab bc cd de ef de}, delimiter = "de" * => the object will contain: * argc = 4, argv = {ab bc cd de} * Example2: argc = 6, argv = {ab bc cd de ef de}, delimiter = NULL * => the object will contain: * argc = 6, argv = {ab bc cd de ef de} * Example3: argc = 6, argv = {ab bc cd de ef de}, delimiter = "fg" * => the object will contain: * argc = 6, argv = {ab bc cd de ef de} * * @param[in] argc argc for the command line arguments object * @param[in] argv argv for the command line arguments object * @param[in] delimiter remove any argv argument AFTER the delimiter. * If it was not found, nothing will be removed */ COMMAND_LINE_ARGUMENTS(INT argc, const CHAR * const * argv, const CHAR * delimiter = NULL) { Enter(argc, argv, delimiter); } /*! * Constructor. Construct an object from a string using MS CRT Parsing rules * (For more details see GetCmdArg() documentation) * * NOTE: Use this function only for original application's command line * * @param[in] commandLine original application's command line represented as string */ COMMAND_LINE_ARGUMENTS(const std::string & commandLine) { Enter(commandLine); } /*! * Copy Constructor. Construct an object from another object * * @param[in] source source object */ COMMAND_LINE_ARGUMENTS(const COMMAND_LINE_ARGUMENTS & source) { Enter(source.m_argc, source.m_argv, NULL); } /*! * Assignment operator * * @param[in] source source object * * @return reference to current object */ COMMAND_LINE_ARGUMENTS & operator= (const COMMAND_LINE_ARGUMENTS & source) { //Avoid self assignment if(this != &source) { Clean(); Enter(source.m_argc, source.m_argv, NULL); } return *this; } /*! * Insert a set of command line arguments into this set of arguments. * * @param[in] args Arguments to be inserted. * @param[in] pos Arguments are inserted before the argument with this position. * If \a pos is -1, they are appended to the end. * * @return reference to current object */ COMMAND_LINE_ARGUMENTS & Insert (const COMMAND_LINE_ARGUMENTS & right, INT pos = -1); /*! * Insert a single argument into this set of arguments. * * @param[in] arg Argument to be inserted. * @param[in] pos The argument is inserted before the argument with this position. * If \a pos is -1, it is appended to the end. * * @return reference to current object */ COMMAND_LINE_ARGUMENTS & Insert (const std::string & arg, INT pos = -1); /*! * Insert a single argument into this set of arguments. * Don't try to tokenize (split) the added argument to several arguments. * * @param[in] arg Argument to be inserted. * @param[in] pos The argument is inserted before the argument with this position. * If \a pos is -1, it is appended to the end. * * @return reference to current object */ COMMAND_LINE_ARGUMENTS & InsertAsOneToken (const std::string & arg, INT pos = -1); /*! * Find an argument by name * * @param[in] argStr - argument to be found * * @return index of argument or -1 if not found */ INT FindArgument(const std::string& argStr) const; /*! * Looks for argument equal to argStr; remove "numOfArgs" arguments starting from the found argument * * @param[in] argStr - argument to be found, * @param[in] numOfArgs - numer of arguments that should be removed starting from the found argument * * @return TRUE if numOfArgs were removed from the list */ BOOL RemoveArguments(const std::string& argStr, INT numOfArgs); /*! * @return Argc of current object * the value life time is as long as the object was not changed * (using operator=(), Insert() or ~COMMAND_LINE_ARGUMENTS() will invalidate this data) */ INT Argc() const { return m_argc; } /*! * @return Argv of current object, * the pointer life time is as long as the object was not changed * (using operator=(), Insert() or ~COMMAND_LINE_ARGUMENTS() will invalidate this data) */ const CHAR * const * Argv() const { return m_argv; } /*! * @return string with all command line arguments separated with \" \" */ std::string String() const; /*! * Destructor */ ~COMMAND_LINE_ARGUMENTS() { Clean(); } private: /*! * Initialize the object using argc, argv and delimiter */ BOOL Enter(INT argc, const CHAR * const * argv, const CHAR * delimiter); /*! * Initialize the object using commandLine string */ BOOL Enter(const std::string & commandLine); /*! * Deallocate all resources used by current object */ BOOL Clean(); /*! * Find array size using argc, argv and delimiter */ INT FindArraySize(INT argc, const CHAR * const * argv, const CHAR * delimiter); /*! * Remove argument by index (0 <= index < m_argc) */ VOID RemoveArgument(INT index); private: INT m_argc; //!< size of argv array CHAR ** m_argv; //!< CHAR* array }; /* DO NOT EDIT */ extern VOID SetAddress0x(BOOL val); /* DO NOT EDIT */ extern BOOL CharIsSpace(CHAR c); /* DO NOT EDIT */ extern CHAR CharToUpper(CHAR c); /* DO NOT EDIT */ extern std::string ptrstr(const VOID *val ); /* DO NOT EDIT */ extern std::string StringFromAddrint( ADDRINT l); /* DO NOT EDIT */ extern std::string StringFromUint64( UINT64 l); /* DO NOT EDIT */ extern std::string StringDec( UINT64 l, UINT32 digits, CHAR padding); /* DO NOT EDIT */ extern std::string StringDecSigned( INT64 l, UINT32 digits, CHAR padding); /* DO NOT EDIT */ extern std::string StringBignum( INT64 l, UINT32 digits, CHAR padding); /* DO NOT EDIT */ extern std::string Reformat(const std::string& s, const std::string& prefix, UINT32 min_line, UINT32 max_line); /* DO NOT EDIT */ extern std::string StringHex32( UINT32 l, UINT32 digits, BOOL prefix_0x); /* DO NOT EDIT */ extern std::string StringBool(BOOL b); /* DO NOT EDIT */ extern std::string StringTri(TRI t); /* DO NOT EDIT */ extern INT32 Int32FromString(const std::string& s); /* DO NOT EDIT */ extern UINT32 Uint32FromString(const std::string& s); /* DO NOT EDIT */ extern INT64 Int64FromString(const std::string& s); /* DO NOT EDIT */ extern UINT64 Uint64FromString(const std::string& s); /* DO NOT EDIT */ extern FLT64 FLT64FromString(const std::string& s); /* DO NOT EDIT */ extern INT CharToHexDigit(CHAR c); /* DO NOT EDIT */ extern ADDRINT AddrintFromString(const std::string& str); /* DO NOT EDIT */ extern std::string ReadLine(std::istream& inputFile, UINT32 *lineNum); /* DO NOT EDIT */ extern UINT32 Tokenize(const std::string& line, std::string *array, UINT32 n); /* DO NOT EDIT */ inline std::string StringHex( UINT32 l, UINT32 digits, BOOL prefix_0x = TRUE) {return StringHex32(l, digits, prefix_0x);} /* DO NOT EDIT */ inline std::string decstr(INT64 val, UINT32 width=0 ) {return StringDecSigned(val,width,' ');} /* DO NOT EDIT */ inline std::string decstr(INT32 val, UINT32 width=0 ) {return StringDecSigned(val,width,' ');} /* DO NOT EDIT */ inline std::string decstr(INT16 val, UINT32 width=0 ) {return StringDecSigned(val,width,' ');} /* DO NOT EDIT */ inline std::string decstr(UINT64 val, UINT32 width=0 ) {return StringDec(val,width,' ');} /* DO NOT EDIT */ inline std::string decstr(UINT32 val, UINT32 width=0 ) {return StringDec(val,width,' ');} /* DO NOT EDIT */ inline std::string decstr(UINT16 val, UINT32 width=0 ) {return StringDec(val,width,' ');} /* DO NOT EDIT */ inline std::string hexstr(INT64 val, UINT32 width=0 ) { std::string ostr; #if defined(_MSC_VER) && _MSC_VER >= 1400 ostr = StringHex( INT32((val >> 16) >> 16), width); #else ostr = StringHex( INT32(val >> 32), width); #endif ostr += StringHex( UINT32(val), 8, FALSE); return ostr; } /* DO NOT EDIT */ inline std::string hexstr(INT32 val, UINT32 width=0 ) {return StringHex(INT32(val),width);} /* DO NOT EDIT */ inline std::string hexstr(INT16 val, UINT32 width=0 ) {return StringHex(INT32(val),width);} /* DO NOT EDIT */ inline std::string hexstr(UINT64 val, UINT32 width=0 ) { std::string ostr; #if defined(_MSC_VER) && _MSC_VER >= 1400 ostr = StringHex( UINT32((val >> 16) >> 16), width); #else ostr = StringHex( UINT32(val >> 32), width); #endif ostr += StringHex( UINT32(val), 8, FALSE); return ostr; } /* DO NOT EDIT */ inline std::string hexstr(VOID *p, UINT32 width=0 ) { #if defined(HOST_IA32E) UINT64 val = reinterpret_cast(p); return hexstr(val,width); #else UINT32 val = reinterpret_cast(p); return StringHex(val,width); #endif } /* DO NOT EDIT */ inline std::string hexstr(const VOID *p, UINT32 width=0 ) { #if defined(HOST_IA32E) UINT64 val = reinterpret_cast(p); return hexstr(val,width); #else UINT32 val = reinterpret_cast(p); return StringHex(val,width); #endif } /* DO NOT EDIT */ inline std::string hexstr(UINT32 val, UINT32 width=0 ) {return StringHex(UINT32(val),width);} /* DO NOT EDIT */ inline std::string hexstr(UINT16 val, UINT32 width=0 ) {return StringHex(UINT32(val),width);} /* DO NOT EDIT */ inline std::string ljstr(const std::string& s, UINT32 width, CHAR padding = ' ') { std::string ostr(width,padding); ostr.replace(0,s.length(),s); return ostr; } /* DO NOT EDIT */ struct DECSTR { DECSTR(UINT32 width = 0) :_w(width){} template std::string operator() (const T & t) const {return decstr(t,_w);} UINT32 _w; }; /* DO NOT EDIT */ struct HEXSTR { HEXSTR(UINT32 width = 0) :_w(width){} template std::string operator() (const T & t) const {return hexstr(t,_w);} UINT32 _w; }; /* DO NOT EDIT */ template std::string StringSequence(ITER begin, ITER end, const CONV & conv, const std::string & delimiter = std::string(" ")) { std::string str; for (ITER it = begin; it != end; ++it) { if (it != begin) {str += delimiter;} str += conv(*it); } return str; } /* DO NOT EDIT */ extern UINT32 BitCount(ADDRINT val); /* DO NOT EDIT */ inline VOID * Addrint2VoidStar(ADDRINT addr) { #if defined(HOST_IA32E) && defined(TARGET_IA32) ASSERT(false,"Should not be called in cross environment\n"); return 0; #else return reinterpret_cast(addr); #endif } /* DO NOT EDIT */ inline ADDRINT VoidStar2Addrint(const VOID * addr) { #if defined(HOST_IA32E) && defined(TARGET_IA32) ASSERT(false,"Should not be called in cross environment\n"); return 0; #else return reinterpret_cast(addr); #endif } /* DO NOT EDIT */ inline ADDRINT VoidStar2Addrint(VOID * addr) { #if defined(HOST_IA32E) && defined(TARGET_IA32) ASSERT(false,"Should not be called in cross environment\n"); return 0; #else return reinterpret_cast(addr); #endif } /* DO NOT EDIT */ template BOOL IsPowerOf2(T value) { return ((value & (value - 1)) == 0); } /* DO NOT EDIT */ template T RoundToNextPower2(T value) { //This algorithm rounds up to the next power of 2 by setting all the significant digits //of the number in binary representation to 1. The rest of the digits are set to be 0. //It increments the number, thus getting the next power of two. This handles all numbers //that aren't powers of two. To handle the case of powers of two, 1 is decremented from //the number before the process begins. This makes no difference if the number is not a //power of 2, and when it is it makes sure we get the same power of two we had before. //For details see "http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2" T width = sizeof(T)*8; //bit width --value; for (T i=1; i < width; i <<= 1) //runs log2(width) times { value = (value | value >> i); //Turn i^2 bytes to 1. } ++value; return value; } /* DO NOT EDIT */ template T RoundUp(T value, size_t alignment) { if (alignment == 0) { return value; } value += alignment - 1; value /= alignment; value *= alignment; return value; } /* DO NOT EDIT */ template T * RoundUp(T * ptr, size_t alignment) { return (reinterpret_cast(RoundUp(reinterpret_cast(ptr), alignment))); } /* DO NOT EDIT */ template T RoundUpPowerOf2(T value, size_t alignment) { if (alignment == 0) return value; T align_1 = static_cast(alignment - 1); ASSERTX((alignment & align_1) == 0); return ((value + align_1) & ~align_1); } /* DO NOT EDIT */ template T * RoundUpPowerOf2(T * ptr, size_t alignment) { return (reinterpret_cast(RoundUpPowerOf2(reinterpret_cast(ptr), alignment))); } /* DO NOT EDIT */ template T RoundDown(T value, size_t alignment) { if (alignment == 0) { return value; } value /= alignment; value *= alignment; return value; } /* DO NOT EDIT */ template T * RoundDown(T * ptr, size_t alignment) { return (reinterpret_cast(RoundDown(reinterpret_cast(ptr), alignment))); } /* DO NOT EDIT */ template T RoundDownPowerOf2(T value, size_t alignment) { if (alignment == 0) return value; T align_1 = static_cast(alignment - 1); ASSERTX((alignment & align_1) == 0); return (value & ~align_1); } /* DO NOT EDIT */ template T * RoundDownPowerOf2(T * ptr, size_t alignment) { return (reinterpret_cast(RoundDownPowerOf2(reinterpret_cast(ptr), alignment))); } /* DO NOT EDIT */ template ADDRINT PointerToInt(const T *ptr) { #if (defined(HOST_IA32) && !defined(TARGET_IA32)) || (defined(HOST_IA32E) && !defined(TARGET_IA32E)) ASSERT(false,"Should not be called in cross environment\n"); return 0; #else return reinterpret_cast(ptr); #endif } /* DO NOT EDIT */ template T *IntToPointer(ADDRINT addr) { #if (defined(HOST_IA32) && !defined(TARGET_IA32)) || (defined(HOST_IA32E) && !defined(TARGET_IA32E)) ASSERT(false,"Should not be called in cross environment\n"); return 0; #else return reinterpret_cast(addr); #endif } /* DO NOT EDIT */ inline INT64 VoidStar2Int(VOID * addr) { #if defined(HOST_IA32E) && defined(TARGET_IA32) ASSERT(false,"Should not be called in cross environment\n"); return 0; #else return reinterpret_cast(addr); #endif } /* DO NOT EDIT */ inline BOOL UnsignedImmediateFits(const UINT64 value, const UINT32 bits) { return 0 == (value>>bits); } /* DO NOT EDIT */ inline void RangeCheck(const UINT32 value, const UINT32 bits) { ASSERT (UnsignedImmediateFits(value, bits), decstr(bits) + "-bit range overflow in " + hexstr(value) + "\n"); } /* DO NOT EDIT */ extern BOOL SignedImmediateFits(const INT64 value, const UINT32 origSize, const UINT32 extendedSize); /* DO NOT EDIT */ inline BOOL SignedImmediateFits(const INT64 value, const UINT32 origSize) { return SignedImmediateFits(value, origSize, 8 * sizeof(ADDRINT)); } /* DO NOT EDIT */ extern BOOL HasBaseName(const char *fileName, const char *baseNameToCheckFor); /* DO NOT EDIT */ inline INT32 MEMORY_ReadInt32(ADDRINT address) { return *reinterpret_cast(address); } /* DO NOT EDIT */ inline VOID MEMORY_WriteInt32(ADDRINT address, INT32 value) { *reinterpret_cast(address) = value; } /* DO NOT EDIT */ inline UINT32 MEMORY_ReadUint32(ADDRINT address) { return *reinterpret_cast(address); } /* DO NOT EDIT */ inline VOID MEMORY_WriteUint32(ADDRINT address, UINT32 value) { *reinterpret_cast(address) = value; } /* DO NOT EDIT */ inline INT64 MEMORY_ReadInt64(ADDRINT address) { return *reinterpret_cast(address); } /* DO NOT EDIT */ inline VOID MEMORY_WriteInt64(ADDRINT address, INT64 value) { *reinterpret_cast(address) = value; } /* DO NOT EDIT */ inline UINT64 MEMORY_ReadUint64(ADDRINT address) { return *reinterpret_cast(address); } /* DO NOT EDIT */ inline VOID MEMORY_WriteUint64(ADDRINT address, UINT32 value) { *reinterpret_cast(address) = value; } /* DO NOT EDIT */ extern ADDRINT GetPageOfAddr(ADDRINT addr); /* DO NOT EDIT */ extern ADDRINT ProgramEntry(const ImageLoaderInfo * mainImage, const ImageLoaderInfo * loader); /* DO NOT EDIT */ extern std::string Joinpath(std::string s1, std::string s2); /* DO NOT EDIT */ extern std::string Basename(const std::string& path); /* DO NOT EDIT */ extern CHAR* CreateTmpFileName(const CHAR* fnameTemplate, const UINT32 fnameTemplateSize); /* DO NOT EDIT */ extern const VOID * GetSp(); /* DO NOT EDIT */ inline size_t PtrDiff(const VOID * ptr1, const VOID * ptr2) { return (reinterpret_cast(ptr1) - reinterpret_cast(ptr2)); } /* DO NOT EDIT */ inline VOID * PtrAtOffset(VOID * ptr, size_t offset) { return (reinterpret_cast(ptr) + offset); } /* DO NOT EDIT */ inline const VOID * PtrAtOffset(const VOID * ptr, size_t offset) { return (reinterpret_cast(ptr) + offset); } /* DO NOT EDIT */ template T * PtrAtOffset(VOID * ptr, size_t offset) { return (reinterpret_cast(PtrAtOffset(ptr, offset))); } /* DO NOT EDIT */ template const T * PtrAtOffset(const VOID * ptr, size_t offset) { return (reinterpret_cast(PtrAtOffset(ptr, offset))); } /* DO NOT EDIT */ template VOID * PushDataToStack(VOID * stack, const T * data, size_t alignment = 1, size_t size = sizeof(T)) { stack = PtrAtOffset(stack, 0 - size); stack = RoundDown(stack , alignment); return memcpy(stack, data, size); } /* DO NOT EDIT */ inline VOID * PushAddrintToStack(VOID * stack, ADDRINT value) { stack = PtrAtOffset(stack, 0 - sizeof(ADDRINT)); *reinterpret_cast(stack) = value; return stack; } /* DO NOT EDIT */ class MemRange { public: //======= Constructors //Default constructor MemRange(): m_base(NULL), m_size(0) {} //Construct range with a given base address and size MemRange(VOID * base, size_t size) : m_base(base), m_size(size) {} MemRange(ADDRINT base, size_t size) : m_base(Addrint2VoidStar(base)), m_size(size) {} //Construct range with a given base and end addresses. //End address of a range is the address of the first byte following the range MemRange(VOID * base, VOID * end) : m_base(base), m_size(PtrDiff(end, base)) {} //Default copy constructor and assignment operator //======= operators == and != BOOL operator == (const MemRange & range) const { return ((m_base == range.m_base) && (m_size == range.m_size)); } BOOL operator != (const MemRange & range) const {return (!(*this == range));} //======= Accessors //Get/set base address of the range. VOID * Base() const {return m_base;} MemRange& Base(VOID * base) { m_base = base; return *this;} //Get/set size, in bytes, of the range. size_t Size() const {return m_size;} MemRange& Size(size_t size) { m_size = size; return *this;} //Get end address of the range. VOID * End() const {return PtrAtOffset(m_base, m_size);} //Get the last address of the non-empty range. VOID * Last() const {return PtrAtOffset(m_base, m_size - 1);} /* * Check to see whether this range is empty * * @return true, if this range is empty, otherwise - false */ BOOL IsEmpty() const {return (m_size == 0);} /* * Check to see whether this range contains the specified memory address * * @param[in] addr memory address, potentially contained in this range * * @return true, if this range contains the specified address, * otherwise - false */ BOOL Contains(const VOID * addr) const { return (PtrDiff(addr, m_base) < m_size); } /* * Check to see whether this range contains the specified memory range * * @param[in] range memory range, potentially contained in this range * * @return true, if this range contains the specified range, * otherwise - false. */ BOOL Contains(const MemRange & range) const { return (Contains(range.m_base) && !range.Contains(End())); } /* Check to see whether this range intersects with the specified memory range * * @param[in] range memory range, potentially intersecting with this range * * @return true, if this range intersects with the specified range * otherwise - false */ BOOL Intersects(const MemRange & range) const { return (Contains(range.m_base) || range.Contains(m_base)); } /* Check to see whether this range is adjacent to the specified memory range * * @param[in] range memory range, potentially adjacent to this range * * @return true, if this range is adjacent to the specified range * otherwise - false */ BOOL AdjacentTo(const MemRange & range) const { return (((range.m_base == End()) && (range.m_base != 0)) || ((m_base == range.End()) && (m_base != 0))); } /* Check to see whether the current stack pointer belongs to this range * * @return true, if current stack pointer belongs to this range * otherwise - false */ BOOL IsCurrentStack() const { return (Contains(GetSp())); } /* * Round base/end address of the range down/up according to specified alignment * * @param[in] alignment alignment value. Must be power of two. * * @return reference to aligned range. */ MemRange& Align(UINT32 alignment) { VOID * end = RoundUp(End(), alignment); m_base = RoundDown(m_base, alignment); m_size = PtrDiff(end, m_base); return *this; } /* * Round both base and end address of the range up according to specified alignment. * The size of the updated range is at least size the range before update. * @param[in] alignment alignment value. Must be power of two. * return reference to aligned range */ MemRange& AlignUp(UINT32 alignment) { m_base = RoundUp(m_base, alignment); m_size = RoundUp(m_size, alignment); return *this; } /* * Round both base and end address of the range down according to specified alignment. * The size of the updated range is at least size the range before update. * @param[in] alignment alignment value. Must be power of two. * @return reference to aligned range */ MemRange& AlignDown(UINT32 alignment) { VOID * end = RoundDown(End(), alignment); m_size = RoundUp(m_size, alignment); m_base = PtrAtOffset(end, 0 - m_size); return *this; } /* * Shift both base and end address of the range * @param[in] offset shift value. * @return reference to shifted range */ MemRange& Shift(size_t offset) { m_base = PtrAtOffset(m_base, offset); return *this; } /* * Shift base address of the range without changing the end address * If the base is shifted to be after the end address, then the region size * will be set to zero * @param[in] offset shift value. * @return reference to shifted range */ MemRange& ShiftBase(size_t offset) { VOID * end = End(); m_base = PtrAtOffset(m_base, offset); if (end < m_base) { m_size = 0; } else { m_size = PtrDiff(end, m_base); } return *this; } /* * Shift end address of the range without changing the base address * @param[in] offset shift value. * @return reference to shifted range */ MemRange& ShiftEnd(size_t offset) { m_size += offset; return *this; } /* * Extend boundaries of this range to include the specified range. * The new range is the minimal range that contains both ranges. * @param[in] range memory range, to be combined with this range * @return reference to updated range */ MemRange& Combine(const MemRange & range) { size_t size; if (range.m_base >= m_base) { size = PtrDiff(range.End(), m_base); } else { size = PtrDiff(End(), range.m_base); *this = range; } if (size > m_size) { m_size = size; } return *this; } /* * Decompose this range into three ranges (each of them may be empty): * @param[out] pIntersection - intersection of range with specified * @param[out] pLowDiff - part of range, that contains all addresses * lower than any address in the specified * @param[out] pHighDiff - part of range, that contains all addresses * higher than any address in the specified * @param[in] range - range to be intersected with and subtracted from * range * All three output paramters are optional - the range is not returned if the * corresponding parameter is NULL. */ VOID Decompose(const MemRange & range, MemRange * pIntersection, MemRange * pLowDiff, MemRange * pHighDiff) const { VOID * thisEnd = End(); VOID * otherEnd = range.End(); VOID * intersectionBase; VOID * intersectionEnd; if (Contains(range.m_base)) { // intersecting ranges intersectionBase = range.m_base; intersectionEnd = (range.Contains(thisEnd) ? thisEnd : otherEnd); } else if (range.Contains(m_base)) { // intersecting ranges intersectionBase = m_base; intersectionEnd = (Contains(otherEnd) ? otherEnd : thisEnd); } else if (m_base > range.m_base) { // intersection is empty; is higher than intersectionBase = intersectionEnd = m_base; } else { // intersection is empty; is lower than intersectionBase = intersectionEnd = thisEnd; } if (pIntersection != 0) { *pIntersection = MemRange(intersectionBase, intersectionEnd); } if (pLowDiff != 0) { *pLowDiff = MemRange(m_base, intersectionBase); } if (pHighDiff != 0) { *pHighDiff = MemRange(intersectionEnd, thisEnd); } } private: VOID * m_base; size_t m_size; }; /* DO NOT EDIT */ inline std::string MemRangeToString(const MemRange & range) { return ("[" + hexstr(range.Base()) + " , " + hexstr(range.End()) + "]"); } /* DO NOT EDIT */ extern MemRange MemPageRange(ADDRINT addr); /* DO NOT EDIT */ extern MemRange MemPageRange(const VOID * addr); /* DO NOT EDIT */ class ONCE_STATE { private: // Function execution state enum { NO_ONCE, //!< initial state - function never executed ONCE_RUNNING, //!< function is currently running ONCE_SUCCESS, //!< function executed successfully ONCE_FAILURE //!< function executed but failed } m_state; public: // Initial state - never executed ONCE_STATE() : m_state(NO_ONCE) {} // Return FALSE if function is already executed. Otherwise, set state to ONCE_RUNNING // and return TRUE. BOOL Enter() { if (m_state == NO_ONCE) { m_state = ONCE_RUNNING; return TRUE; } return FALSE; } // Set and return exit state of the function just executed BOOL Exit(BOOL result = TRUE) { m_state = (result ? ONCE_SUCCESS : ONCE_FAILURE); return result; } // Return TRUE if function is already executed successfully BOOL IsSuccess() const {return (m_state == ONCE_SUCCESS); } // Return TRUE if function is already executed but failed BOOL IsFailure() const {return (m_state == ONCE_FAILURE); } // Return TRUE if function is already executed BOOL IsDone() const {return (IsSuccess() || IsFailure()); } }; /* DO NOT EDIT */ struct OBJECT_DELETER { template static VOID Delete(T* p) {delete p;} }; /* DO NOT EDIT */ struct ARRAY_DELETER { template static VOID Delete(T* p) {delete [] p;} }; /* DO NOT EDIT */ template class COUNTED_PTR { public: /*! * Constructors. * WARNING: do not use the same raw pointer to construct more than one * COUNTED_PTR object */ COUNTED_PTR() : m_cptr(0){} explicit COUNTED_PTR(T * p) : m_cptr((p != 0) ? (new CPTR(p)) : 0) {} COUNTED_PTR(const COUNTED_PTR & r) : m_cptr(r.m_cptr) {AddRef();} /*! * Destructor. */ ~COUNTED_PTR() {ReleaseRef();} /*! * Assignment. */ COUNTED_PTR & operator = (const COUNTED_PTR & r) { r.AddRef(); ReleaseRef(); m_cptr = r.m_cptr; return *this; } VOID Reset() { ReleaseRef(); m_cptr = 0; } VOID Reset(T * p) { if ((m_cptr != 0) && (p == m_cptr->m_ptr)) {return;} ReleaseRef(); m_cptr = ((p != 0) ? (new CPTR(p)) : 0); } /*! * Accessors. */ T * Get() const {return ((m_cptr != 0) ? m_cptr->m_ptr : 0);} T * operator->() const {return Get();} T & operator*() const {return *(Get());} /*! * Comparison. */ BOOL operator == (const COUNTED_PTR & r) const {return (m_cptr == r.m_cptr);} BOOL operator != (const COUNTED_PTR & r) const {return (m_cptr != r.m_cptr);} BOOL operator == (const T * p) const {return (Get() == p);} BOOL operator != (const T * p) const {return (Get() != p);} private: struct CPTR { CPTR(T * p) : m_ptr(p), m_count(1) {} T * m_ptr; C m_count; }* m_cptr; VOID AddRef() const { if (m_cptr != 0) {++m_cptr->m_count;} } VOID ReleaseRef() { if ((m_cptr != 0) && (--m_cptr->m_count == 0)) { D::Delete(m_cptr->m_ptr); delete m_cptr; m_cptr = 0; } } }; /* DO NOT EDIT */ template struct OPTIONAL_VALUE { BOOL m_hasValue; ///< TRUE, if a value has been assigned to this object T m_value; ///< The value assigned to this object /*! * Assign the specified value to this object. * @param[in] value the new value to be assigned to this object */ VOID Set(const T & value) { m_hasValue = TRUE; m_value = value; } /*! * Assign a value to this object or remove the previous assignment. * @param[in] pValue pointer to the new value to be assigned to this object or * NULL to remove the previous assignment */ VOID Set(const T * pValue) { if (pValue != 0) { Set(*pValue); } else { Reset(); } } /*! * Remove the previous value assignment, if any. */ VOID Reset() {m_hasValue = FALSE;} /*! * Get the value of this object, if previously assigned. * @param[out] pValue optional pointer to variable that receives the value assigned to * this object, if any * @return TRUE if a value has been assigned to this object. */ BOOL Get(T * pValue) const { if (m_hasValue && (pValue != 0)) {*pValue = m_value;} return m_hasValue; } /*! * @return TRUE if a value has been assigned to this object. */ BOOL HasValue() const {return m_hasValue;} /*! * @return reference to the value assigned to this object. * The caller must ensure that a value has already been assigned to this object. */ T & Value() {return m_value;} const T & Value() const {return m_value;} /*! * Get a pointer to the value of this object, if the value has been assigned. * @return pointer to the value kept in this object or NULL if no value has been * assigned to this object. */ T * ValuePtr() {return ((m_hasValue) ? &m_value : 0);} const T * ValuePtr() const {return ((m_hasValue) ? &m_value : 0);} }; /* DO NOT EDIT */ extern STAT_NORM StatRawMmapBytes; /* DO NOT EDIT */ extern STAT_NORM StatReservedBytes; /* DO NOT EDIT */ extern VOID UpdateRawMmapBytes(); /* DO NOT EDIT */ extern std::string StringFlt(FLT64 val , UINT32 precision, UINT32 width); /* DO NOT EDIT */ inline std::string fltstr(FLT64 val, UINT32 prec=0,UINT32 width=0 ) {return StringFlt(val,prec,width);} /* DO NOT EDIT */ struct FLTSTR { FLTSTR(UINT32 prec=0,UINT32 width=0) :_p(prec), _w(width) {} template std::string operator() (const T & t) const {return fltstr(t,_p,_w);} UINT32 _p; UINT32 _w; }; /* DO NOT EDIT */