Subject: Re: cpufunc.h
To: John Fremlin <vii@users.sourceforge.net>
From: Richard Earnshaw <rearnsha@buzzard.freeserve.co.uk>
List: port-arm
Date: 05/31/2001 22:59:58
> set_current_stackptr is a low level primitive. Its semantics mean that
> it does lowlevel stuff. If you use it wrong, you get screwed. So
> what. Caveat emptor.
No; caveat the poor guy who's trying to work out why the kernel no-longer
runs correctly if built with gcc-8.7!
> (Ben Harris suggested that the compiler might
> mess with the stack with inline functions so I've turned it into a
> macro.)
Inline functions are probably no worse than macros in this context.
Except that there is no absoulte guarantee that a function will be
inlined; and that if it isn't and it tries to save a return value on the
stack before executing your asm, the return sequence will jump to
never-never land -- beware trying to build such a kernel with the
optimizer off, since all these will happen.
>
> Please explain in more detail the reason for which it is impossible to
> use.
Try the following:
extern void *newstack;
my_func()
{
printf("Running from old stack pointer\n");
set_current_stackptr(newstack);
printf("Running from new stack pointer: %d %d %d %d\n", 1, 2, 3, 4);
...
}
Nothing obviously wrong with this code, but you will almost certainly find
one of the following three things happens (and it may change depending on
the optimization options used when compiling):
1) the 5th argument to printf clobbers something important on your new
stack
2) The stack underflows if it was empty (which might fault)
3) an incorrect value is printed out.
However, my objection is as much conceptual as it is based on any known
problems that make it impossible right now.
My feeling is that you shouldn't be trying to encode something in the
middle of a C function that fundamentally breaks the model the compiler is
using. A function that switches to another stack (in a non-temporary
manner, as a subroutine might do) very definitely breaks this model.
Developing a compiler is as much about agreeing a contract between the
compiler developer and the programmer as it is about getting good
optimizations. I don't think this sort of asm is something that a
compiler developer can accept in such a contract so I (with my gcc
developer hat on) will make no guarantees that, even if it works now, it
will continue to work in the future with another release of the compiler.
I strongly believe that routines that want to mess with the stack in this
way (or, for that matter, want to switch processor mode), should kept
short and written entirely in assembler. The only time I'll change this
opinion is when C grows propper semantics for describing these operations
(since I think this is unlikely to happen, I guess that means I'm unlikely
to change my mind on this :-)
Note that this doesn't mean that I think all use of "asm" is bad.
Disabling (temporarily of course!) interrupts is perfectly OK; as is using
the swp instruction for semaphone type operations. But that doesn't mean
the feature should be abused by using it for things that just aren't
likely to be safe -- that way lies all the problems that Linux kernel
builds seem to have.
R.