ELF on ld 2.17 incorrectly calculates 8- and 16-bit relocations that worked with COFF on ld 2.16.2. h8300-coff-as -oreloc.o reloc.s h8300-coff-ld -mh8300s --oformat binary reloc.o od -tx1 a.out correctly yields: 0000000 6a 08 e0 02 00 02 while h8300-elf-as -oreloc.o reloc.s h8300-elf-ld -mh8300self --oformat binary reloc.o yields: reloc.o:(.text+0x2): relocation truncated to fit: R_H8_DIR16A8 against `addr' and h8300-elf-as -oreloc.o reloc.s h8300-elf-ld -mh8300self reloc.o h8300-elf-objdump -d a.out h8300-elf-objcopy -Obinary a.out od -tx1 a.out yields: 0000000 6a 08 e0 02 01 06 Content of reloc.s: .h8300s _start = 0 .global _start mov @addr + 2 :16, r0l addr = 0xffe000 .word label - . label:
Created attachment 1250 [details] Assembler example to show incorrect 16-bit ELF relocation
This is a gas problem. gas is generating R_H8_DIR16 for the .word expression, which is wrong. The expression needs a 16 bit pc-relative reloc instead, or gas should be resolving the "label-." expression itself. It doesn't resolve the expression because h8300 sets linkrelax and there is no logic to detect that the expression is pc-relative and does not cross a region that could change size.