Marc Schütz
Marc Schütz

Reputation: 1061

Does Linux require a user space stack?

Is there anything in the Linux kernel that requires a valid user space stack? I.e., if I were to write a program in such a way that it only accesses fixed memory locations in the data segment, or does some computations with registers only, could I safely set the stack pointer to 0 or another invalid address, or even to a valid address without having to fear the memory there to be overwritten?

Additional question: Does anyone know the answer to this question regarding other operating systems, e.g. MacOS X, the BSDs, Windows?

Upvotes: 0

Views: 285

Answers (1)

Gil Hamilton
Gil Hamilton

Reputation: 12347

I doubt anyone can tell you this with much confidence but I'll take a stab.

My guess is that it's technically possible to run with no stack but getting the details right will be very hard.

Interrupts and exceptions (page faults, for example) should save registers to a kernel stack not the user space stack so that's no problem. System calls should even work if coded directly in assembly. (Unless you are running in 32-bit mode and use more than 5 arguments, in which case the sixth is on the user stack, but you could still fix that up that easily enough.)

Debugging will be hard obviously; gdb expects your stack to be arranged just so.

Other things to think about:

Typically you are allocated a stack area at startup. Not sure; you might be able to change that with appropriate linker directives. The stack region is usually configured to grow downward. When there's a page fault at an address not in any currently allocated region, it's assumed that a stack region is to be grown. The faulting address must not be less than the value of sp (i.e. esp/rsp) (less a 64K fudge). I guess that's not a problem if you're not using a stack.

When you call the clone syscall to create a new task (thread), you provide a stack pointer for the new task. I'm not sure what exactly the kernel does with that, looks like it just stuffs into the sp register in the new task (if it's non-zero). Which leads me to...

The clone syscall and a number of others are not well-specified. There's a lot of magic embedded in libc to properly handle fork, pthread_create and so forth. You'll have to know that magic and implement it yourself if you want to create additional threads.

Signal handling expects to be able to push arguments onto the user space stack. I don't think you could use signals without a stack -- or at least it would be very complicated.

Upvotes: 1

Related Questions