Hrmm, using weak definitions in the crt0.s was a way to get the crt0.o to compile without ps2sdk as well, according to chp. Unfortunately, it depends on the proper definitions being defined prior to crt0.o being linked when compiling with ps2sdk.
Also defining the symbols in crt0.s as .globl prior to defining a .weak symbol might also be causing trouble since global definitions override weak definitions. It didn't seem to make any difference after changing them, though.
I changed it to use .weakext instead. It seems to work fine now. Your clock example was working, and only 2 tests failed, tests 6 & 8. I was getting 4 tests failing with _ps2sdk_args_parse not being defined, and 3 tests failing after that, so I guess libc wasn't being initialized quite right.
Code: Select all
# _____     ___ ____     ___ ____
#  ____|   |    ____|   |        | |____|
# |     ___|   |____ ___|    ____| |    \    PS2DEV Open Source Project.
#-----------------------------------------------------------------------
# Copyright (c) 2001-2007 ps2dev - http://www.ps2dev.org
# Licenced under Academic Free License version 2.0
# Review ps2sdk README & LICENSE files for further details.
#
# $Id: crt0.s 1466 2008-11-10 01:46:38Z oopo $
# Standard startup file.
   .weak   _init
   .type   _init, @function
   .weak   _fini
   .type   _fini, @function
   .extern   _heap_size
   .extern   _stack
   .extern   _stack_size
   .weakext  _ps2sdk_weak_args_parse, _ps2sdk_args_parse
   .globl    _ps2sdk_weak_args_parse
   .type   _ps2sdk_weak_args_parse, @function
   .weakext _ps2sdk_weak_libc_init, _ps2sdk_libc_init
   .globl   _ps2sdk_weak_libc_init
   .type   _ps2sdk_weak_libc_init, @function
   .weakext _ps2sdk_weak_libc_deinit, _ps2sdk_libc_deinit
   .globl   _ps2sdk_weak_libc_deinit
   .type   _ps2sdk_weak_libc_deinit, @function
   .set   noat
   .set   noreorder
   .text
   .align   2
   nop
   nop
   .globl   _start
   .ent   _start
_start:
zerobss:
   # clear bss area
   la   $2, _fbss
   la   $3, _end
1:
   sltu   $1, $2, $3
   beq   $1, $0, 2f
   nop
   sq   $0, ($2)
   addiu   $2, $2, 16
   j   1b
   nop
2:
   # store eventual loader arguments (passed via a0)
   la   $2, _loader_args
   sw   $4, ($2)
setupthread:
   # setup current thread
   la   $4, _gp
   la   $5, _stack
   la   $6, _stack_size
   la   $7, _args
   la   $8, _root
   move   $gp, $4
   addiu   $3, $0, 60
   syscall         # SetupThread(_gp, _stack, _stack_size, _args, _root)
   move   $sp, $2
   # initialize heap
   la   $4, _end
   la   $5, _heap_size
   addiu   $3, $0, 61
   syscall         # SetupHeap(_end, _heap_size)
   # writeback data cache
   move   $4, $0
   addiu   $3, $0, 100
   syscall         # FlushCache(0)
parseargs:
   # call ps2sdk argument parsing (weak)
   la   $8, _ps2sdk_weak_args_parse
   beqz   $8, 1f
   nop
   jal   _getargs
   nop
   jalr   $8      # _ps2sdk_weak_args_parse(argc, argv)
   nop
1:
libc_init:
   # initialize ps2sdk libc (weak)
   la   $8, _ps2sdk_weak_libc_init
   beqz   $8, 1f
   nop
   jalr   $8      # _ps2sdk_weak_libc_init()
   nop
1:
ctors:
   # call global constructors (weak)
   la   $8, _init
   beqz   $8, 1f
   nop
   jalr   $8      # _init()
   nop
1:
   # call main
   ei
   jal   _getargs
   nop
   jal   main      # main(argc, argv)
   nop
   # call _exit
   j   _exit      # _exit(retval)
   move   $4, $2
   .end   _start
   .align   3
   .globl   _exit
   .ent   _exit
   .text
_exit:
   la   $2, _retval
   sw   $4, ($2)
dtors:
   # call global destructors (weak)
   la   $8, _fini
   beqz   $8, 1f
   nop
   jalr   $8      # _fini()
   nop
1:
libc_uninit:
   # uninitialize ps2sdk libc (weak)
   la   $8, _ps2sdk_weak_libc_deinit
   beqz   $8, 1f
   nop
   jalr   $8      # _ps2sdk_weak_libc_deinit()
   nop
1:
   # conditional exit (depending on if we got arguments through the loader or not)
   la   $2, _retval
   lw   $4, ($2)
   la   $5, _loader_args
   lw   $6, ($5)
   beqz   $6, 1f
   nop
   # called from a loader, close thread
   lw   $7, ($6)
   sw   $0, ($7)   # clear thread id
   addiu   $3, $0, 36
   syscall         # ExitDeleteThread() (noreturn)
1:
   # not called from a loader, return to browser
   addiu   $3, $0, 4
   syscall         # Exit(retval) (noreturn)
   .end   _exit
   .ent   _root
_root:
   addiu   $3, $0, 35
   syscall         # ExitThread() (noreturn)
   .end   _root
   .ent   _getargs
_getargs:
   # check normal arguments
   la   $2, _args
   lw   $3, ($2)
   bnez   $3, 1f
   nop
   # check for arguments passed by a loader
   la   $2, _loader_args
   lw   $3, ($2)
   beqzl   $3, 2f
   addu   $4, $0, 0
   addiu   $2, $3, 4
1:
   lw   $4, ($2)
   addiu   $5, $2, 4
2:
   jr   $ra      # $4 = argc, $5 = argv
   nop
   .end   _getargs
   .bss
   .align   6
_args:
   .space   4+16*4+256   # argc, 16 arguments, 256 bytes payload
_loader_args:
   .space   4      # pointer to loader arguments: thread id, argc, argv
_retval:
   .space   4