C++ static construction on AMD 64?

We use C++ for our driver (no flamewars, please :-). Anyway, to do
this, one thing you need to do is come up with some way to call the
constructors for your global/static objects.

There’s a pretty standard way to do this, described in
http://msdn.microsoft.com/msdnmag/issues/01/01/hood/, that involves
calling the functions pointed to in a specially named data segment
called .CRT$XCU. The compiler puts all the static objects’
constructors in this named segment so that they all get linked
together in one place. This is normally bracketed by a couple of data
segments called .CRT$XCA and .CRT$XCZ (which contain some globally
accessible specially named variables so you can find them). That way
there’s some way for the runtime initialization code to know what the
boundaries of the constructor pointer list are. This still is all
generated by the compiler and linker automatically.

However, we just tried compiling our driver for the AMD64 processor in
preparation for XP AMD64 notebooks coming out soon, and it appears
that that compiler puts the XCA and XCZ segments in an area unrelated
.CRT$XCU. Therefore I don’t know how to find them from our
initialization code any more.

Has anyone run into this, and if so, what was the workaround?

Of course, our next step will be to reverse engineering the CRTL for
this compiler… I was just hoping not to needlessly replicate that
effort…

…/ray..

Hi Ray,

I would recommend allocating the object yourself in DriverEntry and storing
a pointer to it in the global rather than just having a global object. Then
you avoid any these issues altogether. That’s what I do in my code. (It
certainly keeps things simple.)

I don’t know whether you’d consider that a workaround, though. In any case,
good luck!

  • Danilo

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com]
On Behalf Of Ray Trent
Sent: Monday, August 25, 2003 10:35 AM
To: Windows System Software Developers Interest List
Subject: [ntdev] C++ static construction on AMD 64?

We use C++ for our driver (no flamewars, please :-). Anyway, to do
this, one thing you need to do is come up with some way to call the
constructors for your global/static objects.

There’s a pretty standard way to do this, described in
http://msdn.microsoft.com/msdnmag/issues/01/01/hood/, that involves
calling the functions pointed to in a specially named data segment
called .CRT$XCU. The compiler puts all the static objects’
constructors in this named segment so that they all get linked
together in one place. This is normally bracketed by a couple of data
segments called .CRT$XCA and .CRT$XCZ (which contain some globally
accessible specially named variables so you can find them). That way
there’s some way for the runtime initialization code to know what the
boundaries of the constructor pointer list are. This still is all
generated by the compiler and linker automatically.

However, we just tried compiling our driver for the AMD64 processor in
preparation for XP AMD64 notebooks coming out soon, and it appears
that that compiler puts the XCA and XCZ segments in an area unrelated
.CRT$XCU. Therefore I don’t know how to find them from our
initialization code any more.

Has anyone run into this, and if so, what was the workaround?

Of course, our next step will be to reverse engineering the CRTL for
this compiler… I was just hoping not to needlessly replicate that
effort…

…/ray..

Ray:

Allocating the object using new makes the most sense. In addition, to get
the allocation to be
from the right type of memory, paged or non-paged, you have to overload the
operator new.
After that the object will be properly allocated. Of course you also have
to overload the operator
delete to properly free the object when no longer used.

If you need an example of overloaded operator new and operator delete let
me know.

George Blat

NT with real time performance
8016 188th SW, Edmonds, WA 98026

phone: 425-775-7475
fax: 781-998-5940
mailto:xxxxx@ntrealtime.com

At 09:36 PM 8/25/2003, you wrote:

Hi Ray,

I would recommend allocating the object yourself in DriverEntry and storing
a pointer to it in the global rather than just having a global object. Then
you avoid any these issues altogether. That’s what I do in my code. (It
certainly keeps things simple.)

I don’t know whether you’d consider that a workaround, though. In any case,
good luck!

  • Danilo

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com]
On Behalf Of Ray Trent
Sent: Monday, August 25, 2003 10:35 AM
To: Windows System Software Developers Interest List
Subject: [ntdev] C++ static construction on AMD 64?

We use C++ for our driver (no flamewars, please :-). Anyway, to do
this, one thing you need to do is come up with some way to call the
constructors for your global/static objects.

There’s a pretty standard way to do this, described in
http://msdn.microsoft.com/msdnmag/issues/01/01/hood/, that involves
calling the functions pointed to in a specially named data segment
called .CRT$XCU. The compiler puts all the static objects’
constructors in this named segment so that they all get linked
together in one place. This is normally bracketed by a couple of data
segments called .CRT$XCA and .CRT$XCZ (which contain some globally
accessible specially named variables so you can find them). That way
there’s some way for the runtime initialization code to know what the
boundaries of the constructor pointer list are. This still is all
generated by the compiler and linker automatically.

