This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hello! I'm writing a simple 16-bit Forth kernel and encountered a complex problem that I can't solve for several days, so I'm asking for help. Forth uses indirect code, e.g. most Forth 'words' (subroutines) are just list of addresses of another words. Something like this (in assembly): .long OVER .long MINUS .long SWAP .long PLUS ... OVER: ... MINUS: ... and so on. Now this wouldn't be a problem if it would be a 32-bit Forth kernel, but I explicitly need a 16-bit Forth kernel, so all offsets have to be 16-bit. Of course, that's generally impossible on 32- and 64-bit machines, so I'm doing the following: * All Forth code is put into a separate section (let's call it .f_text) * At linking time I use a special linker script which places .f_text at a known address (say, 0x60000), like this: .f_text 0x60000 : { *(.f_text) } I tried to use the --section-start ld option, but there was a bug in its implementation (reported and it's fixed now). * I subtract this known section offset from every offset, e.g: .short OVER-0x60000 .short MINUS-0x60000 .short SWAP-0x60000 .short PLUS-0x60000 This worked fine on x86_64 (my primary development machine), but I encountered a big problem when I tried to compile it for i386: unlike x86_64, on i386 the relocation offset is kept in the .text section directly in the place where the relocation has to be applied. So the problem is that 0x60000 does not fit in the 16-bit word I'm reserving for the relocation. The difference between label offset and 0x60000 guaranteed fits in 16-bits, but the 0x60000 itself doesn't. A partially working solution was to put the .f_text segment at offset zero (sic!) but such executables work only if launched as root. I tried many other solutions: subtracting a known symbol (like _f_text_start) from every symbol: .short PLUS-_f_text_start This gives: test.s:7: Error: can't resolve `.text' {.text section} - `f_text_start' {*UND* section} Also I tried to take only the lower 16 bits from every address, and ensuring that the section start is aligned at 0x10000: .short PLUS & 0xffff This gives: test.s:7: Error: invalid sections for operation on `PLUS' and `L0' Are there any ideas how my goal could be achieved? It would be good to find at least some hack for i386 targets (elf_i386 and pei_i386 would be ideal), since on x86_64 everything works fine with the first approach. -- Andrew
Attachment:
signature.asc
Description: PGP signature
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |