tkchia/binutils-ia16

[question] ia16-elf-ld usage ?

Closed this issue · 2 comments

Hello @tkchia,

After using ia16-elf-gcc to only compile C code to assembly, we are starting the next step to replace as86 and ld86 by the GNU binutils.

We have some errors when linking a very simple executable (the boot sector):

ia16-elf-ld -M  -s  -e _main -o boot/bootsect boot/bootsect.o > boot/bootsect.map
boot/bootsect.o: In function `_main':
(.text+0x15): relocation truncated to fit: R_386_16 against `.text'
(...)
boot/bootsect.o: In function `ok2_read':
(.text+0xee): additional relocation overflows omitted from the output

The source is a single bootsect.s (attached as a .TXT : bootsect.txt), assembled with:

ia16-elf-as -mtune=i8086  -o boot/bootsect.o boot/bootsect.s

Could you please tell us what is the correct usage of as and ld to generate 8086 code in that case ?

Hello @mfld-fr ,

Thank you for the report! The issue is that ia16-elf-ld's default linker script currently writes ELF output (!) and places the text segment at 0x8048000 + SIZEOF_HEADERS. This causes the linker to try to fit the flat address 0x8048054 + 0x19 into the 16-bit offset of ljmp (e.g.), which fails with the errors you observed.

You can view the default linker script with

ia16-elf-ld --verbose

One way to properly build the boot sector code is to override the default settings in the default script --- do something like this:

ia16-elf-ld -Ttext 0 --oformat=binary -M -s -e _main -o boot/bootsect boot/bootsect.o \
  > boot/bootsect.map

Alternatively, you can tell ia16-elf-ld to use a totally different linker script with the -T option (but you will need to write the script). This is actually what ia16-elf-gcc does internally --- it passes one of newlib-ia16's linker scripts to ia16-elf-ld.

Thank you!

Thank you @tkchia for the explanation ! It now works nice with the options you suggested.