However, we just tried compiling our driver for the AMD64 processor in
preparation for XP AMD64 notebooks coming out soon, and it appears
that that compiler puts the XCA and XCZ segments in an area unrelated
.CRT$XCU. Therefore I don’t know how to find them from our
initialization code any more.

Has anyone run into this, and if so, what was the workaround?

Of course, our next step will be to reverse engineering the CRTL for
this compiler… I was just hoping not to needlessly replicate that
effort…

…/ray..


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@ntrealtime.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Of course, I could do this for certain global objects, but it doesn’t
address static member variables of C++ classes and static variables in
file scope (of which we have many, quite of few of which are
protected). I’d rather not tie the detailed implementation of my
classes into my DriverEntry routine, nor do I really want all of my
classes to have to “friend” DriverEntry. Doing so loses much of the
modularity and maintainability advantage of using C++ in the first place.

As for using the right pool, that’s easily solved by setting the right
attributes on the data segment in which the global objects reside
(they aren’t terribly large and having all of them be in non-paged
pool simplifies the design constraints… otherwise some classes would
have to be designed to be used in PASSIVE_LEVEL only, and enforcing
that would be annoying).

George Blat wrote:

Ray:

Allocating the object using new makes the most sense. In addition, to
get the allocation to be
from the right type of memory, paged or non-paged, you have to overload
the operator new.
After that the object will be properly allocated. Of course you also
have to overload the operator
delete to properly free the object when no longer used.

If you need an example of overloaded operator new and operator delete
let me know.

George Blat

NT with real time performance
8016 188th SW, Edmonds, WA 98026

phone: 425-775-7475
fax: 781-998-5940
mailto:xxxxx@ntrealtime.com

At 09:36 PM 8/25/2003, you wrote:

> Hi Ray,
>
> I would recommend allocating the object yourself in DriverEntry and
> storing
> a pointer to it in the global rather than just having a global
> object. Then
> you avoid any these issues altogether. That’s what I do in my code. (It
> certainly keeps things simple.)
>
> I don’t know whether you’d consider that a workaround, though. In any
> case,
> good luck!
>
> - Danilo
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com]
> On Behalf Of Ray Trent
> Sent: Monday, August 25, 2003 10:35 AM
> To: Windows System Software Developers Interest List
> Subject: [ntdev] C++ static construction on AMD 64?
>
> We use C++ for our driver (no flamewars, please :-). Anyway, to do
> this, one thing you need to do is come up with some way to call the
> constructors for your global/static objects.
>
> There’s a pretty standard way to do this, described in
> http://msdn.microsoft.com/msdnmag/issues/01/01/hood/, that involves
> calling the functions pointed to in a specially named data segment
> called .CRT$XCU. The compiler puts all the static objects’
> constructors in this named segment so that they all get linked
> together in one place. This is normally bracketed by a couple of data
> segments called .CRT$XCA and .CRT$XCZ (which contain some globally
> accessible specially named variables so you can find them). That way
> there’s some way for the runtime initialization code to know what the
> boundaries of the constructor pointer list are. This still is all
> generated by the compiler and linker automatically.
>
> However, we just tried compiling our driver for the AMD64 processor in
> preparation for XP AMD64 notebooks coming out soon, and it appears
> that that compiler puts the XCA and XCZ segments in an area unrelated
> .CRT$XCU. Therefore I don’t know how to find them from our
> initialization code any more.
>
> Has anyone run into this, and if so, what was the workaround?
>
> Of course, our next step will be to reverse engineering the CRTL for
> this compiler… I was just hoping not to needlessly replicate that
> effort…
> –
> …/ray..
>
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@ntrealtime.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com


…/ray..

> Has anyone run into this, and if so, what was the workaround?

Yep, we have. For x86 you would do something like this, right?

#pragma data_seg(“.CRT$XCA”)
void (*_StartInitCalls[1])(void)={0};

For IA64/AMD64 you need something like this to accomplish the same:

#pragma section(“.CRT$XCA”,long,read)
__declspec(allocate(“.CRT$XCA”)) void (*_StartInitCalls[1])(void)={0};


Bill McKenzie
Compuware Corporation
Watch your IRPs/IRBs/URBs/SRBs/NDIS pkts with our free WDMSniffer tool:
http://frontline.compuware.com/nashua/patches/utility.htm

