From justin.fletcher@ntlworld.com Mon Apr 19 22:56:54 2004 Date: Wed, 3 Sep 2003 13:05:59 +0100 From: Justin Fletcher Newsgroups: comp.sys.acorn.programmer Subject: Re: Justin's super-quick guide to compiling C for use from other languages On Wed, 3 Sep 2003, Jeremy C B Nicoll wrote: > In article , > Justin Fletcher wrote: > > > Justin's super-quick guide to creating code ..... > > Fascinating! This is definitely an article to keep. Thanks. I expect that the URLs referenced will remain for quite a while - they're only small. I might zip up the content at some point though. > I was puzzled by one thing. In the example: > > > > So, we have a little bit of assembler that does this : > > > ----- s.asm > > ; > > ; Veneer for our C code > > ; > > > AREA |!!!!First|, CODE, READONLY > > > ; Start of the output file > > B doreloc > > B call_get_version > > > IMPORT __RelocCode > > doreloc > > STMFD sp!,{r14} > > BL __RelocCode > > CMP r0,r0 > > LDMFD sp!,{pc} > > What would one actually need to have at __RelocCode for the code > concerned to achieve relocation? [My experience of this sort of thing > is only in ibm mainframe code where relocatable code has this done for > it by the OS when code is loaded into storage - the idea of an > un-relocated module doing it itself is alien to me.] Ah, this was obviously clear to me that I'd explained it at the time. When you create relocatable code in a module with -rmf, the linker will append a lump of code called __RelocCode which is used to relocate all the references. It is immediately followed (at the end of the image) by... * the current position at which the table is logically located * a list of the addresses of all the addresses which need to be relocated When you first link the module all the addresses will appear to be based at &8000. So the 'current position' will be &8000 + offset from start of code to the table. All the other addresses listed will have the same offset applied to them. The relocation code loads this 'current position' and replaces it with the actual address that it lives at. The actual position is then subtracted from the position, giving an offset that must be applied to all the addresses. The code then goes through the table adding on this offset to all the addresses pointed at in the table. Thus, the entire list of addresses is relocated. Once relocated in this manner, the table itself is still consistent because it now describes the logical position of the code as being its new location - if you were to examine the table after the relocation has taken place you would see all the addresses now refer to physical locations. Should that code be then saved out and the reloaded elsewhere (or whatever) the relocation code would still work. This only applies immediately after the relocation code has been called - once you start using the code itself you change its state and it's then dependant on your design as to whether the code can be restarted in this manner. IF you wanted it to be completely restartable you might use the relocatable module method of compilation (-zM to the compiler) or the reentrant variant of APCS (-apcs 3/reent). Neither is simple to describe but they do have benefits. I wouldn't personally use either when linking with another language unless I was very confident about them - I understand them and have used them myself but they take a lot more thinking about. This is OTTOMH and I haven't double checked this one, so it's possible that I'm ignoring flags and other special features of the table off the top of my head. But that's the basic gist of it. The code examples I've given apply to C and not to C++ - you need to do more things to make the C++ code work but the quick notes I put together were getting a little long. Plus it was getting close to 5. -- Gerph {djf0-.3w6e2w2.226,6q6w2q2,2.3,2m4} URL: http://www.movspclr.co.uk/