Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

_kernel_osword not 32 bit compatible

3 views
Skip to first unread message

chris...@bigfoot.com

unread,
Oct 29, 2009, 8:44:01 PM10/29/09
to
I am concerned that the _kernel_osword function (part of the shared C
library kernel) is not 32 bit compatible. It seems to be one of those
which are documented by comments in header file "kernel.h" as
returning >=0 if the call succeeds, -1 if the call fails but causes no
os error, or -2 if the call causes an os error.

Since the result of SWI OS_Word is written to the block pointed to by
R1 instead of returned in a register, the return value of
_kernel_osword might reasonably be expected to indicate only success
or failure. However, having disassembled the relevant part of the
shared C library (in the absence of decent documentation), this
function appears to be returning the value of R1!

A simple test of calling OS_Word from BASIC indicates that the value
of R1 is preserved by this SWI, and therefore _kernel_osword has
effectively cast its 'int *data' argument to type 'int'. Even if the
return value were the appropriate type, I can't see any point in
_kernel_osword returning the address of the parameter block, because
it is already known to the caller. Furthermore, this seems to be a
dangerous policy because if bit 31 of the address of the parameter
block is set then _kernel_osword will return a negative value despite
having succeeded!

IMO this should have been addressed when updating RISC OS for 32 bit
modes. Is it likely that anyone (ab)uses the return value of
_kernel_osword by casting it back to a pointer? If not then it would
be more in keeping with other "kernel.h" functions to return the value
of R0 (reason code). Otherwise this function should at least be
flagged as problematic.

Other dodginess in this area concerns the _kernel_oswrch and
_kernel_osbput functions, which rely upon SWIs XOS_WriteC and XOS_BPut
returning a positive value in R0 unless they set the overflow flag to
indicate an error. Isn't this a foolish assumption? The PRM documents
those SWIs as preserving the entry value of R0, which suggests that
calling _kernel_oswrch or _kernel_osbput with a negative character
code could make them appear to fail.

All of this makes me think that relying on return values >= 0 to
indicate success may be a lost cause, and it would be safer to check
explicitly for -1 or -2. :-(

--
Christopher Bazley

Jonathan Graham Harston

unread,
Oct 30, 2009, 5:50:18 PM10/30/09
to
chrisbazley wrote:
> A simple test of calling OS_Word from BASIC indicates that the value
> of R1 is preserved by this SWI, and therefore _kernel_osword has
[snip]

> block is set then _kernel_osword will return a negative value despite
> having succeeded!

If _kernel_osword() returns -1 because R1 has been preserved and
passed back it must be because R1 was passed as -1, meaning that
the control block was at &FFFFFFFF, which is not possible, as the
call would have been trying to put a block of data wrapping past
the top of memory.

You will either get a return result of whatever address the control
block was held at - which won't be within a few bytes of the top of
memory - or you will get exactly -1 (&FFFFFFFF) or exactly -2
(&FFFFFFFE).

There are many API calls that used to be described as returning <0
where they actually returned -1, and the documentation has been
updated to specify checking for exactly -1, not for <0. To me, this
is just the same.

(I have a file titled "Changes to APIs due to 32-bit addressing"
which includes the lines: A number of APIs, particulalrly the
Window manager, allow registers or values to be a pointer or <0.
These APIs are being updated so that only 0 or -1 are non-pointer
values.)


> modes. Is it likely that anyone (ab)uses the return value of
> _kernel_osword by casting it back to a pointer? If not then it would

The only place I've used it in in my Z80 emulator in C, which does:

chkerr(_kernel_osword(...));
...
chkerr(retval)
{ if (retval != -2) return(0);
...


> _kernel_osbput functions, which rely upon SWIs XOS_WriteC and XOS_BPut
> returning a positive value in R0 unless they set the overflow flag to
> indicate an error. Isn't this a foolish assumption? The PRM documents

It's a foolish assumtion to test for a negative value with the AI
documentation explicitly tells you to test for -1 or -2.


> All of this makes me think that relying on return values >= 0 to
> indicate success may be a lost cause, and it would be safer to check
> explicitly for -1 or -2. :-(

Exactly, just as the documentation tells you to do.

--
J.G.Harston - j...@arcade.demon.co.uk - mdfs.net/User/JGH
In 1939 $50 of groceries would fill three station wagons. Today I
can lift $50 of groceries with one hand. I must have got stronger.

Christopher Bazley

unread,
Oct 31, 2009, 5:48:23 AM10/31/09
to
In message <091030...@arcade.demon.co.uk>
j...@arcade.demon.co.uk (Jonathan Graham Harston) wrote:

> chrisbazley wrote:
[snip]


>> _kernel_osbput functions, which rely upon SWIs XOS_WriteC and XOS_BPut
>> returning a positive value in R0 unless they set the overflow flag to
>> indicate an error. Isn't this a foolish assumption? The PRM documents

> It's a foolish assumtion to test for a negative value with the AI
> documentation explicitly tells you to test for -1 or -2.

If you are referring to the same header file as me, it doesn't TELL
you to do anything. It simply describes two of the many int values
which are not ">= 0 if the call succeeds".

>> All of this makes me think that relying on return values >= 0 to
>> indicate success may be a lost cause, and it would be safer to check
>> explicitly for -1 or -2. :-(

> Exactly, just as the documentation tells you to do.

I would be extremely surprised if there is no code in existence where
the programmer has done something like 'if (_kernel_osword(2, &param)
>= 0)' to check for success - not least because it is less typing than
'if ((e = _kernel_osword(2, &param)) != _kernel_ERROR && e != -1)'.

It is perfectly reasonable in most circumstances to assume that 'not
success' means 'failure'.

--
Chris Bazley
Star Fighter 3000: http://starfighter.acornarcade.com/

0 new messages