home *** CD-ROM | disk | FTP | other *** search
- ;----------------------------------------------------------------------------
- ;
- ; $Source: /unixb/home/unixlib/source/unixlib37/src/sys/s/RCS/_jmp,v $
- ; $Date: 1996/11/06 22:01:42 $
- ; $Revision: 1.3 $
- ; $State: Rel $
- ; $Author: unixlib $
- ;
- ; $Log: _jmp,v $
- ; Revision 1.3 1996/11/06 22:01:42 unixlib
- ; Yet more changes by NB, PB and SC.
- ;
- ; Revision 1.2 1996/10/30 21:59:00 unixlib
- ; Massive changes made by Nick Burret and Peter Burwood.
- ;
- ; Revision 1.1 1996/04/19 21:34:32 simon
- ; Initial revision
- ;
- ;----------------------------------------------------------------------------
-
- GET Unix37:unixlib.s.asm_dec
-
- AREA |C$$code|,CODE,READONLY
-
- IMPORT |__fpflag|
- |__fpflag_ptr|
- DCD |__fpflag|
-
- IMPORT |__alloca_list|,WEAK
- |__alloca_list_ptr|
- DCD |__alloca_list|
- IMPORT free
- IMPORT |_exit|
-
- EXPORT setjmp
-
- NAME setjmp
- setjmp
- ; record the current allocation pointer for use with longjmp
- ; Note, alloca_list is a weak symbol so may not be set
- ; Warning!!!
- ; Do not change alloca_list so that it is not weak
- ; because it is weak in _syslib.s and it would confuse the linker
- LDR a4,[pc,#|__alloca_list_ptr|-.-8]
- CMP a4,#0
- LDRNE a4,[a4,#0]
- STR a4,[a1],#4
-
- LDR a4,[pc,#|__fpflag_ptr|-.-8]
- LDR a4,[a4,#0]
- CMP a4,#0
- ADDEQ a1,a1,#48
- BEQ |__setjmp_l1|
- STFE f4,[a1],#12
- STFE f5,[a1],#12
- STFE f6,[a1],#12
- STFE f7,[a1],#12
- |__setjmp_l1|
- ; warning!!!!
- ; even though a1 does not need to be saved, this position in
- ; the jmp_buf is used when a child process returns via vret
- STMIA a1,{a1,v1,v2,v3,v4,v5,v6,fp,sp,lr}
- MOV a1,#0
- MOVS pc,lr
-
- EXPORT longjmp
-
- NAME longjmp
- longjmp
- ; free allocations that occurred after the setjmp. This must be
- ; done before any registers, including the fp registers, are
- ; restored from the jmp_buf, because free() could do anything.
-
- ; we should be able to safely use v1-v6, since if a recursive
- ; call to longjmp does occur, then the v1-v6 are going to be
- ; safely restored to their current values.
-
- ; what about sl?, should __stack be reset ?
-
- LDR v4,[a1],#4
- LDR v5,[pc,#|__alloca_list_ptr|-.-8]
- CMP v5, #0
- LDRNE v3,[v5,#0]
- MOV v1,a1
- CMPNE v3,v4
- BEQ |__longjmp_l3|
- MOV v2,a2
- |__longjmp_l2|
- MOVS a1,v3
- BEQ |__longjmp_fatal| ; oh fuck!, the list has run out
- LDR v3,[v3,#0]
- ; update pointers in loop.
- ; must be done here in case free indirectly calls longjmp
- STR v3,[v5,#0] ; update head of alloca_list
- STR v3,[v1,#-4] ; update the stored value in jmp_buf
- BL free
- CMP v3,v4
- BNE |__longjmp_l2|
- MOV a2,v2
- |__longjmp_l3|
- LDR a4,[pc,#|__fpflag_ptr|-.-8]
- LDR a4,[a4,#0]
- CMP a4,#0
- ADDEQ v1,v1,#48
- BEQ |__longjmp_l1|
- LDFE f4,[v1],#12
- LDFE f5,[v1],#12
- LDFE f6,[v1],#12
- LDFE f7,[v1],#12
- |__longjmp_l1|
- MOVS a1,a2
- MOVEQ a1,#1 ; longjmp can't return 0
- ; technically there is a problem here if we should be
- ; moving to a higher processor mode, such as USR -> SVC
- ; warning!!!!
- ; while a1 probably doesn't need to be saved here, this
- ; is what the old code did and UnixLib has already caught me out
- ; once by using this position in the jmp_buf as the return
- ; value for vret!!!!
- STR a1,[v1,#0]
- LDMIA v1,{a1,v1,v2,v3,v4,v5,v6,fp,sp,pc}^
-
- ; if we get here something has screwed up. The old value
- ; of alloca list which we were searching for which was active
- ; when the setjmp was called wasn't found. This can happen for
- ; at least two reasons.
- ; 1. The jmpbuf has become corrupt through being overwritten
- ; 2. The user is attempting a longjmp to an invalid setjmp
- ; point, i.e., the scope of the setjmp has exited.
- |__longjmp_fatal|
- ADR a1,|__longjmp_fatal_msg|
- SWI XOS_NewLine
- SWI XOS_NewLine
- SWI XOS_Write0
- SWI XOS_NewLine
- ; This failure is too serious to trying raising a signal, since
- ; all the dynamic allocations have been freed and letting the user
- ; access that memory is just too dangerous. Further, the abort code
- ; or signal handler on abort may longjmp, causing recursion
- ; until the stack runs out. This is all likely to crash the users
- ; poor machine, so bale out now to be nice.
- MOV a1,#EXIT_FAILURE
- B |_exit|
- |__longjmp_fatal_msg|
- DCB "Fatal error detected in longjmp, jmpbuf possibly corrupt.",13,10
- DCB "This can happen for at least two reasons.",13,10
- DCB " - The jmpbuf has become corrupt through being overwritten.",13,10
- DCB " - The program is attempting a longjmp to an invalid setjmp point, ",13,10
- DCB " i.e., the scope of the setjmp has exited.",0
-
- END
-