Code entry point offset incorrect after Link -aof
Stuart Swales (1481) 351 posts |
This one has caused a bit of headscratching… When building Fireworkz and PipeDream, part of the build process is to link all the intermediate AOF files together with the C:o.Stubs to form a fully bound AOF, then to link this single AOF to the resulting AIF !RunImage. Sometimes the resulting build crashes mysteriously… Using C Release 20 tools, I end up seeing that the AIF header’s entry point BLs to the word BEFORE the first instruction of Stub$$Code. The word BLed to contains the address of main(), which moves about a bit as I add/remove debug. Effectively I am executing a different xxxEQ instruction each time I rebuild. If you pull apart C:o.Stubs with Libfile and DecAOF cl_stub_r, you will see this defines an entry point: ‘Entry point at offset 0×0000 in area “Stub$$Code”’ – all fine and dandy. When the intermediate AOF files are linked with the stubs, the fully bound AOF has ‘Entry point at offset 0xffffffff in area “Stub$$Code”’ – not so good at all! (It does this with a trivial hello.c too) The word that gets executed is the last one in C$$Code from cl_stub_r, which has a relocation to the symbol main |
Andrew Rawnsley (492) 1445 posts |
I don’t know if this is a relevant question, but have you tried linking against RISC OS Ltd’s StubsG instead of plain Stubs? The majority of apps tend to use StubsG these days to provide compatibility with old and new SharedCLibrary. I suspect this prohibits the use of C99 stuff though, so I guess it depends on what you’re doing code-wise. |
Stuart Swales (1481) 351 posts |
As I feared, StubsG doesn’t help. (As an aside PipeDream is still C99-library-free so could use StubsG; Fireworkz now uses the C99 library function snprintf() rather than its own homebrew routine for more secure buffer accesses so can’t anymore…) I have come up with a workaround that does at least get a predictable, harmless, instruction executed: 1) move main() to the head of its source file 2) link the object file containing main() first in the list so that it ends up just after the AIF header block Then the executed instruction is the address of main(), 0×808C : ANDEQ r8,r0,r12,LSL #1 (before it was commonplace to end up with a LDR/STR of a random address – yuk!) (Aside 2 – for those who don’t know, the Z flag is always 1 from the exit of the zero-init code, so the xxxEQ instruction that is the address of main() is always executed) |
Jeffrey Lee (213) 6048 posts |
Is there any reason why you’re linking the objects into one big object before producing the final AIF? Most/all software tends to link all the objects into an AIF in one go. I’m not saying that this isn’t a bug in the C tools, but it’s definitely a problem you could avoid if you didn’t go for a two-stage link process. |
Stuart Swales (1481) 351 posts |
Yeah, I have a legacy build tool (i.e. we lost the source in 1993…) that I haven’t yet rewritten that takes the symbols from the final link stage together with this AOF to generate the exported Stubs from Fireworkz that the dynamically loaded modules bind to. Will get round to it sometime, though… |