“Ray Trent” wrote in message news:xxxxx@ntdev…
>
> We use C++ for our driver (no flamewars, please :-). Anyway, to do
> this, one thing you need to do is come up with some way to call the
> constructors for your global/static objects.
>
> There’s a pretty standard way to do this, described in
> http://msdn.microsoft.com/msdnmag/issues/01/01/hood/, that involves
> calling the functions pointed to in a specially named data segment
> called .CRT$XCU. The compiler puts all the static objects’
> constructors in this named segment so that they all get linked
> together in one place. This is normally bracketed by a couple of data
> segments called .CRT$XCA and .CRT$XCZ (which contain some globally
> accessible specially named variables so you can find them). That way
> there’s some way for the runtime initialization code to know what the
> boundaries of the constructor pointer list are. This still is all
> generated by the compiler and linker automatically.
>
> However, we just tried compiling our driver for the AMD64 processor in
> preparation for XP AMD64 notebooks coming out soon, and it appears
> that that compiler puts the XCA and XCZ segments in an area unrelated
> .CRT$XCU. Therefore I don’t know how to find them from our
> initialization code any more.
>
> Has anyone run into this, and if so, what was the workaround?
>
> Of course, our next step will be to reverse engineering the CRTL for
> this compiler… I was just hoping not to needlessly replicate that
> effort…
> –
> …/ray..
>
>
>

Thanks much! That worked great. Looks like it would have been tricky
to reverse engineer that particular bit of magic incantation, too…

Bill McKenzie wrote:

>Has anyone run into this, and if so, what was the workaround?

Yep, we have. For x86 you would do something like this, right?

#pragma data_seg(“.CRT$XCA”)
void (*_StartInitCalls[1])(void)={0};

For IA64/AMD64 you need something like this to accomplish the same:

#pragma section(“.CRT$XCA”,long,read)
__declspec(allocate(“.CRT$XCA”)) void (*_StartInitCalls[1])(void)={0};


Bill McKenzie
Compuware Corporation
Watch your IRPs/IRBs/URBs/SRBs/NDIS pkts with our free WDMSniffer tool:
http://frontline.compuware.com/nashua/patches/utility.htm

“Ray Trent” wrote in message news:xxxxx@ntdev…
>
>>We use C++ for our driver (no flamewars, please :-). Anyway, to do
>>this, one thing you need to do is come up with some way to call the
>>constructors for your global/static objects.
>>
>>There’s a pretty standard way to do this, described in
>>http://msdn.microsoft.com/msdnmag/issues/01/01/hood/, that involves
>>calling the functions pointed to in a specially named data segment
>>called .CRT$XCU. The compiler puts all the static objects’
>>constructors in this named segment so that they all get linked
>>together in one place. This is normally bracketed by a couple of data
>>segments called .CRT$XCA and .CRT$XCZ (which contain some globally
>>accessible specially named variables so you can find them). That way
>>there’s some way for the runtime initialization code to know what the
>>boundaries of the constructor pointer list are. This still is all
>>generated by the compiler and linker automatically.
>>
>>However, we just tried compiling our driver for the AMD64 processor in
>>preparation for XP AMD64 notebooks coming out soon, and it appears
>>that that compiler puts the XCA and XCZ segments in an area unrelated
>>.CRT$XCU. Therefore I don’t know how to find them from our
>>initialization code any more.
>>
>>Has anyone run into this, and if so, what was the workaround?
>>
>>Of course, our next step will be to reverse engineering the CRTL for
>>this compiler… I was just hoping not to needlessly replicate that
>>effort…
>>–
>>…/ray..
>>
>>
>>
>
>
>
>
>


…/ray..

One of my colleagues beat his head against the wall for a good half a day
trying to figure this out originally. He suggested I post this to save you
the head injury :slight_smile:

Glad it helped!


Bill McKenzie
Compuware Corporation
Watch your IRPs/IRBs/URBs/SRBs/NDIS pkts with our free WDMSniffer tool:
http://frontline.compuware.com/nashua/patches/utility.htm

