compiler intrinsics functions for storing the cpu state

I’ve a piece of driver code, i am trying to upgrade an exiting x86 WDM driver to a Windows x64 system using compiler intrinsic functions. I am using the WDK 7600.16385.0 for the build process. The 32 bit version of the driver had some inline assembly code to implement the saving the cpu state at a particular instance. i.e
saving cpu registers they are

  1. segment registers (cs,ds,es,fs, gs,ss), (mov instruction used to get register values)
  2. data registers (esi,edi), (mov instruction used to get register values)
  3. control registers(cro,cr2,cr3,cr4), (found intrinsic function)
  4. descriptor tables (sgdt, sldt, sidt, str), (sgdt sldt sidt str instructions used)
  5. flags register, (found intrinsic function)
  6. stack info (esp, ebp) (mov instruction used to get register values)etc.

I could write intrinsic function for some of them as I explained above.

Is there any way to store the cpu state using any intrinsic function?

Are there any equivalent intrinsic functions are there for following instructions
ltr, push,pop,pushad, popad, stgi opcode??

if anyone are having any idea regarding porting the inline assembly code to x64 system please help me out.

Here I am adding some code FYI

saveCPUState()
{
/* EFER */
myefer = (unsigned long)__readmsr(EFER_MSR);

/* eflags */
myeflags = __readeflags();

/* descriptor tables */
__asm {
sgdt mygdt_limit
sidt myidt_limit
sldt myldt
str mytr
}

/* segment registers */
__asm {
mov mycs, cs
mov myds, ds
mov myes, es
mov myfs, fs
mov mygs, gs
mov myss, ss
}

/* control registers */
mycr0 = __readcr0();
mycr2 = __readcr2();
mycr3 = __readcr3();
mycr4 = __readcr4();

/* data registers */
__asm {
mov myesi, esi
mov myedi, edi
}

/* stack info - not necessary here, but interesting to get rough idea of stack layout for this driver */
__asm {
mov myebp, ebp
mov myesp, esp
}
}

__asm {
ltr isk_state.tr
}

// STGI opcode: 0x0f01dc
__asm {
__emit 0x0f
__emit 0x01
__emit 0xdc
}

Thanks in advance…

xxxxx@gmail.com wrote:

I’ve a piece of driver code, i am trying to upgrade an exiting x86 WDM driver to a Windows x64 system using compiler intrinsic functions. I am using the WDK 7600.16385.0 for the build process. The 32 bit version of the driver had some inline assembly code to implement the saving the cpu state at a particular instance. i.e
saving cpu registers they are

Why? What earthly purpose could this possibly serve? This information
is totally useless. You can look at all of this in a debugger, but you
can’t do anything with this information programmatically. You can’t
restore the CPU state unless you have ALL of the registers, and you
don’t have enough state to do that. You can’t restore the segment
registers without knowing what’s in the GDT and LDT. You can’t restore
the control registers without knowing that the page tables are set up.

I just don’t see the point. And given that there’s no point, the
compiler team has probably not wasted any cycles making this easy.

I will point out that the ANSI standard “setjmp” function grabs all of
the general purpose registers, because those CAN be restores with useful
purpose (see “longjmp”).

Are there any equivalent intrinsic functions are there for following instructions
ltr, push,pop,pushad, popad, stgi opcode??

None of those serve any purpose here.

if anyone are having any idea regarding porting the inline assembly code to x64 system please help me out.

Porting the code blindly is an exercise in futility. WHY are you doing
this? If you can tell us what goal you are trying to accomplish,
perhaps we can advise you on a method for accomplishing it. As it is,
what you are doing is just silly.

