Making gas generate fixups for label differences

Senthil Kumar Selvaraj senthil_kumar.selvaraj@atmel.com
Tue Apr 1 16:07:00 GMT 2014


Hi,

  I am adding DIFF relocs for the AVR target to make sure shrinking
  of instructions during linker relaxation doesn't mess up 
  .debug_line information. While I got that working, I have not been
  able to get gas to generate relocs for label difference expressions in 
  the source file. Consider the following piece of code

.section	.text,"ax",@progbits
.global	main
	.type	main, @function
main:
L1:
    jmp main
L2:
    ret
.global	x
	.section .data
	.type	x, @object
	.size	x, 2
x:
	.word	L2 - L1

The assembler evaluates L2 - L1 to 4 bytes and puts the constant 4 into
the data section, but the linker later relaxes jmp to an rjmp (2 bytes instead
of 4) - the difference in the data section becomes incorrect.

$ /scratch/avr/install/bin/avr-objdump -S relax
<snip>
Disassembly of section .text:

00000000 <main>:
   0:   ff cf           rjmp    .-2         ; 0x0 <main>

   00000002 <L2>:
      2:    08 95           ret

$ /scratch/avr/install/bin/avr-objdump -s relax

      relax:     file format elf32-avr

      Contents of section .data:
       800060 0400                                 ..              
       Contents of section .text:
        0000 ffcf0895                             ....            
        ➜  ~
        [21:34:09]:∞

I looked at the internals manual, but all the TC_FORCE_RELOC* hooks
appear to kick in much later i.e. there is no fixup for which a
relocation has to be generated in this case - there's just the 
evaluated value.  

What am I missing? How do I force gas to emit a fixup for this case?

Regards
Senthil



More information about the Binutils mailing list