“Ray Trent” wrote in message news:xxxxx@ntdev…
>
> Thanks much! That worked great. Looks like it would have been tricky
> to reverse engineer that particular bit of magic incantation, too…
>
> Bill McKenzie wrote:
>
> >>Has anyone run into this, and if so, what was the workaround?
> >
> >
> > Yep, we have. For x86 you would do something like this, right?
> >
> > #pragma data_seg(“.CRT$XCA”)
> > void (* _StartInitCalls [1])(void)={0};
> >
> > For IA64/AMD64 you need something like this to accomplish the same:
> >
> > #pragma section(“.CRT$XCA”,long,read)
> > __declspec(allocate(“.CRT$XCA”)) void
(*_StartInitCalls[1])(void)={0};
> >
> > –
> > Bill McKenzie
> > Compuware Corporation
> > Watch your IRPs/IRBs/URBs/SRBs/NDIS pkts with our free WDMSniffer tool:
> > http://frontline.compuware.com/nashua/patches/utility.htm
> >
> >
> > “Ray Trent” wrote in message news:xxxxx@ntdev…
> >
> >>We use C++ for our driver (no flamewars, please :-). Anyway, to do
> >>this, one thing you need to do is come up with some way to call the
> >>constructors for your global/static objects.
> >>
> >>There’s a pretty standard way to do this, described in
> >>http://msdn.microsoft.com/msdnmag/issues/01/01/hood/, that involves
> >>calling the functions pointed to in a specially named data segment
> >>called .CRT$XCU. The compiler puts all the static objects’
> >>constructors in this named segment so that they all get linked
> >>together in one place. This is normally bracketed by a couple of data
> >>segments called .CRT$XCA and .CRT$XCZ (which contain some globally
> >>accessible specially named variables so you can find them). That way
> >>there’s some way for the runtime initialization code to know what the
> >>boundaries of the constructor pointer list are. This still is all
> >>generated by the compiler and linker automatically.
> >>
> >>However, we just tried compiling our driver for the AMD64 processor in
> >>preparation for XP AMD64 notebooks coming out soon, and it appears
> >>that that compiler puts the XCA and XCZ segments in an area unrelated
> >>.CRT$XCU. Therefore I don’t know how to find them from our
> >>initialization code any more.
> >>
> >>Has anyone run into this, and if so, what was the workaround?
> >>
> >>Of course, our next step will be to reverse engineering the CRTL for
> >>this compiler… I was just hoping not to needlessly replicate that
> >>effort…
> >>–
> >>…/ray..
> >>
> >>
> >>
> >
> >
> >
> >
> >
>
>
> –
> …/ray..
>
>
>

From a “least surprise” perspective, though, you should really avoid
dependending on static initializers/destructors, aside from normal C
variable initialization. Developers of NT device drivers really expect
all significant initialization work to occur in DriverEntry, and NOT
before. The cleanest way to maintain global data is usually to use an
overloaded operator new, or directly call your favorite kernel-mode pool
allocator, from DriverEntry. (And of course, free it during
DriverUnload.)

I say this mostly from the point of view of code base maintenance. If
someone needs to debug or work on your driver, and they are familiar
with NT device drivers, they will ordinarily assume
DriverEntry/DriverUnload handles all real init/shutdown. Anything else
will come as a surprise. The degree of the surprise may range from
curiosity to blue screen.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Bill McKenzie
Sent: Tuesday, August 26, 2003 2:12 PM
To: Windows System Software Developers Interest List
Subject: [ntdev] Re: C++ static construction on AMD 64?

Has anyone run into this, and if so, what was the workaround?

Yep, we have. For x86 you would do something like this, right?

#pragma data_seg(“.CRT$XCA”)
void (*_StartInitCalls[1])(void)={0};

For IA64/AMD64 you need something like this to accomplish the same:

#pragma section(“.CRT$XCA”,long,read)
__declspec(allocate(“.CRT$XCA”)) void
(*_StartInitCalls[1])(void)={0};


Bill McKenzie
Compuware Corporation
Watch your IRPs/IRBs/URBs/SRBs/NDIS pkts with our free WDMSniffer tool:
http://frontline.compuware.com/nashua/patches/utility.htm

“Ray Trent” wrote in message news:xxxxx@ntdev…
>
> We use C++ for our driver (no flamewars, please :-). Anyway, to do
> this, one thing you need to do is come up with some way to call the
> constructors for your global/static objects.
>
> There’s a pretty standard way to do this, described in
> http://msdn.microsoft.com/msdnmag/issues/01/01/hood/, that involves
> calling the functions pointed to in a specially named data segment
> called .CRT$XCU. The compiler puts all the static objects’
> constructors in this named segment so that they all get linked
> together in one place. This is normally bracketed by a couple of data
> segments called .CRT$XCA and .CRT$XCZ (which contain some globally
> accessible specially named variables so you can find them). That way
> there’s some way for the runtime initialization code to know what the
> boundaries of the constructor pointer list are. This still is all
> generated by the compiler and linker automatically.
>
> However, we just tried compiling our driver for the AMD64 processor in

> preparation for XP AMD64 notebooks coming out soon, and it appears
> that that compiler puts the XCA and XCZ segments in an area unrelated
> .CRT$XCU. Therefore I don’t know how to find them from our
> initialization code any more.
>
> Has anyone run into this, and if so, what was the workaround?
>
> Of course, our next step will be to reverse engineering the CRTL for
> this compiler… I was just hoping not to needlessly replicate that
> effort…
> –
> …/ray..
>
>
>


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@sublinear.org To
unsubscribe send a blank email to xxxxx@lists.osr.com

One could call global constructors “manually” during DriverEntry() and,
conversely, global destructors during DriverUnload().

On the other hand, anyone familar with the C runtime knows that “things
can happen” before main(), and similarly anyone familiar with C++ knows
that objects can be constructed before main(). The chance that someone
else may encounter difficulty debugging my code due to their own
ignorance is, to me, not a compelling reason to change the way I code.

