Why was Intel a no-show on No Execute?

R

Robert Redelmeier

In comp.sys.ibm.pc.hardware.chips Sander Vesik said:
No I simply have short temper with those who continue
rambling on even when they have obviously no clue.

A short temper is a shortcoming in itself. It must hurt you.
If cluelessness is obvious, why add to the discussion?
Neither you nor anyone else is appointed the USENET police
to correct all postings.

-- Robert
 
P

Peter \Firefly\ Lund

a totally different reason -- gets() and it's evil siblings
are almost certainly blocking syscalls. A task switch to a
different process is likely and the hw stack will be flooded.

Since most operating systems these days have preemptive multitasking, you
will need to save/restore the hw stack in the context switch function
inside the OS anyway, won't you?

Oh, and have some mechanism that stops the hw stack from getting updated
in supervisor mode?

Or have /two/ hw stacks, so supervisor mode doesn't slow down?
Better to save/fingerprint the stack on entry and abort
if trampled as I explain elsewhere.

Yes, much better solution.

Aren't all OpenBSD utilities compiled with stack canaries, these days?

-Peter

PS: They are right, you really don't know anything about exception
handling in C++, Java, ML, Haskell, ...
 
Y

Yousuf Khan

Peter "Firefly" Lund said:
Not quite. To compensate for the lack of write-but-not-execute and
execute-but-not-write modes for the pages.

Well, so what did I say that was "not quite"?

Yousuf Khan
 
R

Robert Redelmeier

In comp.sys.ibm.pc.hardware.chips "Peter \"Firefly\" Lund said:
Since most operating systems these days have preemptive multitasking, you
will need to save/restore the hw stack in the context switch function
inside the OS anyway, won't you?

Unfortunately, the hw stack is programmer inaccessible AFAIK.
Just a part of the branch prediction mechanism.

Unworkable as a hw solution to buffer overflows
ins gets() amost certainly will cause a task swap.

-- Robert
 
C

Christian Bau

KR Williams said:
Rather than being a little argumentative prig, why don't you
educate us?


There are plenty of documents around on the internet. There is a draft
specification of the C++ Standard available for free, which will explain
C++ exceptions. And at www.sun.com you will find both the Java Language
Specification and the Java Virtual Machine Specification, both available
for free, which you can download and educate yourself.
 
R

Rupert Pigott

Christian said:
[SNIP]
Rather than being a little argumentative prig, why don't you
educate us?



There are plenty of documents around on the internet. There is a draft
specification of the C++ Standard available for free, which will explain
C++ exceptions. And at www.sun.com you will find both the Java Language
Specification and the Java Virtual Machine Specification, both available
for free, which you can download and educate yourself.

ROTFL, it never rains but it pours, eh Keith ? :)

I take it that you still haven't visited the "irrelevant" OpenGL.org
yet, or followed up the van Dam refs I gave you...

