You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1230 lines
41 KiB
1230 lines
41 KiB
//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<UINT64>(p);
|
|
return hexstr(val,width);
|
|
#else
|
|
UINT32 val = reinterpret_cast<UINT32>(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<UINT64>(p);
|
|
return hexstr(val,width);
|
|
#else
|
|
UINT32 val = reinterpret_cast<UINT32>(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 <typename T> 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 <typename T> std::string operator() (const T & t) const {return hexstr(t,_w);}
|
|
UINT32 _w;
|
|
};
|
|
|
|
/* DO NOT EDIT */
|
|
template <typename ITER, typename CONV>
|
|
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<VOID*>(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<ADDRINT>(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<ADDRINT>(addr);
|
|
#endif
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
template <typename T> BOOL IsPowerOf2(T value)
|
|
{
|
|
return ((value & (value - 1)) == 0);
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
template <typename T> 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 <typename T> 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 <typename T> T * RoundUp(T * ptr, size_t alignment)
|
|
{
|
|
return (reinterpret_cast<T *>(RoundUp(reinterpret_cast<ADDRINT>(ptr), alignment)));
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
template <typename T> T RoundUpPowerOf2(T value, size_t alignment)
|
|
{
|
|
if (alignment == 0) return value;
|
|
T align_1 = static_cast<T>(alignment - 1);
|
|
ASSERTX((alignment & align_1) == 0);
|
|
return ((value + align_1) & ~align_1);
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
template <typename T> T * RoundUpPowerOf2(T * ptr, size_t alignment)
|
|
{
|
|
return (reinterpret_cast<T *>(RoundUpPowerOf2(reinterpret_cast<ADDRINT>(ptr), alignment)));
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
template <typename T> T RoundDown(T value, size_t alignment)
|
|
{
|
|
if (alignment == 0)
|
|
{
|
|
return value;
|
|
}
|
|
|
|
value /= alignment;
|
|
value *= alignment;
|
|
|
|
return value;
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
template <typename T> T * RoundDown(T * ptr, size_t alignment)
|
|
{
|
|
return (reinterpret_cast<T *>(RoundDown(reinterpret_cast<ADDRINT>(ptr), alignment)));
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
template <typename T> T RoundDownPowerOf2(T value, size_t alignment)
|
|
{
|
|
if (alignment == 0) return value;
|
|
T align_1 = static_cast<T>(alignment - 1);
|
|
ASSERTX((alignment & align_1) == 0);
|
|
return (value & ~align_1);
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
template <typename T> T * RoundDownPowerOf2(T * ptr, size_t alignment)
|
|
{
|
|
return (reinterpret_cast<T *>(RoundDownPowerOf2(reinterpret_cast<ADDRINT>(ptr), alignment)));
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
template<typename T> 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<ADDRINT>(ptr);
|
|
#endif
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
template<typename T> 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<T*>(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<INT64>(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<INT32*>(address);
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
inline VOID MEMORY_WriteInt32(ADDRINT address, INT32 value)
|
|
{
|
|
*reinterpret_cast<INT32*>(address) = value;
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
inline UINT32 MEMORY_ReadUint32(ADDRINT address)
|
|
{
|
|
return *reinterpret_cast<UINT32*>(address);
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
inline VOID MEMORY_WriteUint32(ADDRINT address, UINT32 value)
|
|
{
|
|
*reinterpret_cast<UINT32*>(address) = value;
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
inline INT64 MEMORY_ReadInt64(ADDRINT address)
|
|
{
|
|
return *reinterpret_cast<INT64*>(address);
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
inline VOID MEMORY_WriteInt64(ADDRINT address, INT64 value)
|
|
{
|
|
*reinterpret_cast<INT64*>(address) = value;
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
inline UINT64 MEMORY_ReadUint64(ADDRINT address)
|
|
{
|
|
return *reinterpret_cast<UINT64*>(address);
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
inline VOID MEMORY_WriteUint64(ADDRINT address, UINT32 value)
|
|
{
|
|
*reinterpret_cast<UINT64*>(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<const INT8 *>(ptr1) - reinterpret_cast<const INT8 *>(ptr2));
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
inline VOID * PtrAtOffset(VOID * ptr, size_t offset)
|
|
{
|
|
return (reinterpret_cast<INT8 *>(ptr) + offset);
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
inline const VOID * PtrAtOffset(const VOID * ptr, size_t offset)
|
|
{
|
|
return (reinterpret_cast<const INT8 *>(ptr) + offset);
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
template <typename T> T * PtrAtOffset(VOID * ptr, size_t offset)
|
|
{
|
|
return (reinterpret_cast<T *>(PtrAtOffset(ptr, offset)));
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
template <typename T> const T * PtrAtOffset(const VOID * ptr, size_t offset)
|
|
{
|
|
return (reinterpret_cast<const T *>(PtrAtOffset(ptr, offset)));
|
|
}
|
|
|
|
/* DO NOT EDIT */
|
|
template <typename T> 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<ADDRINT *>(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 <this> range with specified <range>
|
|
* @param[out] pLowDiff - part of <this> range, that contains all addresses
|
|
* lower than any address in the specified <range>
|
|
* @param[out] pHighDiff - part of <this> range, that contains all addresses
|
|
* higher than any address in the specified <range>
|
|
* @param[in] range - range to be intersected with and subtracted from
|
|
* <this> 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; <this> is higher than <range>
|
|
intersectionBase = intersectionEnd = m_base;
|
|
}
|
|
else
|
|
{
|
|
// intersection is empty; <this> is lower than <range>
|
|
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<typename T> static VOID Delete(T* p) {delete p;}
|
|
};
|
|
|
|
/* DO NOT EDIT */
|
|
struct ARRAY_DELETER
|
|
{
|
|
template<typename T> static VOID Delete(T* p) {delete [] p;}
|
|
};
|
|
|
|
/* DO NOT EDIT */
|
|
template<typename T, typename D = OBJECT_DELETER, typename C = INT32> 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 <typename T> 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 <typename T> std::string operator() (const T & t) const {return fltstr(t,_p,_w);}
|
|
UINT32 _p;
|
|
UINT32 _w;
|
|
};
|
|
|
|
/* DO NOT EDIT */
|
|
|