Chuck

----- Original Message -----
From: “Arlie Davis”
To: “Windows System Software Developers Interest List”

Sent: Wednesday, August 27, 2003 10:56 AM
Subject: [ntdev] Re: C++ static construction on AMD 64?

> >From a “least surprise” perspective, though, you should really avoid
> dependending on static initializers/destructors, aside from normal C
> variable initialization. Developers of NT device drivers really
expect
> all significant initialization work to occur in DriverEntry, and NOT
> before. The cleanest way to maintain global data is usually to use an
> overloaded operator new, or directly call your favorite kernel-mode
pool
> allocator, from DriverEntry. (And of course, free it during
> DriverUnload.)
>
> I say this mostly from the point of view of code base maintenance. If
> someone needs to debug or work on your driver, and they are familiar
> with NT device drivers, they will ordinarily assume
> DriverEntry/DriverUnload handles all real init/shutdown. Anything
else
> will come as a surprise. The degree of the surprise may range from
> curiosity to blue screen.

Argh, we are about to descend into the C++ in the kernel flame war. If you
don’t like C++ in the kernel, you certainly won’t like global constructors.
On the other hand, if you are using C++, you really do want as much standard
functionality as possible. The exception is exceptions. We’ve had this
discussion, there is nothing new to say here, other than the great code
segment from Numega illustrating how to support 64bit segments.

=====================
Mark Roddy
Hollis Technology Solutions
www.hollistech.com
xxxxx@hollistech.com

-----Original Message-----
From: Chuck Batson [mailto:xxxxx@cbatson.com]
Sent: Wednesday, August 27, 2003 1:09 AM
To: Windows System Software Developers Interest List
Subject: [ntdev] Re: C++ static construction on AMD 64?

One could call global constructors “manually” during DriverEntry() and,
conversely, global destructors during DriverUnload().

On the other hand, anyone familar with the C runtime knows that “things can
happen” before main(), and similarly anyone familiar with C++ knows that
objects can be constructed before main(). The chance that someone else may
encounter difficulty debugging my code due to their own ignorance is, to me,
not a compelling reason to change the way I code.

Chuck

----- Original Message -----
From: “Arlie Davis”
To: “Windows System Software Developers Interest List”
Sent: Wednesday, August 27, 2003 10:56 AM
Subject: [ntdev] Re: C++ static construction on AMD 64?

> >From a “least surprise” perspective, though, you should really avoid
> dependending on static initializers/destructors, aside from normal C
> variable initialization. Developers of NT device drivers really
expect
> all significant initialization work to occur in DriverEntry, and NOT
> before. The cleanest way to maintain global data is usually to use an
> overloaded operator new, or directly call your favorite kernel-mode
pool
> allocator, from DriverEntry. (And of course, free it during
> DriverUnload.)
>
> I say this mostly from the point of view of code base maintenance. If
> someone needs to debug or work on your driver, and they are familiar
> with NT device drivers, they will ordinarily assume
> DriverEntry/DriverUnload handles all real init/shutdown. Anything
else
> will come as a surprise. The degree of the surprise may range from
> curiosity to blue screen.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@stratus.com To
unsubscribe send a blank email to xxxxx@lists.osr.com

Not flaming anything. Arlie suggested one should base one’s coding
practices on the expectations of potential maintainers or
troubleshooters, which I happen to disagree with. I wouldn’t want to
write code in such a way as to compensate for someone else’s ignorance
in an area in which they (a hypothetical maintainer or troubleshooter)
should be knowledgeable. If they’re not appropriately versed in the
relevant area(s), they get what they have coming.

I’m not referring to any particular programming language.

Chuck

----- Original Message -----
From: “Roddy, Mark”
To: “Windows System Software Developers Interest List”

Sent: Wednesday, August 27, 2003 8:03 PM
Subject: [ntdev] Re: C++ static construction on AMD 64?

> Argh, we are about to descend into the C++ in the kernel flame war. If
you
> don’t like C++ in the kernel, you certainly won’t like global
constructors.
> On the other hand, if you are using C++, you really do want as much
standard
> functionality as possible. The exception is exceptions. We’ve had this
> discussion, there is nothing new to say here, other than the great
code
> segment from Numega illustrating how to support 64bit segments.
>
>
> =====================
> Mark Roddy
> Hollis Technology Solutions
> www.hollistech.com
> xxxxx@hollistech.com
>
>
> -----Original Message-----
> From: Chuck Batson [mailto:xxxxx@cbatson.com]
> Sent: Wednesday, August 27, 2003 1:09 AM
> To: Windows System Software Developers Interest List
> Subject: [ntdev] Re: C++ static construction on AMD 64?
>
>
> One could call global constructors “manually” during DriverEntry()
and,
> conversely, global destructors during DriverUnload().
>
> On the other hand, anyone familar with the C runtime knows that
“things can
> happen” before main(), and similarly anyone familiar with C++ knows
that
> objects can be constructed before main(). The chance that someone
else may
> encounter difficulty debugging my code due to their own ignorance is,
to me,
> not a compelling reason to change the way I code.
>
> Chuck
>
> ----- Original Message -----
> From: “Arlie Davis”
> To: “Windows System Software Developers Interest List”

