ARM7TDMI
I am trying to understand how effective the undefined instruction exception is at stopping uncontrolled execution in arm mode.
Out of the entire 32bit arm mode instruction space, how many patterns are considered invalid instructions? The docs say that some invalid patterns are not caught by the undefined instruction exception. How many?
Let's put it this way: I wouldn't bet my life on it.
It's also not supposed to stop uncontrolled execution (which may very well be uncontrolled execution of otherwise perfectly valid code), it's supposed to offer a facility to do things like emulating coprocessor instructions if the coprocessor is absent, help with debugging, etc.
Out of the entire 32bit arm mode instruction space, how many patterns are considered invalid instructions?
That depends on which version of the ARM architecture you're looking and on the presence or absence of coprocessors.
The docs say that some invalid patterns are not caught by the undefined instruction exception. How many?
This is described in great detail in the ARM architecture reference manual, chapter 3.13, "Extending the instruction set". "UNPREDICTABLE" instructions are not caught by the undefined instruction exception.
ARM7TDMI, no coprocessors. It should not be that hard to quantify, I just need a listing of all legal instructions as machine code, or just the total count.
The exact number is probably not important since it is no more than a few hundred. The valid 32bit instruction space is a subset of entire set of possible 32bit words. That subset would have to be so small such that random corruption of instruction memory would have a very high prob of producing an undefined instruction exception.
It is a different question as to if any likely failure mode would produce localized memory corruption without catastrophic failure of the device. Environmental effects might be one cause. External memory would also bring in soldering issues.
... I just need a listing of all legal instructions as machine code, or just the total count.
The exact number is probably not important since it is no more than a few hundred.
The branch instruction alone has only 3 fixed bits, the other 29 are its arguments. That's a total of 536870912 valid branch instructions.
It should not be that hard to quantify
Exactly. I don't think anyone has done it, so most likely you'll have to do it yourself. The information is in the ARM7TDMI Technical Reference Manual.
Precisely. Why would ARM use a 32-bit instruction space and then only have a few hundred valid instructions? That's what THUMB with its 16-bit instruction space is for, and even that has more than a few hundred valid instructions.
The largest block of undefined instructions has four fixed bits - that's "only" 2^28 undefined instructions out of 2^32 possible ones.
Actually, it's in the ARM architecture reference manual. The ARM7TDMI Technical Reference Manual does not contain the codes for the various instructions, it only lists the ones supported by that version of the ARM architecture.
And no one has invested the effort to calculate the chances of hitting an undefined instruction since the undefined instruction exception was not intended to be used as a safety feature.
OK, so I was a bit off in my count... If random corruption is only detected on average once out of every 16 words, it is a bit less immediate, but it still seems worth mentioning as a safety feature.
Similarly, it is useful to quantify the number of instructions susceptible to data abort and prefetch abort.
Corruption of instruction memory would also corrupt address fields. A given system will have a memory map that is a tiny fraction of the address space, so if every access outside the valid map could be caught, it would be a plus.
It seems that ARM devices supporting external memory do not take into account the actual device sizes for the purposes of generating exceptions. If the chip select space is 16MB but with only 1MB attached, no exception is generated for accesses beyond 1MB.
Custom external logic may be needed to add that level of safetly.
From my personal experience, when working with a Coldfire V2 MCU, it is often possible to find what caused an exception by just decoding the exception stack frame. On the other hand, a similar application on an ARM7TDMI-based MCU (STR710 family) would be long lost in the woods before it hit a CPU exception. That's because most exceptions were caused by corrupt pointers (I know, but it was early debugging stage) and the Coldfire CPU would generate an exception on the very first illegal memory access because legal memory space is very limited. I guess the moral of the story is: if you want to catch illegal memory accesses efficiently, get an MCU that supports it.