Forum: Compiler & IDEs AVR-gas: .byte und hi/lo8 - illegal relocation size


von Martin S. (msperl)


Lesenswert?

Hallo!

Habe da ein kleines Problem mit dem gnu-as (versionen 2.20 und 2.20.1) 
bei meinem can-boot-loader.

Ich wollte in meinem Flash Pointer via .byte und hi8/lo8 platzieren und 
bekomme immer nur "Error: illegal relocation size: 1".
1
test:
2
        .byte   lo8(test),hi8(test)
3
        .byte   test&0xff,test>>8

zu assemblieren (ohne linken) via:
1
avr-as test.S
 (oder auch
1
avr-gcc -C -x assembler-with-cpp test.S
) liefert:
1
test.S: Assembler messages:
2
test.S:2: Error: illegal relocation size: 1
3
test.S:2: Error: junk at end of line, first unrecognized character is `('
4
test.S:3: Error: illegal relocation size: 1
5
test.S:3: Error: illegal relocation size: 1

das einzige was geht ist:
1
test:
2
        .word   test

Das sollte ja grundsätzlich zu den .byte Konstrukten das selbe Ergebnis 
liefern, aber leider funktioniert nur das .word Konstrukt.

Leider passt dieses .word nicht in meine Konzept mit defines für diverse 
Pattern (via CPP-define) und einzelnen Bytes dazwischen.

Gibt es vielleicht eine Lösung um dies doch korrekt zu assemblieren - 
ich befürchte, das ich das Konzept ändern muss und das ist jetzt meine 
letzte Hoffnung es vielleicht doch noch so hin zu bekommen...

Danke,
       Martin

p.s: es ist unabhängig davon ob der Pointer ins SRAM oder in FLASH 
zeigt...

: Verschoben durch Admin
von Markus M. (adrock)


Lesenswert?

...das würde mich übrigens auch interessieren, bin auch schon auf dieses 
Problem gestoßen...

Grüße
Markus

von sesch (Gast)


Lesenswert?

Der endgültige Wert der Adresse "test" steht erst beim Linken fest. Der 
Compiler fügt daher im obj-File für jede Referenzierung auf diese 
Adresse einen Platzhalter ein und erstellt einen relocation record, 
welcher dem Linker sagt, dass an dieser speziellen Stelle noch der 
finale Wert der Addresse "test" eingetragen werden muss.

Dass der Compiler sich über die ungültige relocation size von 1 
beschwert, liegt daran, dass Adressen bei (den "kleinen") AVR 16bit 
haben und der Linker nur den finalen Wert der Adresse, nicht aber 
irgendwelche Rechenausdrücke, eintragen kann.

von Markus M. (adrock)


Lesenswert?

Ah ok... sehr gute Erklärung, hatte mir schon sowas gedacht.

Aber ich dachte er (der Linker) wäre schlau genug, dass dann doch 
irgendwie zu handhaben...

Aber der Threadersteller könnte sich ja evtl. helfen, wenn er RELATIVE 
Adressen in seiner Struktur verwendet. Sowas funktioniert:

MyLabel:
    .byte (MyLabel2-MyLabel)&0xff, (MyLabel2-MyLabel)>>8, 1, 2, 3, 4
MyLabel2:
    .byte 5, 6

Grüße
Markus

von Martin S. (msperl)


Lesenswert?

Das stimmt und stimmt so nicht, denn das assemblieren (nicht linken!!!)
1
.byte lo8(test),hi8(test)
schlägt fehl, aber
1
.word test
funktioniert wie schon gesagt.

Wenn man sich mit avr-objdump -Dz test.o anschaut, so steht bei der 
.word Variante dann temporär 0,0 drinnen - vermutlich inklusive 
inklusive von elf-marker/sections um die Adressen beim linken richtig zu 
setzen...

Wenn man es dann allerdings linkt, und dann wieder ansieht, so steht die 
korrekte Adresse drinnen, also der linker kann es grundsätzlich - sonst 
würde ein "ldi r24,lo8(test)" ja auch nicht funktionieren - die Adresse 
von test wird erst beim linken bekannt...

Das funktioniert leider nur bei .word - ich hoffte, daß es einen 
"work-around" oder anderen Trick gibt um den gnu-as davon zu überzeugen 
das "richtige" auch bei .byte zu machen (ohne ihn patchen zu müssen...)

Ich werde wohl in den sauren Apfel beißen müssen und muss mir wohl eine 
#define Krücke um diesen Bug herum überlegen...

Weis wer, wo man derartige GNU-as fehler am besten meldet - beim 
avr-team oder bei GNU selbst?

Martin

von Martin S. (msperl)


Lesenswert?

@Markus: Dein Vorschlag steigt leider genau so beim assemblieren aus:
1
# cat test.S 
2
MyLabel:
3
    .byte (MyLabel2-MyLabel)&0xff, (MyLabel2-MyLabel)>>8, 1, 2, 3, 4
4
MyLabel2:
5
    .byte 5, 6
6
7
# avr-as -o test.o test.S 
8
test.S: Assembler messages:
9
test.S:2: Error: illegal relocation size: 1
10
test.S:2: Error: illegal relocation size: 1
11
#

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Martin Sperl schrieb:

> Ich wollte in meinem Flash Pointer via .byte und hi8/lo8 platzieren und
> bekomme immer nur "Error: illegal relocation size: 1".
>
> test:
>         .byte   lo8(test),hi8(test)
>
> Das sollte ja grundsätzlich zu den .byte Konstrukten das selbe Ergebnis
> liefern, aber leider funktioniert nur das .word Konstrukt.
>
> Leider passt dieses .word nicht in meine Konzept mit defines für diverse
> Pattern (via CPP-define) und einzelnen Bytes dazwischen.

Dann pass dein Konzept an und nimm .word, nimm Binutils 2.23+ oder 
portiere Erweiterung PR13503 auf deine bevorzugte Binutils-Version.

In älteren Versionen werder die Expression-Modifier lo8, hi8 und hh8 nur 
für Operanden in Instruktionen unterstützt, nicht für Daten.

Markus M. schrieb:

> Aber ich dachte er (der Linker) wäre schlau genug, dass dann doch
> irgendwie zu handhaben...

Der Linker kann das, war reinprogrammiert wurde. Konstrukte wie oben 
wurden nie benötigt. Erst mit 3-byte Adressen im avr-gcc ergab sich die 
Erfordernis, die entsprechenden Modifier/Relocs auch für Daten zu 
unterstützen.

von Martin S. (msperl)


Lesenswert?

@Johann: Danke für den Hinweis!

Das fröhliche binutil/compiler bauen hat schon begonnen...

von Markus M. (adrock)


Lesenswert?

Martin Sperl schrieb:
> @Markus: Dein Vorschlag steigt leider genau so beim assemblieren aus:

Interessant, bei mir (Studio 6 SP 2) ließ er sich übersetzen.

Na bin mal gespannt ob das mit den neueren Binutils dann funktioniert.

Grüße
Markus

von Martin S. (msperl)


Lesenswert?

Markus M. schrieb:
> Interessant, bei mir (Studio 6 SP 2) ließ er sich übersetzen.

Aber AVR hat - so wie ich verstanden habe - (zumindestens früher ) eine 
eigene Version des Assemblers verwendet, die sich etwas anders verhält 
als...

Daher kann beim Studio immer noch eine andere/gepatchte Version 
verwendet wird - ich nutzte das Studio nicht...

> Na bin mal gespannt ob das mit den neueren Binutils dann funktioniert.

ja mit den neuen binutils klappt es...

Martin

von Markus M. (adrock)


Lesenswert?

...so wie ich es verstanden habe, gibt es nach wie vor den AVR 
Assembler, der sich aber anders als der gcc-as verhält. Ich benutze 
letzteren um genmischte C/ASM-Binaries zu erstellen und halbwegs 
kompatibel zu sein...

Grüße
Markus

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.