mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-09 17:06:24 +00:00
156 lines
4.1 KiB
C
156 lines
4.1 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
typedef unsigned int UInt;
|
|
typedef unsigned long long int ULong;
|
|
|
|
void do_cmpxchg8b ( /*OUT*/
|
|
ULong* rdxOut, ULong* raxOut,
|
|
ULong* memHiOut, ULong* memLoOut,
|
|
ULong* zOut,
|
|
/*IN*/
|
|
ULong rdxIn, ULong raxIn,
|
|
ULong memHiIn, ULong memLoIn,
|
|
ULong rcxIn, ULong rbxIn )
|
|
{
|
|
UInt mem[2];
|
|
ULong block[6];
|
|
mem[0] = (UInt)memLoIn;
|
|
mem[1] = (UInt)memHiIn;
|
|
block[0] = rdxIn;
|
|
block[1] = raxIn;
|
|
block[2] = rcxIn;
|
|
block[3] = rbxIn;
|
|
block[4] = (ULong)&mem[0];
|
|
block[5] = ~(0ULL);
|
|
__asm__ __volatile__(
|
|
"movq %0,%%r11\n"
|
|
"\tmovq 0(%%r11),%%rdx\n"
|
|
"\tmovq 8(%%r11),%%rax\n"
|
|
"\tmovq 16(%%r11),%%rcx\n"
|
|
"\tmovq 24(%%r11),%%rbx\n"
|
|
"\tmovq 32(%%r11),%%r10\n"
|
|
"\tlock cmpxchg8b (%%r10)\n"
|
|
"\tmovabsq $0,%%r10\n"
|
|
"\tsetz %%r10b\n"
|
|
"\tmovq %%r10,40(%%r11)\n"
|
|
"\tmovq %%rdx,0(%%r11)\n"
|
|
"\tmovq %%rax,8(%%r11)\n"
|
|
: /*out*/
|
|
: /*in*/ "r"(&block[0])
|
|
: /*trash*/ "%r11", "%r10", "%rax", "%rbx", "%rcx", "%rdx",
|
|
"cc", "memory" );
|
|
*rdxOut = block[0];
|
|
*raxOut = block[1];
|
|
*memLoOut = (ULong)mem[0];
|
|
*memHiOut = (ULong)mem[1];
|
|
*zOut = block[5];
|
|
}
|
|
|
|
void try8b ( ULong d, ULong a, ULong mHi, ULong mLo, ULong c, ULong b )
|
|
{
|
|
ULong dd, aa, mmHi, mmLo, zz;
|
|
do_cmpxchg8b( &dd, &aa, &mmHi, &mmLo, &zz,
|
|
d,a,mHi,mLo,c,b);
|
|
printf(" Q d:a=%llx:%llx mem=%llx:%llx c:b=%llx:%llx "
|
|
"-> z=%lld d:a=%llx:%llx mem=%llx:%llx\n",
|
|
d,a, mHi,mLo, c,b, zz, dd,aa, mmHi,mmLo );
|
|
}
|
|
|
|
void do_cmpxchg16b ( /*OUT*/
|
|
ULong* rdxOut, ULong* raxOut,
|
|
ULong* memHiOut, ULong* memLoOut,
|
|
ULong* zOut,
|
|
/*IN*/
|
|
ULong rdxIn, ULong raxIn,
|
|
ULong memHiIn, ULong memLoIn,
|
|
ULong rcxIn, ULong rbxIn )
|
|
{
|
|
ULong mem[2] __attribute__((aligned(16)));
|
|
ULong block[6];
|
|
mem[0] = memLoIn;
|
|
mem[1] = memHiIn;
|
|
block[0] = rdxIn;
|
|
block[1] = raxIn;
|
|
block[2] = rcxIn;
|
|
block[3] = rbxIn;
|
|
block[4] = (ULong)&mem[0];
|
|
block[5] = ~(0ULL);
|
|
__asm__ __volatile__(
|
|
"movq %0,%%r11\n"
|
|
"\tmovq 0(%%r11),%%rdx\n"
|
|
"\tmovq 8(%%r11),%%rax\n"
|
|
"\tmovq 16(%%r11),%%rcx\n"
|
|
"\tmovq 24(%%r11),%%rbx\n"
|
|
"\tmovq 32(%%r11),%%r10\n"
|
|
"\t.byte 0xf0, 0x49, 0x0f, 0xc7, 0x0a\n" /* lock cmpxchg16b (%%r10) */
|
|
"\tmovabsq $0,%%r10\n"
|
|
"\tsetz %%r10b\n"
|
|
"\tmovq %%r10,40(%%r11)\n"
|
|
"\tmovq %%rdx,0(%%r11)\n"
|
|
"\tmovq %%rax,8(%%r11)\n"
|
|
: /*out*/
|
|
: /*in*/ "r"(&block[0])
|
|
: /*trash*/ "%r11", "%r10", "%rax", "%rbx", "%rcx", "%rdx",
|
|
"cc", "memory" );
|
|
*rdxOut = block[0];
|
|
*raxOut = block[1];
|
|
*memLoOut = mem[0];
|
|
*memHiOut = mem[1];
|
|
*zOut = block[5];
|
|
}
|
|
|
|
void try16b ( ULong d, ULong a, ULong mHi, ULong mLo, ULong c, ULong b )
|
|
{
|
|
ULong dd, aa, mmHi, mmLo, zz;
|
|
do_cmpxchg16b( &dd, &aa, &mmHi, &mmLo, &zz,
|
|
d,a,mHi,mLo,c,b);
|
|
printf("QQ d:a=%llx:%llx mem=%llx:%llx c:b=%llx:%llx "
|
|
"-> z=%lld d:a=%llx:%llx mem=%llx:%llx\n",
|
|
d,a, mHi,mLo, c,b, zz, dd,aa, mmHi,mmLo );
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
ULong z = 0xDEADBEEF00000000ULL;
|
|
|
|
try8b( 0,1, 5,4, 3,2 );
|
|
try8b( 0,1, 0,1, 3,2 );
|
|
|
|
try8b( 0,1, 0,4, 3,2 );
|
|
try8b( 0,1, 0,0, 3,2 );
|
|
|
|
try8b( 0,1, 5,0, 3,2 );
|
|
try8b( 0,1, 1,1, 3,2 );
|
|
|
|
try8b( 0+z,1+z, 5+z,4+z, 3+z,2+z );
|
|
try8b( 0+z,1+z, 0+z,1+z, 3+z,2+z );
|
|
|
|
try8b( 0+z,1+z, 0+z,4+z, 3+z,2+z );
|
|
try8b( 0+z,1+z, 0+z,0+z, 3+z,2+z );
|
|
|
|
try8b( 0+z,1+z, 5+z,0+z, 3+z,2+z );
|
|
try8b( 0+z,1+z, 1+z,1+z, 3+z,2+z );
|
|
|
|
try16b( 0,1, 5,4, 3,2 );
|
|
try16b( 0,1, 0,1, 3,2 );
|
|
|
|
try16b( 0,1, 0,4, 3,2 );
|
|
try16b( 0,1, 0,0, 3,2 );
|
|
|
|
try16b( 0,1, 5,0, 3,2 );
|
|
try16b( 0,1, 1,1, 3,2 );
|
|
|
|
try16b( 0+z,1+z, 5+z,4+z, 3+z,2+z );
|
|
try16b( 0+z,1+z, 0+z,1+z, 3+z,2+z );
|
|
|
|
try16b( 0+z,1+z, 0+z,4+z, 3+z,2+z );
|
|
try16b( 0+z,1+z, 0+z,0+z, 3+z,2+z );
|
|
|
|
try16b( 0+z,1+z, 5+z,0+z, 3+z,2+z );
|
|
try16b( 0+z,1+z, 1+z,1+z, 3+z,2+z );
|
|
|
|
return 0;
|
|
}
|
|
|