Intel has announced a new technology called Intel® Memory Protection Extensions (Intel® MPX). To find out more about that, check out the Instruction Set Extensions web pages. Once you know about Intel MPX, you may want to experiment with it with Intel® SDE. This article explains how you can do that and some topics that are different when using Intel SDE from when Intel MPX will be deployed in production systems.
Compilers that generate code using the Intel MPX insert instructions in to the execution of programs that help guard against certiain types of memory related problems. When one of these problems is detected the #BR exception is generated. What happens then differs when executing on Intel SDE and what will happen when executing on the future chips that support Intel MPX. In the Intel SDE case, that #BR exception causes execution to goes in to the kernel and the kernel calls a signal handler that we have asked it to call as part of the initialization of our runtime. In a real production system more of the handling of the #BR exception would occur in the Linux* kernel. Our runtime handler takes the initialization, bookkeeping data structures, and bound violation handling that are required to implement Intel MPX. Our runtime also provides some debugging and statistics information that can be valuable when trying to understand your program.
You'll need a compiler that can emit the Intel MPX instructions. We have a GNU gcc compile for linux on the Intel SDE web page. Here is a little example:
% cat mpx.c int main(int argc, char *argv[]) { char buf[10]; /*BAD*/ buf[10] = 0; return 0; }
To compile it with gcc, you must use the -fmpx knob:
% $MPX_GCC/bin/gcc -B$MPX_BINUTILS/bin -fmpx -c -o mpx.o mpx.c
where $MPX_GCC is the environment variable you set to point to your installation of an Intel MPX-enabled gcc. And $MPX_BINUTILS is the path to your installation of the Intel MPX-enabled binutils.
The next step is to link it. The linking step is a little more complex because you must link in the Intel MPX runtime designed to work with Intel SDE. More about this below. There are two shared objects in the runtime kit available on the SDE page. One for 32b applications and one for 64b applications.
% $MPX_GCC/bin/gcc -L$MPX_RUNTIME_LIB -lmpx-runtime64 -Wl,-rpath,$MPX_RUNTIME_LIB -o mpx.exe mpx.o
For linux, if you do not use -rpath above, you MUST have the directory containing the libmpx-runtime32.so and libpl-runtime64.so files included in your environment LD_LIBRARY_PATH variable.
And then to run it:
% $SDE_KIT/sde -mpx-mode -- ./mpx.exe Bound violation detected,status 0x1 at 0x40065f
where $SDE_KIT is an environment variable pointing to your unpacked Intel SDE kit.
The compilation and linking situation is slightly different on Windows. Of course the compiler and knobs are different. But to use the Intel SDE "mpx-runtime", one must link in an object file version of the loadrt.cpp file supplied in our MPX runtime download zip file. This example uses a version of ICL that is not available externally yet.
> icl /c %MPX_RUN_TIME_DIR%\loadrt.cpp > link /LIBPATH:%ICL_LIBS% mpx.obj loadrt.obj
Options and Knobs
SDE has the following knobs available for controlling execution for Intel MPX. These are visible in the (long) output of the command "path-to-kit/sde -long-help". By default Intel SDE support for Intel MPX is disabled. You must enable it with the "-mpx-mode" knob.
-mpx_call_stack [default 0] Collect MPX call stack. -mpx_call_stack_depth [default 10] Specify MPX call-stack max depth -mpx_mode [default 0] Enable=1 or Disable=0 Memory Protection Extensions emulation -mpx_stats [default 0] Compute MPX stats. -mpx_trace_flush [default 0] Flush output after every instruction -mpx_trace_ins specify instruction for MPX to trace [bndmk | bndmov | bndstx | bndldx | bndcl | bndcu | bndcn | all]. -ompx_stats [default sde-mpx-stats.txt] specify MPX stats file name -ompx_trace [default sde-mpx-trace.txt] specify MPX trace file name -mpx_late_open [default 0] delay the opening of the file to the end of the execution -mpx_trace_cb_lines [default 0] number of lines to be used by the circular buffer. if mpx-late-open is used the default value is 1000.
As with all Intel SDE options, underscores in the middle of knobs can be dashes. So "-mpx-mode" and "-mpx_mode" are equivalent. Also for binary valued knobs that default to value 0, you need not specify the "1" value; Specifying "-mpx-mode" is equivalent to "-mpx-mode 1".
Runtime environment variables
The runtime has several environment variables available to influence application and emulation behavior:
CHKP_RT_OUT_FILE set output file for info & debug [default: stdout] CHKP_RT_ERR_FILE set output file for error [default: stderr] CHKP_RT_VERBOSE set verbosity type [default: 2] 0 - print only internal run time errors 1 - just print summary 2 - print summary and bound violation information 3 - print debug information CHKP_RT_MODE set mpx runtime behavior on #BR exception. [stop,count] [default: stop] CHKP_RT_ADDPID generate out,err file for each process. generated file will be CHKP_RT_{OUT,ERR}_FILE.pid [default: no] CHKP_RT_BNDPRESERVE set value for BNDPRESERVE bit. BNDPRESERVE = 0 flush bounds on unprefixed call/ret/jmp BNDPRESERVE = 1 do NOT flush bounds [default: 0] CHKP_RT_PRINT_SUMMARY print summary at the end of the run [default: no] CHKP_RT_HELP print this help and exit.
Here is an example of how to use the environment variables:
>setenv CHKP_RT_MODE count >setenv CHKP_RT_OUT_FILE mpx_example.txt >setenv CHKP_RT_PRINT_SUMMARY 1 >PATH-TO-SDE-KIT/sde -mpx-mode -- test.exe >cat mpx_example.txt Bound violation detected,status 0x1 at 0x40072f Bound violation detected,status 0x1 at 0x40074a MPX run time summary: number of BRs: 2. size of allocated L1: 2147483648B total size of allocated L2 entries: 0B Used environment variables: CHKP_RT_OUT_FILE = mpx_example.txt CHKP_RT_MODE = count CHKP_RT_PRINT_SUMMARY = 1
The bound violation exception is mapped to SIGSEGV. On Linux you can define your own handler for SIGSEGV using sigaction(). This handler will be called for SIGSEGV exceptions which are NOT of type bound validation.
Disassembly
The XED tool included in the Intel SDE kit can disassemble the Intel MPX instructions. The opcodes used by the Intel MPX instructions execute as NOPs when Intel MPX is not enabled.
PATH-TO-SDE-KIT/xed -i mpx.exe | grep MPX XDIS 400781: MPX MPX F30F1B4020 bndmk bnd0, ptr [rax+0x20] XDIS 400786: MPX MPX 0F1B0408 bndstx bnd0, ptr [rax+rcx*1] XDIS 40078a: MPX MPX 0F1A0C08 bndldx bnd1, ptr [rax+rcx*1] XDIS 40078e: MPX MPX 660F1B0A bndmov xmmword ptr [rdx], bnd1
Questions?
If you have questions about using Intel SDE or Intel MPX with Intel SDE, please comment below or contact us on the discussion forum.
This article was written by Michael Berezalsky, Ady Tal, and Mark Charney.