> Sent: Wednesday, August 27, 2003 10:56 AM
> Subject: [ntdev] Re: C++ static construction on AMD 64?
>
>
> > >From a “least surprise” perspective, though, you should really
avoid
> > dependending on static initializers/destructors, aside from normal C
> > variable initialization. Developers of NT device drivers really
> expect
> > all significant initialization work to occur in DriverEntry, and NOT
> > before. The cleanest way to maintain global data is usually to use
an
> > overloaded operator new, or directly call your favorite kernel-mode
> pool
> > allocator, from DriverEntry. (And of course, free it during
> > DriverUnload.)
> >
> > I say this mostly from the point of view of code base maintenance.
If
> > someone needs to debug or work on your driver, and they are familiar
> > with NT device drivers, they will ordinarily assume
> > DriverEntry/DriverUnload handles all real init/shutdown. Anything
> else
> > will come as a surprise. The degree of the surprise may range from
> > curiosity to blue screen.
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@stratus.com To
> unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@cbatson.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

Sorry, I agree with Arlie on this. I have seen too many drivers with “cute
code” in them, where the original developer claims it was obvious to him.
Funny thing is half the time when you ask them after they have not looked at
the code for a while, they have to do a major analysis to understand it
themselves.

I am not picking on C++, or any other construct, but one should be
constantly asking themselves “Is this the best way to do x, given the norm
in development?”. C++ (at the full language) is not the norm for driver
development, if it truly simplifies your design and code to the point that
the costs (such as the workarounds that lead to this thread) are justified,
well and good. But, it is all to often I see “This is neat so lets use it”
when there is no need for such an approach, and in the end reliability and
maintability suffer.

Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting

----- Original Message -----
From: “Chuck Batson”
To: “Windows System Software Developers Interest List”
Sent: Wednesday, August 27, 2003 9:20 AM
Subject: [ntdev] Re: C++ static construction on AMD 64?

> Not flaming anything. Arlie suggested one should base one’s coding
> practices on the expectations of potential maintainers or
> troubleshooters, which I happen to disagree with. I wouldn’t want to
> write code in such a way as to compensate for someone else’s ignorance
> in an area in which they (a hypothetical maintainer or troubleshooter)
> should be knowledgeable. If they’re not appropriately versed in the
> relevant area(s), they get what they have coming.
>
> I’m not referring to any particular programming language.
>
> Chuck

I see no mystery here, what’s the big deal ? If you need something global,
create the object in DriverEntry, it’s that simple. There should be no
“norm” for driver development, who needs straightjackets ? And using C++
increases reliability.

Alberto.

-----Original Message-----
From: Don Burn [mailto:xxxxx@acm.org]
Sent: Wednesday, August 27, 2003 9:40 AM
To: Windows System Software Developers Interest List
Subject: [ntdev] Re: C++ static construction on AMD 64?

Sorry, I agree with Arlie on this. I have seen too many drivers with “cute
code” in them, where the original developer claims it was obvious to him.
Funny thing is half the time when you ask them after they have not looked at
the code for a while, they have to do a major analysis to understand it
themselves.

I am not picking on C++, or any other construct, but one should be
constantly asking themselves “Is this the best way to do x, given the norm
in development?”. C++ (at the full language) is not the norm for driver
development, if it truly simplifies your design and code to the point that
the costs (such as the workarounds that lead to this thread) are justified,
well and good. But, it is all to often I see “This is neat so lets use it”
when there is no need for such an approach, and in the end reliability and
maintability suffer.

Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting

----- Original Message -----
From: “Chuck Batson”
To: “Windows System Software Developers Interest List”
Sent: Wednesday, August 27, 2003 9:20 AM
Subject: [ntdev] Re: C++ static construction on AMD 64?

> Not flaming anything. Arlie suggested one should base one’s coding
> practices on the expectations of potential maintainers or
> troubleshooters, which I happen to disagree with. I wouldn’t want to
> write code in such a way as to compensate for someone else’s ignorance
> in an area in which they (a hypothetical maintainer or troubleshooter)
> should be knowledgeable. If they’re not appropriately versed in the
> relevant area(s), they get what they have coming.
>
> I’m not referring to any particular programming language.
>
> Chuck


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@compuware.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