FWIW think C.Bau is being much harsher than I, the C++ standard is a
--ing tome++ and it was full of thinkos, errors and contradictions.
Despite that it is nigh-on essential reading if you're going to look
at exceptions. Sigh, about time I re-read bits of it myself. :(

Cheers,
Rupert
 
P

Peter \Firefly\ Lund

Unfortunately, the hw stack is programmer inaccessible AFAIK.
Just a part of the branch prediction mechanism.

Yes, but you were going to change that anyway, weren't you?

(or was it somebody else's idea? I forget already)
Unworkable as a hw solution to buffer overflows
ins gets() amost certainly will cause a task swap.

How often do you read from stdin in a server or root program? Well, with
CGI, but isn't that just about it?

Most buffer overflows don't happen where the I/O takes place, I think.
(this is backed by regular reading about unix/linux security holes for
years on lwn.net)

Besides, stdio is buffered so not every call to gets() leads to a system
call. Far from it, in fact, unles you are reading something a human
types, as s/h/it types it.

-Peter
 
K

KR Williams

roo@try- said:
Christian said:
[SNIP]
Rather than being a little argumentative prig, why don't you
educate us?



There are plenty of documents around on the internet. There is a draft
specification of the C++ Standard available for free, which will explain
C++ exceptions. And at www.sun.com you will find both the Java Language
Specification and the Java Virtual Machine Specification, both available
for free, which you can download and educate yourself.

ROTFL, it never rains but it pours, eh Keith ? :)

You think I worry about your lame "discussions"?
I take it that you still haven't visited the "irrelevant" OpenGL.org
yet, or followed up the van Dam refs I gave you...

No, and I have not intention of doing so anytime soon. Because
you think I should trudge through code that I likely wouldn't
understand doesn't mean those are my marching orders.
FWIW think C.Bau is being much harsher than I, the C++ standard is a
--ing tome++ and it was full of thinkos, errors and contradictions.
Despite that it is nigh-on essential reading if you're going to look
at exceptions. Sigh, about time I re-read bits of it myself. :(

Harsher? No, simply just as full of himself as are you. The
purpose of these forums is to educate and be educated. You two
are too full of yourselves to do the former. Why are you here?
....just to prove how much smarter you are than some simple
hardware dweebs? The arrogance is unbelievable. Personally, I
don't much care about this particular discussion, but would have
appreciated a hint a little deeper then "I'm right, go look it
up, you're too stupid to understand" attitude we're getting from
you two. No, this sort of thing isn't on my bed time reading
list.
 
S

Sander Vesik

In comp.arch Robert Redelmeier said:
A short temper is a shortcoming in itself. It must hurt you.
If cluelessness is obvious, why add to the discussion?
Neither you nor anyone else is appointed the USENET police
to correct all postings.

I don't believe I need an appointment for it.
 
R

Rupert Pigott

KR said:
roo@try- said:
Christian said:
[SNIP]


Rather than being a little argumentative prig, why don't you
educate us?

I didn't notice that this was cross-posted alt.flame come to think
of it. ;)
You think I worry about your lame "discussions"?

Not really because you don't actually participate in them. I am
a little concerned when you cross-post vitriol though. In this case
Bau is quite correct : the relevent stuff is freely available in the
standard, and it's --ing huge. Not really something you can condense
easily, better that the guy goes away, digests it then comes back
with some new material to discuss.
No, and I have not intention of doing so anytime soon. Because
you think I should trudge through code that I likely wouldn't
understand doesn't mean those are my marching orders.

That's a shame because I specifically chose them because they are
aimed at folks who are competant hard/soft types but don't have an
in depth knowledge of the topic. I found the van Dam book to be a
very useful primer myself.
Harsher? No, simply just as full of himself as are you. The
purpose of these forums is to educate and be educated. You two

The vast majority of USENET does not fit that model, comp.arch
has never really has been a spoon-feed group, although Mashey was
pretty good at it. :)
are too full of yourselves to do the former. Why are you here?
...just to prove how much smarter you are than some simple
hardware dweebs? The arrogance is unbelievable. Personally, I

No. I find it a bit bizarre that on the on hand you assert that
these groups are for facilitating education, yet on the other
hand you dismiss the use of references. Education does not
exclusively consist of being spoon-fed regurgitated text. IMO
that wastes everyone's time.
don't much care about this particular discussion, but would have
appreciated a hint a little deeper then "I'm right, go look it
up, you're too stupid to understand" attitude we're getting from
you two. No, this sort of thing isn't on my bed time reading
list.

It's a stock response in the *hardware* orientated comp.arch. In
truth it's become a lot tamer than it was, but they generally do
not really appreciate having to regurgitate stuff that is freely
available, why the hell should folks get spoon-fed ?

Cheers,
Rupert
 
S

spinlock

Did you say "stack fragmentation" and
"argument stack" and "linkage stack"?

1st) There is only one stack, every thing goes
on it.

2nd) The "stack" is linear, controlled by a single
pointer(ESP), there is no way to have fragmentation.

Rob Warnock said:
+---------------
| > I don't think it's _required_ by any standard that local vars are
| > allocated on the stack, but it sure makes memory managment easy.
|
| It also facilitates recursion and re-entrancy. But it needn't be the
| same stack as the return linkage pointer.
+---------------

But if you *don't* do it, then you have trouble with stack fragmentation
and/or collisions with your "argument stack" expanding at a different rate
than your "linkage stack", resulting in one or the other bumping into
arbitrary limits at inconvenient times. As a result, one or the other
of the stacks gets pushed off into the heap (usually the argument stack)
as a linked list of stack-allocated "malloc()" blocks [optimized by
allocating a bunch at a time], which puts a lot of stress on "malloc()",
or gets pushed into a separately-managed segment of address space, which
puts pressure on memory allocation in general and the dynamic loader in
particular.

