Generating an abort
Pages: 1 2
Rick Murray (539) 13840 posts |
I think it depends upon why you want an abort – there are different ones. Off the top of my head, you could:
|
Stuart Swales (8827) 1357 posts |
Not on a low-vector system it won’t! |
Charles Ferguson (8243) 427 posts |
Pretty sure that’s not an abort in all cases. That would just start execution at &8000 on 26bit systems. Depending on how you branched to it, it might execute code in thumb mode, which might be entirely valid.
Pretty sure that’s just unpredictable, isn’t it?
Does not generate an abort. Attempts to change mode from within user mode are ineffective. The following is a section of code from a test tool used to exercise various mechanisms for reporting errors within the the SCL. It depends on what you mean by ‘abort’ as to whether this is useful to you – in this case this is testing all the mechanisms of triggering a failure within a C program: THE FOLLOWING IS THE SOURCE THAT DOES THE ACTUAL STUFF static void recurse_hugely(void *x) { /* Note: The two calls mean that this function cannot have the first call tail-optimised. The two writes to the local buffer mean that the buffer cannot be discarded. The passing of the parameter means that the compiler shouldn't be able to see that it's only written to locally and uses automatic storage. Norcroft wouldn't do any of those, but I'm just making sure. */ char cack[1024*512]; /* 1/2 M per recurse should do us */ cack[0]='1'; recurse_hugely(cack); cack[0]='2'; recurse_hugely(cack); } /*********************************************** <c> Gerph ********* Function: dis_numberval Description: find the number an instruction refers to Parameters: instr = instruction (ALU instructions only) Returns: pointer to a string ******************************************************************/ char *dis_numberval(unsigned int instr) { int mantissa=(instr & 0x0ff); int exponent=32- ((instr & 0xf00) >> (8-1)); unsigned int val=(mantissa<<exponent)+(mantissa>>(32-exponent)); static char num[32]; strcpy(num,",#"); sprintf(num,",#&%x",val); if ( (val<4096) && (val!=0) ) { sprintf(num,"%s ; = %i",num,val); } { extern void *malloc(int); int k; if (_swix(4, 1<<31, &k)) /* ReadC */ k = 27; if (k == 'a') /* a= abort */ abort(); else if (k == 'd') /* d= data abort */ *(int*)-4 = 9; else if (k == 'e') /* e= error */ _swi(43, 1, "\0\0\0\1An error message\n"); else if (k == 'p') /* p= prefecth abort */ ((void (*)(void))0x3700000)(); else if (k == 'u') /* u= undefined instruction */ _word(0xE6000010); else if (k == 'f') /* f= free of already freed memory */ { void *x = malloc(4); free(x); free(x); } else if (k == 'm') /* m= malloc block corruption */ { unsigned long *x = malloc(4); memset(x-4, 0, 32); free(x); } else if (k == 'A') /* A= assert error */ __assert("fail", __FILE__, __LINE__); else if (k == 's') /* s= stack overflow */ recurse_hugely(NULL); else if (k == 27) /* ESC= just raise escape */ _swix(6, 1, 125); /* OS_Byte set escape */ } return num; } There’s a bunch of other aborts missing, such as FP exceptions (which can be reporting in a variety of ways) and a whole variety of memory exceptions (ARM define a whole host of different ways in which the system may abort due to memory not being there; in addition to the memory not existing or not being accessible in the mode you’re in, there’s faults for broken page tables, and asynchronous error reporting). On earlier systems you can get an address exception if you try to access an address that cannot contain memory. The above code doesn’t appear to trigger the branch through zero code, but that’s probably because that’s not an interesting case – it’s exactly the same as the raised error. It just happens to come from the Kernel, not the application. |
Rick Murray (539) 13840 posts |
[branching to something like &8001]
In all cases, no. But on later ARMv7 it will abort 1. I’m guessing the need to abort is for testing something, because it’s not really a behaviour one would want in release code. ;-) [bogus instruction like loading a register using itself as the source address, with writeback]
Unpredictable means the processor can handle it how it wants. Later ARMv7 will fault these sorts of instructions as invalid 2 3. How I know? Various pieces of software (especially Zap) that worked fine on the Beagle (early ARMv7) and the original Pi (ARMv6) but fell over with exceptions on the Pi2 (later ARMv7). I’ve looked at this stuff, seen things like “load R10 from the address pointed to by R10 with writeback to R10” and I wonder how it ever worked. Then I wonder how many lurking gotchas like that are around that may have caused erratic behaviour in the past?
Thanks, it’s useful to compare (I have something similar (but simpler) to test my backtrace handler). Though, given the original question related to an assembler instruction, I’m not sure if C would be useful? 1 A missing ALIGN giving a bogus branch address in the header is why Zap’s Obey extension failed. 2 The Menu module within TemplEd. 3 Various places in various bits of Zap. |
Charles Ferguson (8243) 427 posts |
Yes, that was my point. It can handle it how it wants. That includes ignoring it, or turning into a sperm whale.
Sorry, I’ll stop answering questions where the person asking them doesn’t specify what they want to know. |
Jeffrey Lee (213) 6048 posts |
[branching to something like &8001]
Have fun finding an ARMv7 machine on which this will abort. *x rmkill specialfx *memorya 8000 df112000 *go 8001 Like Charles said, it’ll trigger a switch into Thumb mode. So branching to an arbitrary odd address isn’t a good way of getting a reliable abort, because unless you place the right instructions at the target address, the CPU could do any number of things before it aborts. |
David J. Ruck (33) 1635 posts |
Our F1 ECU code had test points which would cause every possible type of abort, so tests could trigger them and check it there handled correctly (crashing being frowned upon during the race). This was ported from PPC to ARM for the next generation of ECUs, but I’m damned if I can remember the exact instruction sequences we used. |
Jon Abbott (1421) 2651 posts |
If you need a guaranteed cross-platform Abort, use a non-existent Copro instruction. Would help if we knew the context. Is the intent to force an unstable halt or a trap point? A Debugger break point might be a better option. |
Colin Ferris (399) 1814 posts |
I’m trying to 32bit ArmDebug – trying to locate where the Module is going into 26svc mode. Thinking of how to split the BASIC Assembler into smaller lumps. It’s one giant file at the moment. Point taken from Gerf – about only being able to switch to 26bit from Svc mode – perhaps replacing the OS_EnterOS into a FN and globally being able to temp replace it with a NOP. A another point Vrpc seems to at desktop using *showregs shows ro is in a 26bit mode – does RPCem do the same? Running Red S. It does the same earlier ro5 – no double boot and no modules loaded?? |
Martin Avison (27) 1494 posts |
That is simple. Decide on a good split point. Select the assembler code you want to split out, then save it as a separate file. Delete what you have saved, and add in the gap FNxxxx where xxxx is any name for the removed code. Load the file as a library at the start of the main program. Edit the new saved lump to add DEF FNxxx ar the start and =0 at the end. Repeat as required – I have a program with dozens of assembler ‘lumps’. VRPC & RpcEmu are both emulating a real RPC, so 26bit only. |
Stuart Swales (8827) 1357 posts |
I generally run RPCEmu in 32-bit mode with RISC OS 5 these days! Might fire up a RO 4.39 instance every other month or so. Anyhow a thing to remember is that the RISC PC processors enter their exception handlers in 32-bit mode before doing any faffy 26-bit stuff, which might affect how ArmDebug hooks into them. |
David J. Ruck (33) 1635 posts |
Didn’t that only come in with the StrongARM? IIRC the ARM610 and ARM710 could run in true 26bit configuration (both code and data), and switched to 26 bit code and 32 bit data after boot. |
Stuart Swales (8827) 1357 posts |
Hazy memory. Exceptions definitely forced into 32-bit mode in StrongARM as you say. I had a look at the RO 4.39 SWI handler earlier and that was forcing a change to 26-bit mode even when RPCEmu was configured for ARM610, so it might just be CPU-agnostic code. (and if so, SWI handler inefficiency – heresy!) |
Rick Murray (539) 13840 posts |
PRM5a – However, because the processor is in a 32 bit configuration, all exceptions (including Undefined Instruction and Software Interrupt) force the processor to a privileged 32 bit mode appropriate to the exception. RISC OS 3.5 on an ARM610 (and other RiscPC incarnations) used a hybrid 26/32 bit setup that generally looked and felt like 26 bit to most programs. |
Colin Ferris (399) 1814 posts |
When (Vrpc or red s) reaches Desktop press f12 – type *showregs -its in a 26bit mode. |
Rick Murray (539) 13840 posts |
ARM6xx in original RISC OS (3.6?) code, showing exception entered in 32 bit mode, which is then bashed to 26 bit mode so the rest of RISC OS works. ;) |
Colin Ferris (399) 1814 posts |
It is interesting that a Mrs r0,cpsr Doing ‘go 0’ sets *showregs in 32bit User mode. |
Stuart Swales (8827) 1357 posts |
That’s a duff emulator. Try on a real RISC PC. [Edit: I have been disabused of this notion!] |
Jeffrey Lee (213) 6048 posts |
Not if he’s running RISC OS 5.
That’s because the buffer where the exception registers are stored is zero-initialised on startup. Mode 0 = USR26. |
Stuart Swales (8827) 1357 posts |
@Geoffrey: Don’t think that Vrpc runs RISC OS 5 though? [Edit: To avoid showregs confusion maybe it is worth initialising the CPSR dump state to be a typical USR32 one rather than zero] @Rick: Thanks for that info, it’s not in my printed PRM5. Was a printed PRM5a ever issued? I have the PDF. |
David Pitt (3386) 1248 posts |
RISC OS 5 can be softloaded on VRPC. OS5.24 is running in VRPC here. The softload is manual. That is as far as I got. |
Stuart Swales (8827) 1357 posts |
@David: Interesting, thanks! As I don’t have VRPC I wouldn’t have thought of that. I always associate VRPC with 4/6. |
Charlotte Benton (8631) 168 posts |
The problem with not reinventing the wheel, is that in many cases the wheels are dependent on the continued commitment of a single person. We ideally need a situation where lots of people have an “absolutely everything” file on their hard disk, which can be used to restart any lost projects, so long as just a single copy remains intact. |
Rick Murray (539) 13840 posts |
This is something that is cropping up with various open source projects. Lots of people happy to use, one unpaid developer responsible. It works as long as it’s something that developer is passionate about, but once it turns into a bunch of entitled people demanding to know why their pet bug hasn’t been seen to, it’s no longer fun but alas there’s nobody else… |
Charlotte Benton (8631) 168 posts |
Of course, the other thorny issue is copyright. However, given the choice between pirating content that isn’t even sold any more, and that content being lost forever, I’d say the latter is preferable. |
Pages: 1 2