The contents of this e-mail are intended for the named addressee only. It
contains information that may be confidential. Unless you are the named
addressee or an authorized designee, you may not copy or use it, or disclose
it to anyone else. If you received it in error please notify us immediately
and then destroy it.

I agree that poorly-documented “cute tricks” can be difficult to
maintain, even for the original author. However, I expect a programmer
to be familiar with the language he or she is using. Knowledge of (or
at least awareness of) things defined in the language standard are a
prerequisite… for example, the consequences of global object
construction/destruction in C++, or atexit() in C – which for the
unaware could have just as “surprising” an effect.

Chuck

----- Original Message -----
From: “Don Burn”
To: “Windows System Software Developers Interest List”

Sent: Wednesday, August 27, 2003 8:39 PM
Subject: [ntdev] Re: C++ static construction on AMD 64?

> Sorry, I agree with Arlie on this. I have seen too many drivers with
“cute
> code” in them, where the original developer claims it was obvious to
him.
> Funny thing is half the time when you ask them after they have not
looked at
> the code for a while, they have to do a major analysis to understand
it
> themselves.
>
> I am not picking on C++, or any other construct, but one should be
> constantly asking themselves “Is this the best way to do x, given the
norm
> in development?”. C++ (at the full language) is not the norm for
driver
> development, if it truly simplifies your design and code to the point
that
> the costs (such as the workarounds that lead to this thread) are
justified,
> well and good. But, it is all to often I see “This is neat so lets
use it”
> when there is no need for such an approach, and in the end reliability
and
> maintability suffer.
>
> Don Burn (MVP, Windows DDK)
> Windows 2k/XP/2k3 Filesystem and Driver Consulting
>
> ----- Original Message -----
> From: “Chuck Batson”
> To: “Windows System Software Developers Interest List”

> Sent: Wednesday, August 27, 2003 9:20 AM
> Subject: [ntdev] Re: C++ static construction on AMD 64?
>
>
> > Not flaming anything. Arlie suggested one should base one’s coding
> > practices on the expectations of potential maintainers or
> > troubleshooters, which I happen to disagree with. I wouldn’t want
to
> > write code in such a way as to compensate for someone else’s
ignorance
> > in an area in which they (a hypothetical maintainer or
troubleshooter)
> > should be knowledgeable. If they’re not appropriately versed in the
> > relevant area(s), they get what they have coming.
> >
> > I’m not referring to any particular programming language.
> >
> > Chuck

This is simply the C++ in the kernel flame war. Please stop. We are not
going to convince anyone to switch sides.

=====================
Mark Roddy
Hollis Technology Solutions
www.hollistech.com
xxxxx@hollistech.com

-----Original Message-----
From: Don Burn [mailto:xxxxx@acm.org]
Sent: Wednesday, August 27, 2003 9:40 AM
To: Windows System Software Developers Interest List
Subject: [ntdev] Re: C++ static construction on AMD 64?

Sorry, I agree with Arlie on this. I have seen too many drivers with “cute
code” in them, where the original developer claims it was obvious to him.
Funny thing is half the time when you ask them after they have not looked at
the code for a while, they have to do a major analysis to understand it
themselves.

I am not picking on C++, or any other construct, but one should be
constantly asking themselves “Is this the best way to do x, given the norm
in development?”. C++ (at the full language) is not the norm for driver
development, if it truly simplifies your design and code to the point that
the costs (such as the workarounds that lead to this thread) are justified,
well and good. But, it is all to often I see “This is neat so lets use it”
when there is no need for such an approach, and in the end reliability and
maintability suffer.

Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting

----- Original Message -----
From: “Chuck Batson”
To: “Windows System Software Developers Interest List”
Sent: Wednesday, August 27, 2003 9:20 AM
Subject: [ntdev] Re: C++ static construction on AMD 64?

> Not flaming anything. Arlie suggested one should base one’s coding
> practices on the expectations of potential maintainers or
> troubleshooters, which I happen to disagree with. I wouldn’t want to
> write code in such a way as to compensate for someone else’s ignorance
> in an area in which they (a hypothetical maintainer or troubleshooter)
> should be knowledgeable. If they’re not appropriately versed in the
> relevant area(s), they get what they have coming.
>
> I’m not referring to any particular programming language.
>
> Chuck


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@stratus.com To
unsubscribe send a blank email to xxxxx@lists.osr.com

> This is simply the C++ in the kernel flame war. Please stop. We are not

going to convince anyone to switch sides.

Amen brother.

Geeze, it’s always the same posts from the same folks. How about we just
all cut and paste from some previous C++ flame war and be done with it?


Bill McKenzie
Compuware Corporation
Watch your IRPs/IRBs/URBs/SRBs/NDIS pkts with our free WDMSniffer tool:
http://frontline.compuware.com/nashua/patches/utility.htm

