avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Broken R_AVR_16 relocation? Or is my compiler wrong?


From: Senthil Kumar Selvaraj
Subject: Re: [avr-gcc-list] Broken R_AVR_16 relocation? Or is my compiler wrong?
Date: Tue, 12 Jan 2016 15:02:19 +0530
User-agent: mu4e 0.9.13; emacs 24.5.1

Dylan McKay writes:

> Hello there,
>
> I am generating AVR executables with my own compiler, but linking them with
> AVR-GCC.
>
> Here is an example of a C file, which avr-as compiles fine. I made sure to
> first use my compiler to generate assembly from this file, and then
> assemble this using my compiler and gcc so that they are both using the
> same assembly source file.
>
> void foo();int bar = 2;int abc = 2;
> int jmp __attribute__((section(".vectors"))) = 0x940C;void (*ptr)()
> __attribute__((section(".vectors"))) = (&foo);
> void milan() { }void foo(){}void inter() { }
> int qwerty = 2;
>
> The .vectors section is generated fine. The correct jmp instruction is
> placed. Both compilers generate R_AVR_16 relocations for this.
>
> GCC however generates this (avr-objdump output):
>
> RELOCATION RECORDS FOR [.vectors]:
> OFFSET   TYPE              VALUE
> 00000004 R_AVR_16          .text+0x00000004
>
> Note that .text+0x00000004 does point to foo in the object file.
>
> Whereas my compiler generates this:
>
> RELOCATION RECORDS FOR [.vectors]:
> OFFSET   TYPE              VALUE
> 00000002 R_AVR_16          foo
>
> The problem is that GCC’s hardcoded section+offset works, but my symbol
> does not. avr-ld correctly relocates GCC code to foo in the executable, but
> relocates my code to _etext+0x2.
>
> Am I doing something wrong, or is not just not properly supported?

GAS has an adjust_reloc_syms method that does the symbol to
section+offset modification. 
https://www.sourceware.org/ml/binutils/2002-05/msg00065.html
hints at why that's done.

As for your problem, I suspect you need R_AVR_16_PM (not R_AVR_16) - the
reloc with the PM suffix shifts the symbol value 1 bit to the right to
convert it from a byte address to a word address - which is what the JMP
instruction's encoding expects. GAS generates this reloc if it sees the
gs or pm modifier for an operand i.e.

.word gs(foo)

To reproduce your issue, I stripped off the gs modifier to make gas
generate a R_AVR_16 reloc. I also made it generate a reloc against foo
by declaring foo weak. But that still works:

$ ~/avr/install/bin/avr-as -mmcu=avr5 weak.s -o weak.o
$ ~/avr/install/bin/avr-objdump -r weak.o

weak.o:     file format elf32-avr

RELOCATION RECORDS FOR [.vectors]:
OFFSET   TYPE              VALUE 
00000002 R_AVR_16          foo


$ ~/avr/install/bin/avr-ld -mavr5 weak.o
$ ~/avr/install/bin/avr-objdump -S a.out

a.out:     file format elf32-avr


Disassembly of section .text:

00000000 <jmp>:
   0:   0c 94                                               ..

00000002 <ptr>:
   2:   14 00                                               ..

00000004 <milan>:
   4:   cf 93           push    r28
   6:   df 93           push    r29
   8:   cd b7           in      r28, 0x3d       ; 61
   a:   de b7           in      r29, 0x3e       ; 62
   c:   00 00           nop
   e:   df 91           pop     r29
  10:   cf 91           pop     r28
  12:   08 95           ret

00000014 <foo>:
  14:   cf 93           push    r28
  ...

I get the same result if the reloc is against the section name. ie.

$ ~/avr/install/bin/avr-as -mmcu=avr5 weak.s -o weak.o
$ ~/avr/install/bin/avr-objdump -r weak.o

weak.o:     file format elf32-avr

RELOCATION RECORDS FOR [.vectors]:
OFFSET   TYPE              VALUE 
00000002 R_AVR_16          .text+0x00000010


$ ~/avr/install/bin/avr-ld -mavr5 weak.o
$ ~/avr/install/bin/avr-objdump -S a.out

a.out:     file format elf32-avr


Disassembly of section .text:

00000000 <jmp>:
   0:   0c 94                                               ..

00000002 <ptr>:
   2:   14 00                                               ..

00000004 <milan>:
   4:   cf 93           push    r28
   6:   df 93           push    r29
   8:   cd b7           in      r28, 0x3d       ; 61
   a:   de b7           in      r29, 0x3e       ; 62
   c:   00 00           nop
   e:   df 91           pop     r29
  10:   cf 91           pop     r28
  12:   08 95           ret

00000014 <foo>:
  14:   cf 93           push    r28

Can you send the assembly file that produced the incorrect behavior?
Also, can you tell us the binutils version you are using?

Regards
Senthil



reply via email to

[Prev in Thread] Current Thread [Next in Thread]