From 20ee3c3f6c16c3550427082b15f6bb389fbc2db3 Mon Sep 17 00:00:00 2001 From: Ben Avison <bavison@gitlab.riscosopen.org> Date: Tue, 2 Dec 2003 16:51:33 +0000 Subject: [PATCH] Changes for Customer W; also suitable for building on an Iyonix. Detail: * No longer uses aasm to build h.swis. * (Only) compatible with new C compilers: assumes const static data is placed in separate read-only areas, and suitable command-line switch is used to ensure that library static data is never placed in a zero- init area. * Stack extension code now thread-safe. * Heap thread-safety code (in clib) now uses SWP instruction test results from stack extension code (in kernel) - as a side effect, the exported symbol _swp_available now exists, if you need to use it elsewhere. * Slightly closer to having top-bit-set heap addresses working. Admin: Tested in a Tungsten build, and with Customer W's test suite. Version 5.48. Tagged as 'RISC_OSLib-5_48' --- Makefile | 16 +++++++--- VersionASM | 14 ++++---- VersionNum | 22 ++++++------- c/alloc | 29 +++-------------- clib/s/cl_spare | 2 +- h/alloc | 1 + kernel/s/k_body | 85 ++++++++++++++++++++++++++++++++++++++++++++++--- kernel/s/k_data | 4 ++- s/makehswis | 2 ++ 9 files changed, 122 insertions(+), 53 deletions(-) diff --git a/Makefile b/Makefile index 618ba61..22f1044 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,7 @@ LIBDIR = <Lib$Dir> # # Generic options: # -AS = aasm +AS = objasm CC = cc CMHG = cmhg CP = copy @@ -71,8 +71,9 @@ XTENT = perl build:xtentries > DIFF = gnu.diff -df >null: -AFLAGS = -depend !Depend -Stamp -quit -CFLAGS = -c -depend !Depend ${INCLUDES} -DDDE -fK +AFLAGS = -depend !Depend +# The zz switch stops library static data being placed in a zero-init area +CFLAGS = -c -depend !Depend ${INCLUDES} -DDDE -fK -zz10000000 CPFLAGS = ~cfr~v WFLAGS = ~c~r~v @@ -632,8 +633,13 @@ lib.clib: ${CLIB_MOD_OBJS} ${MODSQZ} $@ # Derived headers: -derived.swis: s.makehswis h.swisheader s.swioptions - ${AS} ${AFLAGS} -from s.makehswis -to $@ +derived.swis: o.swis + ${LD} -bin -o $@ o.SWIs + stripnulls $@ + settype $@ text + +o.swis: s.makehswis h.swisheader s.swioptions + ${AS} ${AFLAGS} s.makehswis -o $@ settype $@ text s.swioptions: diff --git a/VersionASM b/VersionASM index 87252b7..c5a8945 100644 --- a/VersionASM +++ b/VersionASM @@ -1,6 +1,6 @@ ; ; This file is automatically maintained by srccommit, do not edit manually. -; Last processed by srccommit version: 1.68. +; Last processed by srccommit version: 1.2. ; GBLS Module_MajorVersion GBLA Module_Version @@ -11,13 +11,13 @@ GBLS Module_HelpVersion GBLS Module_ComponentName GBLS Module_ComponentPath -Module_MajorVersion SETS "5.47" -Module_Version SETA 547 +Module_MajorVersion SETS "5.48" +Module_Version SETA 548 Module_MinorVersion SETS "" -Module_Date SETS "03 Nov 2003" -Module_ApplicationDate SETS "03-Nov-03" +Module_Date SETS "02 Dec 2003" +Module_ApplicationDate SETS "02-Dec-03" Module_ComponentName SETS "RISC_OSLib" Module_ComponentPath SETS "RiscOS/Sources/Lib/RISC_OSLib" -Module_FullVersion SETS "5.47" -Module_HelpVersion SETS "5.47 (03 Nov 2003)" +Module_FullVersion SETS "5.48" +Module_HelpVersion SETS "5.48 (02 Dec 2003)" END diff --git a/VersionNum b/VersionNum index 96f7a40..83bd420 100644 --- a/VersionNum +++ b/VersionNum @@ -1,23 +1,23 @@ -/* (5.47) +/* (5.48) * * This file is automatically maintained by srccommit, do not edit manually. - * Last processed by srccommit version: 1.68. + * Last processed by srccommit version: 1.2. * */ -#define Module_MajorVersion_CMHG 5.47 +#define Module_MajorVersion_CMHG 5.48 #define Module_MinorVersion_CMHG -#define Module_Date_CMHG 03 Nov 2003 +#define Module_Date_CMHG 02 Dec 2003 -#define Module_MajorVersion "5.47" -#define Module_Version 547 +#define Module_MajorVersion "5.48" +#define Module_Version 548 #define Module_MinorVersion "" -#define Module_Date "03 Nov 2003" +#define Module_Date "02 Dec 2003" -#define Module_ApplicationDate "03-Nov-03" +#define Module_ApplicationDate "02-Dec-03" #define Module_ComponentName "RISC_OSLib" #define Module_ComponentPath "RiscOS/Sources/Lib/RISC_OSLib" -#define Module_FullVersion "5.47" -#define Module_HelpVersion "5.47 (03 Nov 2003)" -#define Module_LibraryVersionInfo "5:47" +#define Module_FullVersion "5.48" +#define Module_HelpVersion "5.48 (02 Dec 2003)" +#define Module_LibraryVersionInfo "5:48" diff --git a/c/alloc b/c/alloc index 446a080..33ad2a5 100644 --- a/c/alloc +++ b/c/alloc @@ -248,37 +248,23 @@ static char sys_message[60]; /* Mutex-y things */ static int heapMutex; -static jmp_buf *swpNotAvailable = NULL; /* boolean also used to pass jmp_buf to sig handler */ +extern int _swp_available; +#ifndef __APCS_32 static int arm2_swp(int newValue, int *location); +#endif static inline int swp(int newValue, int *location) { #ifndef __APCS_32 - if (swpNotAvailable) return arm2_swp(newValue, location); + if (!_swp_available) return arm2_swp(newValue, location); #endif int oldValue; __asm { SWP oldValue, newValue, [location] } return oldValue; } -#ifdef __APCS_32 #define INITMUTEX heapMutex = 1 -#else -#define INITMUTEX \ - do { \ - heapMutex = 1; \ - jmp_buf jb; \ - swpNotAvailable = &jb; \ - void (*old_sig_handler)(int) = signal(SIGILL, temp_sig_handler); \ - if (setjmp(jb) == 0) { \ - int temp; \ - __asm { SWP temp, 1, [&heapMutex] } \ - swpNotAvailable = NULL; \ - } \ - signal(SIGILL, old_sig_handler); \ - } while (0) -#endif #define ACQUIREMUTEX \ do { \ @@ -1077,7 +1063,7 @@ extern void *malloc(size_t size) ENTRYTOALLOC(ptr); ptr = (void *)_primitive_alloc(BYTESTOWORDS(size)); - if ((int)ptr < OK) { + if ((unsigned)ptr >= MINHEAPERROR) { #ifdef STATS ShowStats(); #endif @@ -1162,11 +1148,6 @@ extern void _init_user_alloc(void) } #ifndef __APCS_32 -static void temp_sig_handler(int sig) -{ - longjmp(*swpNotAvailable, 1); -} - static int arm2_swp(int newValue, int *location) { int irqs_off = _kernel_irqs_disabled(); diff --git a/clib/s/cl_spare b/clib/s/cl_spare index e2c330d..21060a8 100644 --- a/clib/s/cl_spare +++ b/clib/s/cl_spare @@ -25,7 +25,7 @@ EXPORT |CLib_data_end| - % 112*4 + % 124*4 |CLib_data_end| END diff --git a/h/alloc b/h/alloc index f6625f7..13b4966 100644 --- a/h/alloc +++ b/h/alloc @@ -56,6 +56,7 @@ typedef struct BlockStruct { #define OK 0 #define FAILED -1 #define CORRUPT -2 +#define MINHEAPERROR -2 /* ensure you update this if you add any new errors */ #define SIZEMASK 0xfffffffc /* all except bottom two bits, when applied */ /* to block.size yields no of address units */ diff --git a/kernel/s/k_body b/kernel/s/k_body index e385931..f64e10c 100644 --- a/kernel/s/k_body +++ b/kernel/s/k_body @@ -408,6 +408,14 @@ uwb_size # 0 ; this chunk - they won't ever be used. We must set mark (to be ; not IsAStackChunk) and SL_xxx_Offset. Also prev. STR sp, [v6, #O_extendChunk] + [ {CONFIG}<>26 + MOV r0, #1 + STR r0, [v6, #O__swp_available] + | + BL CheckIfSwpAvailable + ] + MOV r0, #1 + STR r0, [v6, #O_extendChunkNotInUse] ADD r0, sl, #SL_Lib_Offset LDMIA r0, {r1, r2} ADD r0, sp, #SC_SLOffset+SL_Lib_Offset @@ -512,6 +520,41 @@ NoMainProgram FatalError Keep SWI GenerateError + [ {CONFIG}=26 +; v6 = static base +; sp -> extendChunk, which we will use as workspace +; assumed entered in USR mode with SVC stack empty +CheckIfSwpAvailable + STMIA sp!, {r0-r12,r14} ; error handler might corrupt anything + MOV r0, #0 ; start off assuming error will happen + STR r0, [v6, #O__swp_available] + + MOV r0, #6 + MOV r1, #0 + MOV r2, #0 + MOV r3, #0 + SWI XOS_ChangeEnvironment ; read existing error handler + STMIA sp!, {r1-r3} + MOV r0, #6 + ADR r1, %FT01 + MOV r2, sp + MOV r3, sp + SWI XOS_ChangeEnvironment ; set temp error handler + + SWP r0, r0, [sp] ; try a SWP + + MOV r0, #1 + STR r0, [v6, #O__swp_available] ; note we were successful + B %FT02 +01 + MOV sp, r0 ; put back sp after error +02 + MOV r0, #6 + LDMDB sp!, {r1-r3} + SWI XOS_ChangeEnvironment ; restore error handler + LDMDB sp!, {r0-r12,pc} + ] + ;StrongARM - there is dynamic code here, but this is sorted in _kernel_init, after ;all calls to CopyHandler CopyHandler @@ -2624,8 +2667,8 @@ alloc_return_block ; as only ip is free. ; We can save things on the stack a distance below fp which allows the ; largest possible list of saved work registers (r0-r3, r4-r9 inclusive, -; plus fp, sp, lr, entry pc, = 14 regs in total) plus a minimal stack -; frame for return from StkOvfExit (a further 4 words, giving 18 in total) +; plus fp, sp, lr = 13 regs in total) plus a minimal stack +; frame for return from StkOvfExit (a further 4 words, giving 17 in total) ; plus 4 extended floating point registers (a further 3*4 words) MOV ip, sp |_kernel_stkovf_split| @@ -2849,6 +2892,19 @@ StkOvfGetNewChunk Keep ; Now we swap to the special extension chunk (to give a reasonable ; stack size to malloc). LoadStaticBase v2, ip +03 MOV a1, #0 + ADD a2, v2, #O_extendChunkNotInUse + [ {CONFIG}=26 + LDR lr, [v2, #O__swp_available] + TEQ lr, #0 + SWPNE a1, a1, [a2] + BLEQ Arm2Swp + | + SWP a1, a1, [a2] + ] + TEQ a1, #0 + BLEQ Sleep ; preserves Z + BEQ %BT03 LDR a2, [v2, #O_extendChunk] LDR a3, [a2, #SC_size] ADD a3, a2, a3 ; new sp @@ -2863,14 +2919,17 @@ StkOvfGetNewChunk Keep LDR ip, [v2, #O_allocProc] CMPS ip, #0 BEQ %F01 ; (restore stack chunk, then error) - LDR v2, [v2, #O_freeProc] - STMFD sp!, {a1, v2} ; chunk size in bytes, dealloc proc + LDR lr, [v2, #O_freeProc] + STMFD sp!, {a1, lr} ; chunk size in bytes, dealloc proc MOV lr, pc MOV pc, ip + MOV lr, v2 MOVS v2, a1 LDMFD sp!, {v3, ip} ; size in bytes, dealloc 01 LDMFD sp, {sl, fp, sp} ; back to old chunk + MOV a1, #1 + STR a1, [lr, #O_extendChunkNotInUse] BEQ StkOvfError STR v3, [v2, #SC_size] STR ip, [v2, #SC_deallocate] @@ -2913,6 +2972,24 @@ StackOverflowFault Keep ErrorBlock StackOverflow, "Stack overflow", C45 + [ {CONFIG}=26 +Arm2Swp ; like SWP a1,a1,[a2] but corrupts a3, lr and flags + SWI IntOff + LDR a3, [a2] + STR a1, [a2] + SWI IntOn + MOV a1, a3 + MOV pc, lr + ] + +Sleep +; a2 -> pollword +; must exit with Z set + MOV a1, #6 + SWI &20033 ; XOS_UpCall + CMP a1, a1 + MOV pc, lr + ;*-------------------------------------------------------------------* ;* Arithmetic * ;*-------------------------------------------------------------------* diff --git a/kernel/s/k_data b/kernel/s/k_data index fb0fb77..e2d59c8 100644 --- a/kernel/s/k_data +++ b/kernel/s/k_data @@ -104,6 +104,8 @@ initSlotSize Variable lk_RestoreOSHandlers Variable extendChunk Variable +extendChunkNotInUse Variable +_swp_available ExportedVariable rootStackChunk Variable ; Tmp space for expanding PC value in fatal error handler @@ -117,6 +119,6 @@ reg_hex_buff Variable 3 disable_stack_extension ExportedVariable 1 -unused Variable 16 +unused Variable 14 END diff --git a/s/makehswis b/s/makehswis index 55e4d97..9670b35 100644 --- a/s/makehswis +++ b/s/makehswis @@ -104,6 +104,8 @@ string2 SETS "&":CC:(:STR:value) ;SoundWorkSpace * &01F04000 GET Hdr:PublicWS + AREA |Text$Data|, DATA + ; First output the file header BIN h.swisheader -- GitLab