Broken R_AVR_16 relocation? Or is my compiler wrong?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Broken R_AVR_16 relocation? Or is my compiler wrong?

Dylan McKay

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?


_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Broken R_AVR_16 relocation? Or is my compiler wrong?

Senthil Kumar Selvaraj
On Thu, Jan 07, 2016 at 10:55:33PM +1300, Dylan McKay wrote:

> 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?
> ???

Hmm, I remember seeing code in gas turning symbol relocs into
sectionstart+offset ones. Give me a day to dig that up.

Regards
Senthil

_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Broken R_AVR_16 relocation? Or is my compiler wrong?

Senthil Kumar Selvaraj
In reply to this post by Dylan McKay

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

_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Loading...