saveCPUState()
{
/* EFER */
myefer = (unsigned long)__readmsr(EFER_MSR);

/* eflags */
myeflags = __readeflags();

The “eflags” have already been affected by the instructions that
preceded this one.

/* data registers */
__asm {
mov myesi, esi
mov myedi, edi
}

Why not the other registers? Why do you slight eax, ebx, ecx, and edx?

__asm {
ltr isk_state.tr
}

// STGI opcode: 0x0f01dc
__asm {
__emit 0x0f
__emit 0x01
__emit 0xdc
}

STGI is AMD-only. That should give you an “invalid instruction”
exception on x86. What on earth are you trying to do here?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

No ASM in NT kernel drivers; at all. Ok, there is one exception:

#if defined(X86) || defined(AMD64)
// Do your asm here
#endif

And the only time I would ever consider this is if I found a Windows bug
that needed patching in my code.

On Wed, Jan 7, 2015 at 1:08 PM, Tim Roberts wrote:

> xxxxx@gmail.com wrote:
> > I’ve a piece of driver code, i am trying to upgrade an exiting x86 WDM
> driver to a Windows x64 system using compiler intrinsic functions. I am
> using the WDK 7600.16385.0 for the build process. The 32 bit version of
> the driver had some inline assembly code to implement the saving the cpu
> state at a particular instance. i.e
> > saving cpu registers they are
>
> Why? What earthly purpose could this possibly serve? This information
> is totally useless. You can look at all of this in a debugger, but you
> can’t do anything with this information programmatically. You can’t
> restore the CPU state unless you have ALL of the registers, and you
> don’t have enough state to do that. You can’t restore the segment
> registers without knowing what’s in the GDT and LDT. You can’t restore
> the control registers without knowing that the page tables are set up.
>
> I just don’t see the point. And given that there’s no point, the
> compiler team has probably not wasted any cycles making this easy.
>
> I will point out that the ANSI standard “setjmp” function grabs all of
> the general purpose registers, because those CAN be restores with useful
> purpose (see “longjmp”).
>
>
> > Are there any equivalent intrinsic functions are there for following
> instructions
> > ltr, push,pop,pushad, popad, stgi opcode??
>
> None of those serve any purpose here.
>
>
> > if anyone are having any idea regarding porting the inline assembly code
> to x64 system please help me out.
>
> Porting the code blindly is an exercise in futility. WHY are you doing
> this? If you can tell us what goal you are trying to accomplish,
> perhaps we can advise you on a method for accomplishing it. As it is,
> what you are doing is just silly.
>
>
>
> > saveCPUState()
> > {
> > /* EFER /
> > myefer = (unsigned long)__readmsr(EFER_MSR);
> >
> > /
eflags /
> > myeflags =__readeflags();
>
> The “eflags” have already been affected by the instructions that
> preceded this one.
>
>
> > /
data registers */
> > asm {
> > mov myesi, esi
> > mov myedi, edi
> > }
>
> Why not the other registers? Why do you slight eax, ebx, ecx, and edx?
>
>
> >
asm {
> > ltr isk_state.tr
> > }
> >
> > // STGI opcode: 0x0f01dc
> > asm {
> >
emit 0x0f
> > emit 0x01
> >
emit 0xdc
> > }
>
> STGI is AMD-only. That should give you an “invalid instruction”
> exception on x86. What on earth are you trying to do here?
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


Jamey Kirby
Disrupting the establishment since 1964

This is a personal email account and as such, emails are not subject to
archiving. Nothing else really matters.

Tim,

I have implemented drivers with this capability. In fact 18 years ago
at WinHEC we demoed a checkpointing / failover system that required saving
of the state. I will agree the need is rare, but Jamey is correct there is
a need at times.

Don Burn
Windows Driver Consulting
Website: http://www.windrvr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Wednesday, January 07, 2015 1:09 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] compiler intrinsics functions for storing the cpu state

xxxxx@gmail.com wrote:

I’ve a piece of driver code, i am trying to upgrade an exiting x86 WDM
driver to a Windows x64 system using compiler intrinsic functions. I
am using the WDK 7600.16385.0 for the build process. The 32 bit
version of the driver had some inline assembly code to implement the
saving the cpu state at a particular instance. i.e saving cpu
registers they are

Why? What earthly purpose could this possibly serve? This information is
totally useless. You can look at all of this in a debugger, but you can’t
do anything with this information programmatically. You can’t restore the
CPU state unless you have ALL of the registers, and you don’t have enough
state to do that. You can’t restore the segment registers without knowing
what’s in the GDT and LDT. You can’t restore the control registers without
knowing that the page tables are set up.

I just don’t see the point. And given that there’s no point, the compiler
team has probably not wasted any cycles making this easy.

I will point out that the ANSI standard “setjmp” function grabs all of the
general purpose registers, because those CAN be restores with useful purpose
(see “longjmp”).

Are there any equivalent intrinsic functions are there for following
instructions ltr, push,pop,pushad, popad, stgi opcode??

None of those serve any purpose here.

if anyone are having any idea regarding porting the inline assembly code
to x64 system please help me out.

Porting the code blindly is an exercise in futility. WHY are you doing
this? If you can tell us what goal you are trying to accomplish, perhaps we
can advise you on a method for accomplishing it. As it is, what you are
doing is just silly.

saveCPUState()
{
/* EFER */
myefer = (unsigned long)__readmsr(EFER_MSR);

/* eflags */
myeflags = __readeflags();

The “eflags” have already been affected by the instructions that preceded
this one.

/* data registers */
__asm {
mov myesi, esi
mov myedi, edi
}

Why not the other registers? Why do you slight eax, ebx, ecx, and edx?

__asm {
ltr isk_state.tr
}

// STGI opcode: 0x0f01dc
__asm {
__emit 0x0f
__emit 0x01
__emit 0xdc
}

STGI is AMD-only. That should give you an “invalid instruction”
exception on x86. What on earth are you trying to do here?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Jamey Kirby wrote:

No ASM in NT kernel drivers; at all. Ok, there is one exception:

#if defined(X86) || defined(AMD64)
// Do your asm here
#endif

I assume you meant
#if defined(X86)
because there is no inline asm for AMD64.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Jamey,

Since there is no inline asm for AMD64 , is there any alternative approach.

I assume MASM still works. One would have to understand the x64 execution
environment, but if you are doing things like saving processor state, it
seems like a good bet you do. There are parts of the OS written in
assembler, like it’s pretty hard to write a scheduler context switch or
interrupt gate entry/exit in C.

Jan

On 1/8/15, 5:24 AM, “xxxxx@gmail.com” wrote:

>Hi Jamey,
>
>Since there is no inline asm for AMD64 , is there any alternative
>approach.
>
>-