Thanks for the suggestion. Actually, we do that already. We just do it
in a slightly more complicated than usual way.

Where did you think I was calling my CppInit function *from*, anyway? :slight_smile:

BTW, I agree that flamewars about C++ in drivers aren’t needed here…
in fact, that’s why I specifically asked for no flamewars in my
original posting… Suffice it to say that some people will think the
maintainability advantages of C++ outweigh the maintainability
disadvantages of C++ and others won’t.

Arlie Davis wrote:

From a “least surprise” perspective, though, you should really avoid
dependending on static initializers/destructors, aside from normal C
variable initialization. Developers of NT device drivers really expect
all significant initialization work to occur in DriverEntry, and NOT
before. The cleanest way to maintain global data is usually to use an
overloaded operator new, or directly call your favorite kernel-mode pool
allocator, from DriverEntry. (And of course, free it during
DriverUnload.)

I say this mostly from the point of view of code base maintenance. If
someone needs to debug or work on your driver, and they are familiar
with NT device drivers, they will ordinarily assume
DriverEntry/DriverUnload handles all real init/shutdown. Anything else
will come as a surprise. The degree of the surprise may range from
curiosity to blue screen.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Bill McKenzie
Sent: Tuesday, August 26, 2003 2:12 PM
To: Windows System Software Developers Interest List
Subject: [ntdev] Re: C++ static construction on AMD 64?

>Has anyone run into this, and if so, what was the workaround?

Yep, we have. For x86 you would do something like this, right?

#pragma data_seg(“.CRT$XCA”)
void (*_StartInitCalls[1])(void)={0};

For IA64/AMD64 you need something like this to accomplish the same:

#pragma section(“.CRT$XCA”,long,read)
__declspec(allocate(“.CRT$XCA”)) void
(*_StartInitCalls[1])(void)={0};


Bill McKenzie
Compuware Corporation
Watch your IRPs/IRBs/URBs/SRBs/NDIS pkts with our free WDMSniffer tool:
http://frontline.compuware.com/nashua/patches/utility.htm

“Ray Trent” wrote in message news:xxxxx@ntdev…
>
>>We use C++ for our driver (no flamewars, please :-). Anyway, to do
>>this, one thing you need to do is come up with some way to call the
>>constructors for your global/static objects.
>>
>>There’s a pretty standard way to do this, described in
>>http://msdn.microsoft.com/msdnmag/issues/01/01/hood/, that involves
>>calling the functions pointed to in a specially named data segment
>>called .CRT$XCU. The compiler puts all the static objects’
>>constructors in this named segment so that they all get linked
>>together in one place. This is normally bracketed by a couple of data
>>segments called .CRT$XCA and .CRT$XCZ (which contain some globally
>>accessible specially named variables so you can find them). That way
>>there’s some way for the runtime initialization code to know what the
>>boundaries of the constructor pointer list are. This still is all
>>generated by the compiler and linker automatically.
>>
>>However, we just tried compiling our driver for the AMD64 processor in
>
>
>>preparation for XP AMD64 notebooks coming out soon, and it appears
>>that that compiler puts the XCA and XCZ segments in an area unrelated
>>.CRT$XCU. Therefore I don’t know how to find them from our
>>initialization code any more.
>>
>>Has anyone run into this, and if so, what was the workaround?
>>
>>Of course, our next step will be to reverse engineering the CRTL for
>>this compiler… I was just hoping not to needlessly replicate that
>>effort…
>>–
>>…/ray..
>>
>>
>>
>
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@sublinear.org To
> unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>


…/ray..

I’ve supported C++ in no-static-constructor mode since the days of cfront,
simply by disallowing static constructors. A DriverEntry procedure would
seem to be an ideal place to trigger a manual replacement mechanism.

Better … give it a number and post the list of numbers in the FAQ.

Flame War numb:

  1. C++ versus C.
  2. WinDbg versus Softice.

Hmmm this gives me an idea on how to approach an article Walter ask me to
do. Right now I’m thinking of taking the tone of Andy Rooney and postulating
the fine art of answering stupid questions. :slight_smile:


Gary G. Little
Seagate Technologies, LLC

“Bill McKenzie” wrote in message
news:xxxxx@ntdev…
>
> > This is simply the C++ in the kernel flame war. Please stop. We are not
> > going to convince anyone to switch sides.
>
> Amen brother.
>
> Geeze, it’s always the same posts from the same folks. How about we just
> all cut and paste from some previous C++ flame war and be done with it?
>
> –
> Bill McKenzie
> Compuware Corporation
> Watch your IRPs/IRBs/URBs/SRBs/NDIS pkts with our free WDMSniffer tool:
> http://frontline.compuware.com/nashua/patches/utility.htm
>
>
>
>