Absolute files with certain byte sequence crash
Dennis Ranke (8444) 7 posts |
During a coding session, I came across a simple Absolute file that crashes with “No writable memory at this address” (For some reason truncated to “No writable mem” when running from ram disc.) on RISC OS 5. From what I could determine, this crash happens whenever bytes 15-19 of the Absolute file are exactly EB 11 00 00 EF. (ie. “bl somewhere, swi OS_Exit”). A simple example is: 00008000 : EF00013F : ?..ï : SWI OS_WriteI+"?" 00008004 : E3A01000 : .. ã : MOV R1,#0 00008008 : EF000011 : ...ï : SWI OS_Exit 0000800C : EB000000 : ...ë : BL &00008014 00008010 : EF000011 : ...ï : SWI OS_Exit This runs fine on RO3.71 (RPCEmu Easy-Start bundle), but crashes on a recent 5.29 beta rom with a nightly beta HardDisc4, as well as on 5.28 with no !Boot folder as seen on https://rpcemu.m-h.org.uk/ Changing any of the 5 bytes will make it run, even though they are never actually executed. This smells like something trying to fingerprint a certain class of executable and maybe trying to patch them? Is this a known behavior / byte sequence to avoid, and if yes, are there any others? |
Martin Avison (27) 1494 posts |
Perhaps it is assuming that it is in AIF format? These have various branches and lengths in the first 40 bytes or so. And I think the error you see also depends on the length of the Absolute file, and its contents, including at +16 SWI OS_Exit. I have not found a definition of what an Absolute file should contain. |
Julie Stamp (8365) 474 posts |
Yes the last two lines (&800C and &8010) make FileSwitch think your code is in AIF, and tries to interpret the following words as how much memory is needed for you. I guess putting in |
Rick Murray (539) 13840 posts |
PRM 4-438 (appendix D “Code file formats” of the final book), and also at the back of the DDE’s Desktop Tools book (p271 in an older PDF) which is probably a copy of the PRM chapter, only a tad more up to date…? |
Stuart Swales (8827) 1357 posts |
In an ideal world the FileSwitch test (introduced 11 years ago) would be extended to cover the first five words of potential AIF header. Not exactly time-critical code. Check SWI OS_Exit first for quick reject. First three words could be NOP as well as BLs. At least we don’t have to worry about BLNV etc these days. |
Rick Murray (539) 13840 posts |
It’s here: https://gitlab.riscosopen.org/RiscOS/Sources/FileSys/FileSwitch/-/blob/master/s/FSControl#L534 |
Martin Avison (27) 1494 posts |
@Rick: Thanks for the references. However, although PRM4 and DDE docs give the AIF format, neither actually say that Absolute files are interpreted as AIF files if the words at +12 and +16 match AIF. And I had searched PRM4 for ‘Absolute’. Obviously the source ‘clarifies’ what is going on, but it should not be necessary to read that to answer the OPs question. |
Stuart Swales (8827) 1357 posts |
Similar behaviour may have been around since RISC OS 4 (or 6, who knows) days in the other world: http://www.riscos.com/support/developers/riscos6/programmer/codeformats.html “Since RISC OS 3.7, absolute files without AIF headers have been deprecated as it is impossible to determine the execution format of an executable without such a header.” [their statement] |
Rick Murray (539) 13840 posts |
That’s a later modification to the source, so wouldn’t be in the PRM. Arguably the DDE might want to mention it.
That was enforced by RISC OS Ltd in one version of their RISC OS, and then unenforced because lots of stuff broke. I would imagine that enforcing AIF headers would cause breakage to almost all of the appified BASIC programs (which is an abomination in itself). I disagree with forcing AIF headers, but I agree that it ought to be an option. Once in a while I get a weird crash and looking in Zap I see the program starting BLX which would have once been BLNV. There’s no mechanism within RISC OS to filter out 26 bit software – the error that you might see is actually generated by CLib when the old app tries to start the program up using the obsolete APCS-R call. Yup, that’s 26 bit code getting that far. Thankfully (BLX aside) it’s compatible enough that CLib can catch it. For non-C programs, well… Of course, I’m guilty of abusing this |
Dennis Ranke (8444) 7 posts |
Thanks everyone! That makes a lot of sense. I actually did avoid the crash by adding a MOV R0, R0 before the SWI OS_Exit, it just didn’t feel right to do that without fully understanding the issue. That’s the danger of relying on the “knowledge” gained from coding on Archimedes and RiscPC in my teens: I only ever produced headerless Absolute files from BASIC and never heard about AIF headers. (Or maybe I heard about them but dismissed them as being from this weird C world.) So I guess, technically I’m supposed to add a valid header, which doesn’t look like too much hassle. |
Rick Murray (539) 13840 posts |
Until ROLtd started to enforce AIF headers, and RISC OS 5 started to try to automatically allocate enough slot space… …that’s more or less what it was, some weird C thing. ;)
How are you building your code? If you’re using the DDE, you can just get the linker to spit out an AIF for you. |
Dennis Ranke (8444) 7 posts |
I’m actually trying out compiling Rust code to RISC OS on a whim. Which actually works out pretty nicely. (32bit only, though, as LLVM doesn’t support 26bit mode ARM code. edit: this should have read “StrongARM and up only, though, as LLVM doesn’t support ARMv3 or earlier”) The start of the file is just a handwritten assembly section, so no help from the linker there. |
Julie Stamp (8365) 474 posts |
Nice, I do hope you get somewhere with it, I had a go but got really stuck. |
Paolo Fabio Zaino (28) 1882 posts |
I did quite a bit of work on that in 2022, I also worked on a linker script, some picture and more details here: https://twitter.com/PaoloFabioZaino/status/1581773161632530432 Then I got bored because, obviously, while I got it to the point of building almost perfect AIF (still needed some work, but it was close), then there is even more work to do for the core and std, add support for RMA and Jeffrey’s multi-core library. I think Julie’s effort on stick to the ELF32 is probably a better idea, but still needs the work on core and std, SWI, RMA etc. For my personal set of projects and goals, in the end I have decided to write my own byte code VM, given it’s easy to target that from LLVM and avoid alltogether all the issues above. Here is the VM work, it’s almost working with Jeffrey’s multi-core code and also adds support for hybrid preemptive multitasking as well as full memory protection (an abstracts the RMA, SWIs and even the WIMP). Performance are not too bad, so far it’s twice as fast as BBC BASIC, faster than Lua and a lot faster than CPython. Basically it will work as a “WASM substitute” for RISC OS (bonus: it also runs well on Linux, BSD, macOS and Windows) and, again, as an LLVM target it’s way easier than native binary for RISC OS (IMHO): https://paolozaino.wordpress.com/portfolio/ultima-vm-unified-lightweight-typed-instructions-machine/ The other advantage is that the VM is already 64bit, so won’t need code that runs on it now to be recompiled. The VM runs from RISC OS 3.10 all the way up to RO 5 (including 4 and 6), althought is most machines with 3.10 won’t have a lot of memory, but can still be used to run tools and stuff that doesn’t use a lot of RAM. I’ll show progresses so far at the RISC OS Show in Bristol this Saturday if anyone is interested. Good luck with your effort, it cool to see someone is working on Rust for RO native! :) |
Dennis Ranke (8444) 7 posts |
I guess my perspective is slightly different, as I’m not a regular user of RISC OS any more. I just return every few years to remember simpler times, when executable files were just loaded at address 0×8000 and executed from there, and you could comfortably build complete applications just using OS system calls directly. ;) As such, for my rust experiments, I’m not too concerned with porting the std lib. I’m perfectly happy with just core + alloc, and then writing thin wrappers around SWIs as needed. What I have working so far is pretty much enough for a simple command line tool |
Paolo Fabio Zaino (28) 1882 posts |
Makes sense. I am having fun with RO too, it’s nostalgia mostly and intellectual challenge, lots of fun :) |
Dave Higton (1515) 3525 posts |
Times still are that simple, aren’t they? That’s what all ordinary apps do. |