We had some of these issues with the Am29000 Subroutine Calling Standard
(circa 1987), which had both a "register cache" stack for linkage
information and "small" arguments (which were passed in registers)
and a "memory" stack for "large" arguments (as well as *any* argument,
regardless of size, that the called subroutine referenced by address).[1]
Had the 29k CPU family ever made it into the 32-bit Unix[2] workstation
market, where as we know address space layout has become an issue
(especially with an ever-larger number of DLLs or DSOs competing for space),
the two-stack calling sequence could have become quite problematic.
[As it was, in the embedded-processor space it was pretty much a non-issue.]


-Rob

[1] Actually, the rule was that the first 16 *words* of arguments got
passed in registers and any further words of arguments got passed
on the memory stack, except that if the called routine referenced
any of the first 16 words by address (e.g., "&foo") then that word
and all subsequence words of the register args would get copied into
the memory stack at subroutine entry. Yes, this meant that whenever
the memory stack got used at all there was a 64-byte area at the
front reserved in case the first 16 words needed to be manifested
in memory. (*Ugh*)

[2] Both BSD and System-V ports were done to the Am29000 -- both were
quite straightforward since the 29k was a friendly target enviroment --
but shortly after both were up & running AMD chose not to promote
the 29k as a Unix engine, and they were abandoned.
 
R

Rob Warnock

+---------------
| Did you say "stack fragmentation" and "argument stack" and "linkage stack"?
+---------------

Yes, exactly so!

+---------------
| 1st) There is only one stack, every thing goes on it.
|
| 2nd) The "stack" is linear, controlled by a single
| pointer(ESP), there is no way to have fragmentation.
+---------------

Not in the Am29000 CPU family!! The linkage, register spill/fill, and
"small argument" stack pointer was register GR1, and the "large argument"
(and any addressed arguments) stack pointer was register MSP [a.k.a. GR125].

And there have certainly been other machines which didn't use single
linear stacks, e.g., early IBM S/360 code which statically allocated
register save blocks in the callers, which the callees dynamically
linked and unlinked (with back-pointers) without moving or "growing"
anything. The call stack was this a singly-linked list of static blocks
randomly scattered all over memory. [Yes, this did *not* support
recursive routines! At least, not this default linkage.]


-Rob
 
B

Brian Inglis

Well, I'm not entirely sure how these constructs are
implemented by the compilers, but I would expect a
simple `jmp` instruction. This does NOT disturb the
hw call/ret stack, nor pose any buffer-overflow danger.

longjmp resets the registers from the jmpbuf (except returned result
value is changed to longjmp argument) including stack and frame
pointers and returns as if from the earlier setjmp call, but with a
different returned result value.
 
N

Nick Maclaren

And there have certainly been other machines which didn't use single
linear stacks, e.g., early IBM S/360 code which statically allocated
register save blocks in the callers, which the callees dynamically
linked and unlinked (with back-pointers) without moving or "growing"
anything. The call stack was this a singly-linked list of static blocks
randomly scattered all over memory. [Yes, this did *not* support
recursive routines! At least, not this default linkage.]

Sorry, Rob, but that is completely wrong. Yes, it allowed recursive
routines, in at least three separate ways, all of which were used.
There was no requirement for the save areas to be static.


Regards,
Nick Maclaren.
 
R

Rob Warnock

+---------------
| >And there have certainly been other machines which didn't use single
| >linear stacks, e.g., early IBM S/360 code which statically allocated
| >register save blocks in the callers, which the callees dynamically
| >linked and unlinked (with back-pointers) without moving or "growing"
| >anything. The call stack was this a singly-linked list of static blocks
| >randomly scattered all over memory. [Yes, this did *not* support
| >recursive routines! At least, not this default linkage.]
|
| Sorry, Rob, but that is completely wrong. Yes, it allowed recursive
| routines, in at least three separate ways, all of which were used.
| There was no requirement for the save areas to be static.
+---------------

Sorry, I guess I misspoke. I didn't mean to imply that there was any
*requirement* for the save areas to be static, only that it was permitted
(if recursion wasn't needed). And for some programmers (at least, around
the shops where I was first exposed to S/360 code) it was their default
coding style, and that if you did that the resulting stack was therefore
non-linear (discontinuous).


-Rob
 
N

Nick Maclaren

