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.

220 lines
5.0 KiB

/*
* Copyright 2002-2019 Intel Corporation.
*
* This software is provided to you as Sample Source Code as defined in the accompanying
* End User License Agreement for the Intel(R) Software Development Products ("Agreement")
* section 1.L.
*
* This software and the related documents are provided as is, with no express or implied
* warranties, other than those that are expressly stated in the License.
*/
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
typedef typeof(malloc) * MallocType;
typedef typeof(free) * FreeType;
MallocType mallocFun;
FreeType freeFun;
#ifndef STATIC_LINK
/* The maximal 32-bit decimal unsigned integer (4294967295) takes 10 bytes. */
#define max32BitDecLen 10
/* The maximal 64-bit hexadecimal unsigned integer (0xffffffffffffffff) takes 18 bytes. */
#define max64BitHexLen 18
#define max64BitHexNoPrefixLen 16
/*
* A simple conversion function from a 32-bit unsigned integer to a string with no dynamic allocation of memory.
* The function stores the string in the supplied buffer which is expected to be at least max32BitDecLen bytes
* long. No \0 terminator is stored.
*
* The function returns the number of written digits.
*/
unsigned int SimpleDecStr(unsigned int num, char* buf)
{
static const char conversionMap[10] =
{
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9'
};
char temp[max32BitDecLen] = { 0 };
unsigned int src = 0;
unsigned int dst = 0;
if (0 == num)
{
buf[0] = '0';
return 1;
}
while (0 != num)
{
assert(src < max32BitDecLen);
temp[src] = conversionMap[num%10];
num /= 10;
++src;
}
while (0 < src)
{
--src;
buf[dst] = temp[src];
++dst;
}
return dst;
}
/*
* A simple conversion function from an unsigned integer (of pointer size) to a hexadecimal string representation
* with no dynamic allocation of memory. The function stores the string in the supplied buffer which is expected
* to be at least max64BitHexLen bytes long. No \0 terminator is stored.
*
* The function returns the number of written characters.
*/
unsigned int SimpleHexStr(uintptr_t num, char* buf)
{
static const char conversionMap[16] =
{
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'a',
'b',
'c',
'd',
'e',
'f'
};
char temp[max64BitHexNoPrefixLen] = { 0 };
unsigned int src = 0;
unsigned int dst = 2;
buf[0] = '0';
buf[1] = 'x';
if (0 == num)
{
buf[2] = '0';
return 3;
}
while (0 != num)
{
assert(src < max64BitHexNoPrefixLen);
temp[src] = conversionMap[num%16];
num >>= 4; /* num /= 16 */
++src;
}
while (0 < src)
{
--src;
buf[dst] = temp[src];
++dst;
}
return dst;
}
#endif // not STATIC_LINK
void * mallocWrapper(int size)
{
void * res = (*mallocFun)(size);
#ifdef STATIC_LINK
fprintf(stderr,"malloc(%d) = %p\n", size, res);
#else
static const char* startStr = "malloc(";
static const char* middleStr = ") = ";
static const char* endStr = "\n";
static const unsigned int stringTermLen = 1; /* '\0' */
const unsigned int startLen = strlen(startStr);
const unsigned int middleLen = strlen(middleStr);
const unsigned int endLen = strlen(endStr);
const unsigned int msgSize = startLen + middleLen + endLen + max32BitDecLen + max64BitHexLen + stringTermLen;
char msg[msgSize];
unsigned int i = 0;
/* Build the message as seen in the fprintf above. */
strncpy(&(msg[i]), startStr, startLen);
i += startLen;
i += SimpleDecStr(size, &(msg[i]));
strncpy(&(msg[i]), middleStr, middleLen);
i += middleLen;
i += SimpleHexStr((uintptr_t)res, &(msg[i]));
strncpy(&(msg[i]), endStr, endLen);
i += endLen;
msg[i++] = '\0';
write(STDERR_FILENO, msg, i);
#endif // not STATIC_LINK
return res;
}
void freeWrapper(void *p)
{
#ifndef STATIC_LINK
static const char* startStr = "free(";
static const char* endStr = ")\n";
static const unsigned int stringTermLen = 1; /* '\0' */
const unsigned int startLen = strlen(startStr);
const unsigned int endLen = strlen(endStr);
const unsigned int msgSize = startLen + endLen + max64BitHexLen + stringTermLen;
char msg[msgSize];
unsigned int i = 0;
/* Build the message as seen in the fprintf below. */
strncpy(&(msg[i]), startStr, startLen);
i += startLen;
i += SimpleHexStr((uintptr_t)p, &(msg[i]));
strncpy(&(msg[i]), endStr, endLen);
i += endLen;
msg[i++] = '\0';
#endif // not STATIC_LINK
(*freeFun)(p);
#ifdef STATIC_LINK
fprintf(stderr,"free(%p)\n",p);
#else
write(STDERR_FILENO, msg, i);
#endif // STATIC_LINK
}
void SetOriginalFptr(MallocType m, FreeType f)
{
mallocFun = m;
freeFun = f;
}