what good is a bad pointer - rosco-pc/propeller-wiki GitHub Wiki

what defines bad ?

In the bad old days [of C], a bad pointer was one which did not point to a valid addressable object. This could come from any of 3 things:

  1. a dereference on a null pointer - often location 0 in memory had 'code' in it and just as often that code was a valid instruction which when 'de-referenced' yielded either a /good/ (but unexpected) valid memory address or an invalid one. Either way - a bad idea.
  2. a non existent memory address - completely outside the physical memory of the machine
  3. an unsupported memory address - unsupported may mean valid (present) but likely to be clobbered by the model because its use is reserved to another purpose such as below the stack or amid (freed) heap or code. All but the latter would be subject to change in mysterious ways (stack for instance would vary during an interrupt or call to another function) and the latter (code) had better be the start of a real function. A final 'unsupported' memory address is one which incorrectly points 'inside' an object inadvertently.

Is it possible to turn these 3 cases around to make them either 'safer', useful or meaningful? I don't plan to make all memory valid - that's what virtualization does... and virtualization /is not/ what we need. (it really does little to handle case 3).

For case 1 (NULL)

Lets start simple. Can a null pointer be made a little 'safer' in case it IS actually dereferenced. Many C compiler vendors selected one of 3 ways to handle this (sometimes with help of the operating system).

  • make low memory non-existent to simply map case #2 back to case #1.
  • put the string "Null\0" into the lowest memory location (somehow)
  • put a zero at that location so that Null points to Null ad-infinitum (my favorite)

Is this sufficient? Lets try to see if all of the other cases can be made to work...

For case 3 (unsupported) Life gets interesting here. When there is plenty of memory and Mhz to go around, one can use 'electric-fence' and similar tools to detect pointers that are given values unexpectedly. On a micro controller like the prop, you don't have this luxury. Never the less, one can at least limit values to be in the ranges of "on the stack"(vs below the stack) "in data" and "in (allocated) heap" and finally "at beginning of function" by doing different kinds of costly runtime checking. We may come back to this one...

For case 2 (non-existent) On many architectures, a non-existent memory address reference causes a trap or an exception. This is not true on many newer chips like the Prop.

At a minimum, when one 'walks off the end' of memory some known value is returned (such as all bits on or off). This value can be checked-for though at some performance cost. Perhaps a useful cost if debugging is enabled. Of course if the value IS all off, one can fairly quickly check the condition codes and if the value IS all on, one can compare that to the known highest writable memory address.

[ROM addresses are probably not a concern as very few access to ROM occur in uncontrolled ways.]

The point is, this case often does get caught and mapped into a specific value. It would depend a lot on the application being able to judge if that value could be confused with with real potential data values (0 or ~0). When following a linked list, this would be fine as its fair to quickly test for 0 or ~0 at each link juncture.

But what if a non-existent memory address were /intentionally/ used to signal something special? Remember in the early Apple days when illegal instructions were used to tickle (get into) the operating system? What if we gave meaning to certain special pointer values?

So long as the pointer wasn't confusable with valid memory locations, then one could use these pointer-values (or ranges thereof) to reference memory on other devices or perhaps even in other systems (given cooperation by the part of the system that 'looks-up' where a pointer goes).

Now hold on before trying to map every device on the planet into a 32 bit address space! I know its tempting for an engineer to want to plan out where everything is. Resist! Such things are the realm of a linker or dynamic library loader (which will be covered in another article) .