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.
103 lines
2.9 KiB
103 lines
2.9 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.
|
|
*/
|
|
|
|
|
|
/*! @file
|
|
* An example of SMC inside a basic block.
|
|
* To run this application under pin, specify -smc_strict option.
|
|
*/
|
|
#include "smc_util.h"
|
|
#include "../Utils/sys_memory.h"
|
|
|
|
#if !defined(TARGET_IA32) || !defined(TARGET_WINDOWS)
|
|
#error This must be a 32-bit Windows program.
|
|
#endif
|
|
|
|
#define CODE_SECTION(name) __pragma(code_seg(name))
|
|
#define SECTION_END __pragma(code_seg())
|
|
|
|
/*!
|
|
* A function whose single basic block modifies its own code.
|
|
* The function copies "bar" string into the specified buffer. If in-BBL SMC
|
|
* is not handled, the output string is "foo".
|
|
* To simplify calculation of the size of this function, it is placed in a special
|
|
* code section along with the immediately following foo2barEnd() function.
|
|
*/
|
|
CODE_SECTION("foo2bar_code")
|
|
static void foo2bar(char * result)
|
|
{
|
|
__asm
|
|
{
|
|
// Modify immediate operands in smc* instructions
|
|
mov byte ptr [offset smc1 + 2], 'b';
|
|
mov byte ptr [offset smc2 + 2], 'a';
|
|
mov byte ptr [offset smc3 + 2], 'r';
|
|
|
|
mov eax, dword ptr [result];
|
|
|
|
smc1: mov byte ptr [eax], 'f'; // *result++ = 'f'
|
|
inc eax;
|
|
|
|
smc2: mov byte ptr [eax], 'o'; // *result++ = 'o'
|
|
inc eax;
|
|
|
|
smc3: mov byte ptr [eax], 'o'; // *result++ = 'o'
|
|
inc eax;
|
|
|
|
mov byte ptr [eax], 0; // *result = 0
|
|
}
|
|
}
|
|
SECTION_END
|
|
|
|
CODE_SECTION("foo2bar_code")
|
|
static void foo2barEnd(char * str) {}
|
|
SECTION_END
|
|
|
|
/*!
|
|
* Exit with the specified error message
|
|
*/
|
|
static void Abort(string msg)
|
|
{
|
|
cerr << msg << endl;
|
|
exit(1);
|
|
}
|
|
|
|
/*!
|
|
* The main procedure of the application.
|
|
*/
|
|
int main(int argc, char *argv[])
|
|
{
|
|
// Set read-write-execute protection for the code of the foo2bar() function
|
|
size_t pageSize = GetPageSize();
|
|
const char * start = CastPtr<char>(foo2bar);
|
|
const char * end = CastPtr<char>(foo2barEnd);
|
|
char * firstPage = (char *)(((size_t)start) & ~(pageSize - 1));
|
|
char * endPage = (char *)(((size_t)end + pageSize - 1) & ~(pageSize - 1));
|
|
if (!MemProtect(firstPage, endPage - firstPage, MEM_READ_WRITE_EXEC))
|
|
{
|
|
Abort("MemProtect failed");
|
|
}
|
|
|
|
// Execute the function and verify result
|
|
char result[16];
|
|
foo2bar(result);
|
|
if (strcmp(result, "bar") != 0)
|
|
{
|
|
Abort("foo2bar: Unexpected result");
|
|
}
|
|
cerr << "foo2bar: Success" << endl;
|
|
return 0;
|
|
}
|
|
|
|
/* ===================================================================== */
|
|
/* eof */
|
|
/* ===================================================================== */
|