I'm trying to compile Beebdroid for my Android phone (to fix a Bluetooth keyboard weirdness). I'm hitting a problem with the linker complaining about the text segment being unsharable:
arm-linux-androideabi/bin/ld: warning: shared library text segment is not shareable
I'm only familiar with segments in principle, and haven't encountered this before. I see -fPIC
is already on the x86 branches in the makefile, and it seems unlikely ARM would need it with its easy PC-relative addressing, but I added it to the ARM flags anyway to no avail, so I'm presuming it's not the C code.
This leads me to assume it's the assembly code that's triggering the error.
https://github.com/littlefluffytoys/Beebdroid/blob/master/app/src/main/jni/6502asm_arm.S
It does say .text
early in the assembly file, but I looked at the clang assembler guide at infocentre.arm.com and the only executable segments I could substitute are 'init' and 'fini', neither of which look like a good idea.
Is the assembler spotting some dodgy code in the assembly, and marking the text segment as unshareable, to make the linker explode? There's no warning to that effect.
There is a look-up table indexed by 6502 op-codes to find implementing routines:
@ Get the ASM function. If this doesnt exist, fall back to C version.
adr r1, fns_asm // previously ldr r1, =fns_asm
ldr r2, [ r1, r0, lsl #2]
cmp r2, #0
beq use_c_fn
@ Call assembly function
blx r2
b done_call
I already changed the ldr
to an adr
, and moved the function closer to the table so it was within range, and I'm expecting to have to get the assembler to make the table relative, and add the PC before I do the jump, but I was kinda hoping to get a successful compile before I start trying to puzzle the details of that out.
There are plenty of macros, but the only directives I can see are .text
, .global exec6502
, and an .ltorg
, none of which look like they should be causing a problem.
Is it choking on the table itself? Do I have to subtract another label from each of the routine labels, so the assembler understands they're relative? Seems... a bit sophisticated.
Is there even an assembler version of -fPIC I need to supply?
Thanks for any pointers.
Edit: I've just noticed there are some more ldr Rx,=
instructions - two related to labels defined elsewhere, and one (I think) to absolute address 40000. Looks like I need to ask how to get C labels from assembler in a PIC-compatible way!
Edit 2: I think I can just add function pointer fields to the CPU register structure, which I'll pass to the code in r0 (instead of using acpu) and keep in r4 as the current code is.
ldr %r4, =acpu
andldr %r1, =fns
are problematic. I believe you need a GOT to access these. You can remove the lines to see if it builds. Then you need to figure a way to put them back to make the code work. I also think you are correct about the table. You needfns_asm: .word fns_asm - opasm_ora_indzx ...
Then you will sub the table lookup to thefns_asm
address loaded at run time. Like,@ Call assembly function\n sub %r2, %r1, %r2\n blx %r2
. – artless noisefns_asm
needs to be converted from an address to an offset. Ie, subtract a common address from the table entries. Then reverse that at run time. This table can be used for jump threading by changing 'RETURN' to look up the next instruction. – artless noiseacpu
into a parameter toexec6502
and adding thefns_c
to the acpu structure. (I don't need to worry about thebl sbc_bcd
and similar, do I - the linker will magic that? I'm used to the BBC Basic assembler which had no linker at all.) The table is already sort-of offset: I have its base address and can compute it on the fly for a first stab. But yes, I'll replace its entries with macros that do maths, and look for more efficiencies as the need arises. – android.weasel