Commit 20ee3c3f authored by Ben Avison's avatar Ben Avison
Browse files

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'
parent 1c7c8124
......@@ -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:
......
;
; 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
/* (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"
......@@ -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();
......
......@@ -25,7 +25,7 @@
EXPORT |CLib_data_end|
% 112*4
% 124*4
|CLib_data_end|
END
......@@ -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 */
......
......@@ -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 *
;*-------------------------------------------------------------------*
......
......@@ -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
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment