SWI error blocks are the key mechanism by which errors are returned from SWIs. Whenever a SWI call exits with the V flag set, R0 will contain a pointer to an error block, with the following structure:
Offset | Contents |
---|---|
+0 | Error number |
+4 | Error String (zero terminated) |
The error number is broken down as follows:
Bits | Meaning when set |
---|---|
0-7 | Basic error number |
8-23 | Error owner or Error Generator |
24-29 | Reserved. Must be 0 |
30 | Defined to be 0 |
31 | Error is serious (hardware). Owner is then; |
0 Machine failure (data abort, undefined instruction, etc.) | |
1 Co-Processor failure | |
2 Floating Point (FPA) | |
3 Econet | |
6 Floating Point (VFP) |
X SWI’s are allowed to generate (rather than return) serious errors.
Starting with RISC OS 5.23, whenever a SWI exits with the V flag set, some sanity checks will be performed on R0 to try and make sure it’s a valid error block pointer. This is designed to help catch programming mistakes before they are able to cause problems elsewhere – e.g. on a system running with high processor vectors, a null error pointer will result in a crash. Without help from the kernel, the SWI which generated the bad error pointer may be hard to track down.
If a bad error pointer is detected then it will be swapped for a pointer to a different error block, with the error message describing which SWI is at fault.
For compatibility with existing programs, XOS_GenerateError is exempt from SWI error pointer validity checks (it is essentially a no-op as far as error generation is concerned, and many programs take advantage of this and abuse the SWI by using it for other purposes, e.g. as a method of triggering callbacks or converting null-terminated strings to BASIC form). All other SWIs, whether called in X or non-X forms, will have the error pointer check performed.