03 May 2022, 22:48 | #1 |
Registered User
Join Date: Apr 2019
Location: UK
Posts: 228
|
vasm -pic with -Fbin
I'm trying to learning how to load and execute code from a bootblock and struggling to get the vasm -pic option to warn (error) when it detects absolute code.
The bootblock allocates memory and uses trackdisk IO request to load INCBIN'd code from a track on disk. The binary code is build from Code:
ORG 0 ; Infinite loop flashing the screen clr.w d0 loop: addq.w #1,d0 move.w d0,$dff180 ; flash screen cmp.w #$fff,d0 bne loop clr.w d0 bra loop ; OK: PC-relative branch jmp loop ; BAD: Jump to absolute address. Not position independent code Code:
vasmm68k_mot.exe -pic -Fbin -o intermediates/TrackdiskMain.bin -L %Build%/TrackdiskMain.list -Lall -wfail TrackdiskMain.asm I realise at some point I may have to assemble load files and fix up relocations in the loaded hunks, but for now I'd just like to be able to catch any non-position independent code at build time. (Attached full source for more context) |
03 May 2022, 23:27 | #2 |
Registered User
Join Date: Mar 2012
Location: Norfolk, UK
Posts: 1,157
|
What the -pic flag actually does is disallow relocations, not absolute addresses. Because you've specified the starting location with ORG, it knows exactly where in memory the label "loop" will be, so no relocation is required.
If you remove the ORG you'll see that there's still no error - but if you look at the generated code, the JMP has been replaced with an equivalent BRA in order to satisfy the -pic constraint. If you place a large ds.b immediately before the jmp, so that the branch target is more than 32k away then you'll get an error message, since it now can't satisfy the -pic constraint. |
03 May 2022, 23:50 | #3 |
Registered User
Join Date: Apr 2019
Location: UK
Posts: 228
|
Thanks. I had tried removing the ORG and was surprised it didn't error then. I didn't realise the assembler was doing so much work silently behind the scenes!
While I'm learning these fundamentals it might be helpful if vasm didn't silently change my instructions for me and instead informed me if code is illegal. Is there an option for this? |
04 May 2022, 00:03 | #4 |
Registered User
Join Date: Mar 2012
Location: Norfolk, UK
Posts: 1,157
|
I guess the easiest way would be the specify the -no-opt flag, so you get exactly the code you asked for. (Without it, the JMP will be turned into a BRA even without the -pic option just because it's faster and smaller code.)
|
04 May 2022, 00:09 | #5 |
Registered User
Join Date: Apr 2019
Location: UK
Posts: 228
|
Code:
error 35 in line 14 of "TrackdiskMain.asm": relocation not allowed > jmp loop ; BAD: Jump to absolute address. Not position independent code |
04 May 2022, 01:08 | #6 | |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,537
|
Quote:
For example you could generate Atari TOS executables instead, which have a much simpler relocation table. Or use vlink to output "rawbin" or "rawseg" format with option -q, which will append a similar reloc table to a raw binary file. I did use "rawseg" in my games, because I wanted to support multiple segments (Chip and Fast). Otherwise "rawbin" is easier to use. |
|
04 May 2022, 14:24 | #7 |
Registered User
Join Date: Apr 2019
Location: UK
Posts: 228
|
Thanks. I'll definitely give rawbin and rawseg a go, if I can overcome my fear of the linker scripts ;-).
I guess rawbin1 is the one to use and rawbin2 is aimed at another machine. Now that I understand the hunk format, loaders, bootblocks and trackdisk, it might be a good exercise to write a tool to take a simple hunk load file and create a bootblock trackdisk loader disk image from it. It might be fun to try the reverse too and "one file" a disk with custom bootblock loader. |
05 May 2022, 13:50 | #8 | ||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,537
|
Quote:
rawbinthe default linker script should usually suffice ( rawsegis another topic). vlink -brawbin1 -q myobj.ois all it needs for a first test. Quote:
rawbin2can output multiple files, when there are gaps larger than 16 bytes in your code (e.g. as a result from multiple orgdirectives). rawbin1just fills the gaps with zero-bytes. |
||
05 May 2022, 14:22 | #9 |
Registered User
Join Date: Apr 2019
Location: UK
Posts: 228
|
I've read the vlink rawbin1 docs, but I'm a little confused. My test program has a single section with a single reference to a label in the same section. I can see that when linking with with -q the file grows by 5 bytes: 00 00 00 01 08. This means that there is a single relocation at offset 8 - this matches the disassembly so great.
But how would I know the offset of the reloc table in the binary when I load it? I guess maybe this is the part of the explaination I don't understand. You may reference it by using the __end symbol, which marks the end of the bss section.I don't know how to get at a symbol when the binary is loaded, or what the "bss section" is (my code by definition is a single CODE section)? |
05 May 2022, 15:57 | #10 | ||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,537
|
Quote:
__end, which marks the address after your last byte. When you do the relocation in your startup code you can use this symbol to find the table. For example: Code:
xref __end lea __end,a0 move.l (a0)+,d0 ; reloc table size in bytes ... Quote:
__endfollows after "code", or whatever. In any case it should mark the end of your whole program. |
||
05 May 2022, 16:17 | #11 |
Registered User
Join Date: Apr 2019
Location: UK
Posts: 228
|
Thanks but I'm still not quite there. This is the process I envisage. Please could you tell me where I am going wrong?
1. Write main.asm, the code that the bootblock will load, relocate and execute. 2. Build main.asm with -rawbin1 -q -o main.bin 3. Write bootblock.asm with INCBIN "main.bin" at f.ex offset of track 1 4. bootblock.asm boot code reads main.bin tracks from disk into memory (trackdisk IO) 5. Somehow access __end symbol from incbined main.bin to find relocation table 6. Apply relocations to loaded code 7. JMP to loaded code. I cannot see how the __end symbol can be accessed from an incbined binary, so perhaps this is not the correct process. Thanks. Last edited by hop; 05 May 2022 at 16:17. Reason: Formatting |
05 May 2022, 16:51 | #12 | |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,537
|
Your envisioned procedure looks completely fine!
Quote:
__end. Point 5 seems to me as if you want to access it from within the source code of main.asm. Which would be fine, and was shown in the example above. But this last sentence seems as if you want to access __endwithin the source code of bootblock.asm? May I ask why? To keep main.bin shorter? If you absolutely want to do that, then there are still two solutions:
Code:
dc.l __end-* |
|
05 May 2022, 17:52 | #13 | ||
Registered User
Join Date: Apr 2019
Location: UK
Posts: 228
|
Quote:
Yes. I imagined bootblock.asm simply incbining main.bin and handling the relocations. It just seems to make sense for the loader (bootblock.asm) to do the loading using the relocation table, and the load file (main.asm) to simply be a payload (e.g. game code). I'm struggling to get my head around the load file containing code to relocate itself. Quote:
However, I think rawseg is ultimately the way to go, because most (all) of my applications/executables will have multiple sections: at least CODE (any) and BSS/DATA (Chip). Do I have to use a linker script for this case? I think I saw you posted one in the Trackmo tech thread. Is that ready to go? Last edited by hop; 05 May 2022 at 17:54. Reason: typo |
||
05 May 2022, 21:06 | #14 | ||||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,537
|
Quote:
lea __end(pc),a0doesn't work, because your program is larger than 32K, you can still store the offset as dc.l __end-*somewhere in reach. Quote:
Quote:
Quote:
section chipmem,dataor change the script. Note, that the section directive's "chip" attribute has no meaning when the output is not hunk-format. An advantage over the default script is support for the small-data model, in case you need that. |
||||
05 May 2022, 21:28 | #15 |
Registered User
Join Date: Apr 2019
Location: UK
Posts: 228
|
Thanks. I’ll try this out. Does this count as naughty self modifying code? If the relocation code is potentially next to the relocated code, would any CPU instruction cache need to be flushed after the relocations are applied?
|
06 May 2022, 00:16 | #16 | ||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,537
|
Quote:
Quote:
|
||
14 May 2022, 10:23 | #17 | |
Registered User
Join Date: Apr 2019
Location: UK
Posts: 228
|
Quote:
Code:
<bootblock header> <use trackdisk to load rawbin file with prefixed reloc table offset> ; apply the relocation table movea.l a4,a0 ; A0 <- address of loadfile ; read reloc table offset ; n.b: -rawbin1 -q still appends a relocation table to the binary even if there are no entries. ; In that case the table size longword would just be $00000000 move.l (a0),d0 ; D0 <- reloc table offset ; Read first longword movea.l a4,a1 ; A1 <- address of loadfile adda.l d0,a1 ; A1 <- reloc table move.l (a1)+,d1 ; D1 <- reloc table size in bytes. A1 <- address of first byte in bytestream ; Read bytestream and apply relocations relocLoop tst.l d1 ; end of bytestream? beq relocLoopEnd ; yes? Done subq.l #1,d1 ; dec bytecount ; read byte ; - A byte between 1 and 255 represents the distance in bytes to the *next* relocation offset (i.e. offset from previous) ; (starts at zero). moveq #0,d0 move.b (a1)+,d0 bne reloc ; A zero byte indicates that the following word contains a distance greater than 255. ; Read longword offset ; n.b. Can't do move.l (a1)+,d0 because the 68000 can only read words (and longwords) from ; word-aligned (even) addresses (68020+ can actually read from odd addresses at the expense of performance) subq #4,d1 ; bytecount -= sizeof(long) move.b (a1)+,d0 ; read MSB $XX...... lsl.l #8,d0 move.b (a1)+,d0 lsl.l #8,d0 move.b (a1)+,d0 lsl.l #8,d0 move.b (a1)+,d0 ; read LSB $......XX reloc adda.l d0,a0 ; A0 <- address of longword to relocate move.l (a0),d0 ; D0 <- relative address add.l a4,d0 ; Add loaded program start address D0 <- absolute address move.l d0,(a0) ; store absolute address bra relocLoop ; next offset relocLoopEnd ; Invalidate the instruction cache for 68020+ CPUs ; Required in case any of the relocated code is in the cache and needs to be refetched from RAM IF MIN_SUPPORTED_OS_VERSION>=37 jsr _LVOCacheClearU(a6) ; V37 (Kickstart 2.04) Cannot be called on KS1.3 ELSE btst #AFB_68020,AttnFlags+1(a6) beq executeLoadfile lea invalidateInstructionCache(pc),a5 ; Supervisor userfunc jsr _LVOSupervisor(a6) ENDIF executeLoadfile adda.l #4,a4 ; skip relocation table offset longword jmp (a4) error moveq #$FFFFFFFF,d0 ; boot failure code rts |
|
14 May 2022, 11:42 | #18 | |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,053
|
Quote:
Speed/size is probably not an issue here, but I would write that loop like this (2 bytes shorter, slightly faster): Code:
; Read bytestream and apply relocations bra.b relocNext relocLoop ; read byte ... relocNext subq.l #1,d1 ; dec bytecount, end of bytestream? bgt.b relocLoop Code:
subq.l #4,a7 ; once only move.l a7,a2 ; ... move.b (a1)+,(a2)+ move.b (a1)+,(a2)+ move.b (a1)+,(a2)+ move.b (a1)+,(a2)+ move.l -(a2),d0 ... addq.l #4,a7 ; once only |
|
14 May 2022, 11:54 | #19 |
Registered User
Join Date: Apr 2019
Location: UK
Posts: 228
|
Thanks. I'll try those changes. I guess size could become important when this is extended to load multiple sections if the code stays in the bootblock.
|
15 May 2022, 16:12 | #20 |
Registered User
Join Date: Apr 2019
Location: UK
Posts: 228
|
I have a first pass rawseg loader working now. I'd like to look at this script for reference. The vlink website seems to be down and couldn't see it on the GitHub. Where can it be found?
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Anyone help with a pic of wb 3.1 on 4:3 tv? | cypher007 | support.Hardware | 14 | 30 June 2020 08:18 |
Wave Pic | pmc | Coders. Tutorials | 18 | 03 June 2009 18:37 |
It's... Request-a-pic! | Shoonay | EAB's competition | 42 | 05 July 2008 15:03 |
This may be handy for some ( BIG PIC ) | synchro | Amiga scene | 27 | 27 June 2004 22:00 |
|
|