|> +---------------
|> | >And there have certainly been other machines which didn't use single
|> | >linear stacks, e.g., early IBM S/360 code which statically allocated
|> | >register save blocks in the callers, which the callees dynamically
|> | >linked and unlinked (with back-pointers) without moving or "growing"
|> | >anything. The call stack was this a singly-linked list of static blocks
|> | >randomly scattered all over memory. [Yes, this did *not* support
|> | >recursive routines! At least, not this default linkage.]
|> |
|> | Sorry, Rob, but that is completely wrong. Yes, it allowed recursive
|> | routines, in at least three separate ways, all of which were used.
|> | There was no requirement for the save areas to be static.
|> +---------------
|>
|> Sorry, I guess I misspoke. I didn't mean to imply that there was any
|> *requirement* for the save areas to be static, only that it was permitted
|> (if recursion wasn't needed). And for some programmers (at least, around
|> the shops where I was first exposed to S/360 code) it was their default
|> coding style, and that if you did that the resulting stack was therefore
|> non-linear (discontinuous).

It is PERMITTED under Unix on RISC systems, too, and some compilers
for some languages have done it!

But, yes, 'stacks' could be discontiguous, and often were. That also
applied to quite a few languages that allowed recursion. The same
would be true on any Unix/RISC compiler that used similar techniques.


Regards,
Nick Maclaren.
 
S

Sander Vesik

In comp.arch spinlock said:
Did you say "stack fragmentation" and
"argument stack" and "linkage stack"?

He did - unfortunately it seems you didn't read any further...
1st) There is only one stack, every thing goes
on it.

There may be any numebr of stacks. There are in fact cases
where you need to either not have a stack (so *everything*
is heap allocated) or povide for an arbitrary number of
stacks which are grabrage-collectable. Like when implementing
scheme.
2nd) The "stack" is linear, controlled by a single
pointer(ESP), there is no way to have fragmentation.

Wrong again. The only requirement is that ESP (in the one
architecture that has it) points to something that has
a certain amount of "free" space next to it. Not just that,
but there are no limits to having multiple concurent stacks,
referenced from other registers.

Never mind that he was talking about AMD 29000 for most of
his message, something that you don't seem to have understood.
 
A

Andi Kleen

Not in the Am29000 CPU family!! The linkage, register spill/fill, and
"small argument" stack pointer was register GR1, and the "large argument"
(and any addressed arguments) stack pointer was register MSP [a.k.a. GR125].

And there have certainly been other machines which didn't use single
linear stacks, e.g., early IBM S/360 code which statically allocated

[...]

IA64 also has two stacks: a register stack and a data stack. Normally
it seems to be implemented by letting the data stack grow down and
the register stack grow up, towards each other. C and even normal
assembly programming doesn't ever see the register stack though, since
it it is handled transparently in the background.

Of course that is much easier on a 64bit architecture where wasting
some address space does not matter much. On a 32bit architecture
you could get into problems since you don't know how much
space is needed for both stacks in advance. When you're multithreaded
the problem multiplies. For example on current 32bit x86 linux the main
scalability barrier for the max number of threads supported per process
is how much virtual address space can be allocated for each
thread stack.

BTW I wonder how the IA64 32bit ABIs e.g. as used on HP-UX solve
that issue. Most likely they will only support a small number
of threads at least, or add inconvenient restrictions on max
recursion for threads.

-Andi
 
S

spinlock

Rob Warnock said:
+---------------
| Did you say "stack fragmentation" and "argument stack" and "linkage stack"?
+---------------

Yes, exactly so!

You posted to COMP.SYS.INTEL, I dont think they make the 29000.
The x86 architecture has one stack.

Regardless, no stack can be fragmented. Sorry, they are a singly-linked
list.
No way to delete in the middle.
+---------------
| 1st) There is only one stack, every thing goes on it.
|
| 2nd) The "stack" is linear, controlled by a single
| pointer(ESP), there is no way to have fragmentation.
+---------------

Not in the Am29000 CPU family!! The linkage, register spill/fill, and
"small argument" stack pointer was register GR1, and the "large argument"
(and any addressed arguments) stack pointer was register MSP [a.k.a. GR125].

And there have certainly been other machines which didn't use single
linear stacks, e.g., early IBM S/360 code which statically allocated
register save blocks in the callers, which the callees dynamically
linked and unlinked (with back-pointers) without moving or "growing"
anything. The call stack was this a singly-linked list of static blocks
randomly scattered all over memory. [Yes, this did *not* support
recursive routines! At least, not this default linkage.]


-Rob
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top