Forum: Compiler & IDEs AVR8 gnu toolchain unterschiede linux/windows


von R. F. (ruefo)


Lesenswert?

Hallo,
ich habe ein Projekt für einen xmega128a3u, welches ich mit der Atmel 
Toolchain übersetze. In der Zusammenarbeit mit Kollegen hat sich 
herausgestellt, dass das generierte hexfile unterschiedlich ist, wenn 
man es unter Windows und unter Linux compiliert.

Hier die Toolchain unter Linux:
1
avr-gcc --version
2
avr-gcc (AVR_8_bit_GNU_Toolchain_3.5.3_1700) 4.9.2
3
[...]

Und hier unter Windows:
1
avr-gcc.exe --version
2
avr-gcc.exe (AVR_8_bit_GNU_Toolchain_3.5.3_1700) 4.9.2
3
[...]

Der diff ergibt, dass das Ende der Hexfiles gleich aussieht, nur die 
Anfänge unterscheiden sich (also vermutlich irgendwelche libs?).

Meine Frage: Was sind die Unterschiede und wie kann ich identische 
Hexfiles erzeugen? Vielen Dank schonmal!
Gruß

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Rüdiger F. schrieb:
> Meine Frage: Was sind die Unterschiede

Wie soll man diese erkennen, wenn Du sie nicht zeigst?

"Ich habe zwei Hemden im Kleiderschrank. Was sind die Unterschiede?"

Zeig bitte auch für beide Betriebssysteme, wie der Code compiliert wird, 
also sämtliche Compiler- und Linkeraufrufe. Dort könnten auch 
verschiedene Optimierungsstufen bzw. andere Compilerflags benutzt worden 
sein.

: Bearbeitet durch Moderator
von R. F. (ruefo)


Lesenswert?

Leider ist es mir nicht erlaubt, die originalen Hexfiles zu posten. Ich 
werde mal kurz ein kleines Testprojekt erstellen. Meine Frage zielte 
aber auch auf die Unterschiede der beiden Toolchains - also der 
Schneider und nicht der Hemden ;)

Zum Thema Flags und Aufrufe:
Es wird das identische Makefile genutzt. Nur der Pfad der Toolchain ist 
anders.

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Rüdiger F. schrieb:
> Leider ist es mir nicht erlaubt, die originalen Hexfiles zu posten.

Dann wird es Stochern im Dunkeln.

Schon die Verwendung von
1
__DATE__ __TIME__

im Code wird einen Unterschied erzeugen. Du wirst dann antworten, dass 
beide Konstanten nicht verwendet werden. Und so geht das Spielchen dann 
weiter - ohne echtes Ergebnis.

Voschlag:

Compiliere einen möglichst kleinen, öffentlich zugänglichen Source auf 
beiden Rechnern und poste dann die Unterschiede. Darüber kann man dann 
disktutieren.

Aber bei einem Closed-Source, wo sogar die HEX-Files geheim sind, kannst 
Du das absolut vergessen. Hast Du jetzt Schiss, dass einer der beiden 
Varianten nicht korrekt arbeitet?

von R. F. (ruefo)


Lesenswert?

> Voschlag:
>
> Compiliere einen möglichst kleinen, öffentlich zugänglichen Source auf
> beiden Rechnern und poste dann die Unterschiede. Darüber kann man dann
> disktutieren.

mach ich. (coming soon..)

> Aber bei einem Closed-Source, wo sogar die HEX-Files geheim sind, kannst
> Du das absolut vergessen. Hast Du jetzt Schiss, dass einer der beiden
> Varianten nicht korrekt arbeitet?

nein. Bei uns steht die CRC übers Hexfile im Release-Protokoll.

Danke bis hierhin.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rüdiger F. schrieb:
> Bei uns steht die CRC übers Hexfile im Release-Protokoll.

CRCs sind gut, um Übertragungsfehler zu erkennen.

Wenn man sich sicher sein will, dass zwei Dokumente gleich sind,
sollte man lieber eine kryptografische Prüfsumme wie SHA256 nutzen.

von R. F. (ruefo)


Lesenswert?

Jörg W. schrieb:
> Rüdiger F. schrieb:
>> Bei uns steht die CRC übers Hexfile im Release-Protokoll.
>
> CRCs sind gut, um Übertragungsfehler zu erkennen.
>
> Wenn man sich sicher sein will, dass zwei Dokumente gleich sind,
> sollte man lieber eine kryptografische Prüfsumme wie SHA256 nutzen.

ja. ich weiß. Ist etwas komplizierter und definitiv OT, warum es hier 
mit CRC gemacht wird. Hat z.T. damit zu tun dass das auch noch auf dem 
MC gerechnet wird. Aber wenn schon OT: Geht denn SHA256 in schnell auf 
nem xmega?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rüdiger F. schrieb:
> Geht denn SHA256 in schnell auf nem xmega?

Hab' ich noch nicht probiert.  Für den Controller würde ich auch
erstmal zu CRC tendieren (ggf. halt CRC-32).  SHA war eher fürs
Release-Management offline gemeint.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Rüdiger F. schrieb:
> Hier die Toolchain unter Linux:avr-gcc --version
> avr-gcc (AVR_8_bit_GNU_Toolchain_3.5.3_1700) 4.9.2
> [...]
>
> Und hier unter Windows:avr-gcc.exe --version
> avr-gcc.exe (AVR_8_bit_GNU_Toolchain_3.5.3_1700) 4.9.2
> [...]

Ok, die Compiler haben die gleiche Version. Aber was ist mit den
Binutils und der AVR-Libc? Ich vermute, dass ihr bei letzterer zwei
verschiedene Version habt.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> Ich vermute, dass ihr bei letzterer zwei
> verschiedene Version habt.

Da es die von Atmel herausgegebene Toolchain ist, sollten sie
eigentlich die gleiche Basis benutzt haben.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Jörg W. schrieb:
> Da es die von Atmel herausgegebene Toolchain ist, sollten sie
> eigentlich die gleiche Basis benutzt haben.

Upps, das habe ich überlesen. Ja, dann hätte ich eigentlich auch gleiche
Ergebniss erwartet (bis vielleicht auf die LF bzw. CR/LF-Zeilenenden im
Hexfile).

Trotzdem würde ich die Versionen mal vergleichen. Es könnte ja sein,
dass aus Versehen zwei Installationen vermischt wurden oder bei Atmel
jemand geschludert hat. Irgendwo muss der Unterschied ja schließlich
herkommen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> bis vielleicht auf die LF bzw. CR/LF-Zeilenenden im
> Hexfile

Selbst die sollten gleich sein, denn Intel Hex ist nun einmal mit
<CR><LF>-Zeilenenden definiert.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> Ja, dann hätte ich eigentlich auch gleiche
> Ergebniss erwartet (bis vielleicht auf die LF bzw. CR/LF-Zeilenenden im
> Hexfile).

Rüdiger F. schrieb:
> Der diff ergibt, dass das Ende der Hexfiles gleich aussieht, nur die
> Anfänge unterscheiden sich (also vermutlich irgendwelche libs?).

Es ist also definitiv mehr als CRLF vs. LF. Aus dem Bauch heraus würde 
ich denken, dass die Libs eher am Ende des HEX-Files liegen. Oder geht 
das wild durcheinander?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Frank M. schrieb:
> Oder geht das wild durcheinander?

Der Startup-Code steht zumindest am Anfang.

von R. F. (ruefo)


Lesenswert?

OK, Korrektur: der Anfang ist gleich:
1
$ diff linux.hex win.hex -y | head -n 10
2
:100000000C94143C0C94353C0C949EF70C94353CA9         :100000000C94143C0C94353C0C949EF70C94353CA9
3
:100010000C94353C0C94353C0C94353C0C94506A53         :100010000C94353C0C94353C0C94353C0C94506A53
4
:100020000C94353C0C94D8690C94353C0C94353CBC         :100020000C94353C0C94D8690C94353C0C94353CBC
5
:100030000C94353C0C9411E80C9426FA0C94353C45         :100030000C94353C0C9411E80C9426FA0C94353C45
6
:100040000C94353C0C94353C0C94353C0C94353C6C         :100040000C94353C0C94353C0C94353C0C94353C6C
7
:100050000C94353C0C94353C0C94353C0C94353C5C         :100050000C94353C0C94353C0C94353C0C94353C5C
8
:100060000C94353C0C94353C0C94353C0C94353C4C         :100060000C94353C0C94353C0C94353C0C94353C4C
9
:100070000C946DEF0C94353C0C94CFEF0C94353C04         :100070000C946DEF0C94353C0C94CFEF0C94353C04
10
:100080000C94E1E20C94353C0C949ECF0C94BDCFC3         :100080000C94E1E20C94353C0C949ECF0C94BDCFC3
11
:100090000C94353C0C94353C0C94353C0C94353C1C         :100090000C94353C0C94353C0C94353C0C94353C1C

in der Mitte dann:
1
$ diff linux.hex win.hex -y --suppress-common-lines | head -n 10
2
:100880000C945ECC0C9483F90C94987D0C94117E9E             |  :100880000C94F2980C94E6680C9492890C944FFAAC
3
:100890000C94F6680C9485C20C9490A00C94887EFD             |  :100890000C9458680C94E3E90C94176C0C949E68C3
4
:1008A0000C9429DF0C943B7D0C944E7D0C94A8FA9B             |  :1008A0000C94516D0C94837E0C9466420C9467CB2F
5
:1008B0000C944BE90C9492890C9412A00C94FDB307             |  :1008B0000C946C460C94E2680C9404680C944468A4
6
:1008C0000C946ACD0C946CA00C94829D0C944A46B6             |  :1008C0000C94DC680C94AC7D0C944AD10C94FD59CA
7
:1008D0000C94769C0C94AE680C944FFA0C94B4680B             |  :1008D0000C940D980C945B460C94C4F90C9461C371
8
:1008E0000C9400680C94EC680C94A57E0C94E0B316             |  :1008E0000C94EC6A0C948CCC0C944DCC0C94AC5ABB
9
:1008F0000C944C680C944C9C0C94149C0C94DD98B7             |  :1008F0000C942B990C940DFA0C9489D00C94B3B3EE
10
:100900000C94C2FB0C94C6680C9497420C949668A5             |  :100900000C94F67D0C9461CC0C9488680C9450681F
11
:100910000C941F990C94A4880C9488680C94B2D7FA             |  :100910000C948ADA0C943B7D0C9493C20C945C93F7

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Das sind irgendwelche Sprünge, die sich unterscheiden, also immer
noch innerhalb der Vektortabelle (würde ich jetzt vom Angucken her
so schätzen).

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Jörg W. schrieb:
> Der Startup-Code steht zumindest am Anfang.

:-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Frank M. schrieb:
> Jörg W. schrieb:
>> Der Startup-Code steht zumindest am Anfang.
>
> :-)

Naja, er muss ja an sich nur logisch am Anfang sein; der erste
Sprung (Reset-Vektor) springt dahin.  Im Prinzip könnte man ihn
also (bis auf die Vektortabelle) ans Ende linken lassen.  Machen
die üblichen Linkerscripte aber nicht, sie setzen ihn wirklich
nach der Vektortabelle.

Logisch gesehen ist er jedoch Bestandteil der Bibliothek.

von Oliver S. (oliverso)


Lesenswert?

Ich würde als erstes Mal den erzeugten Assemblercode und die Map-Files 
vergleichen.

Ansonsten: ist die Linkreihenfolge der Objektdateien und der libs 
wirklich identisch?

Oliver

von R. F. (ruefo)


Lesenswert?

Habe gerade mal den Code auf eine leere Main-Loop reduziert und dann die 
gleichen Makefiles verwendet (gleiche CFLAGS wie beim vollständigen 
Projekt). Ergebnis: Gleiches Hex-File.

Die Map-Files im Original sind definitiv unterschiedlich. Hier fällt auf 
das sich die Adressen+Größen der .debug_str unterscheiden. Heißt das 
irgendwas? Sollten die nicht gleich sein? Eigentlich sollten die dann im 
Release eh weg sein..

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rüdiger F. schrieb:
> Hier fällt auf das sich die Adressen+Größen der .debug_str
> unterscheiden. Heißt das irgendwas?

Dass die Pfadnamen sich unterscheiden. ;-)

von R. F. (ruefo)


Lesenswert?

OK. Stimmt natürlich. Aber selbst mit -g0 bekomme ich keine gleichen 
Ergebnisse. Frage am Rande: wenn die Größe des Segments mit 0x00 
angegeben ist, dann wandert da doch nichts ins Hexfile, oder?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rüdiger F. schrieb:
> OK. Stimmt natürlich. Aber selbst mit -g0 bekomme ich keine gleichen
> Ergebnisse.

-g0 beeinflusst nur die aktuelle Compilation, nicht aber das, was
ggf. aus der Bibliothek mit eingeschleppt wird.

> Frage am Rande: wenn die Größe des Segments mit 0x00
> angegeben ist, dann wandert da doch nichts ins Hexfile, oder?

Ein Segment von 0 Byte Größe kann auch im Hexfile nur 0 Byte
belegen. ;-)

von Bernd K. (prof7bit)


Lesenswert?

Rüdiger F. schrieb:
> OK, Korrektur: der Anfang ist gleich:
> $ diff linux.hex win.hex -y | head -n 10

Vielleicht solltest Du die beiden hexen lieber erstmal disassemblieren 
bevor Du sie vergleichst. Oder machst Du das im Kopf?

von S. R. (svenska)


Lesenswert?

Was mir an der ganzen Diskussion fehlt, ist ein Vergleich der 
ELF-Dateien. Sind die (gestrippt) byteweise identisch oder gibt es schon 
dort Unterschiede? Und wenn es Unterschiede gibt, wo befinden sich die?

Aus einem Hexfile irgendwas rauszulesen ist sportlich und vor allem 
extrem unnütz, wenn es auch besser geht. ;-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

S. R. schrieb:
> Was mir an der ganzen Diskussion fehlt, ist ein Vergleich der
> ELF-Dateien.

Wenn die Hex-Dateien unterschiedlich sind, dann müssen es die
ELF-Dateien auch sein (OK, gleiche Zeilenlänge natürlich mal
vorausgesetzt).

Andererseits heißt nicht jeder Unterschied in den ELF-Dateien, dass
der tatsächliche Code sich wirklich unterscheiden würde.  Sowas wie
Debug-Info wurde ja schon genannt.

von R. F. (ruefo)


Lesenswert?

Guten Morgen und erstmal vielen Dank für die -wie ich finde, Gewinn 
bringende- Diskusion und Beteiligung. Leider hab ich grad noch allerhand 
andere Baustellen, also nicht wundern wenn es nicht gleich weiter geht..

Zum Thema map-File: mit -g0 finde ich jetzt zumindest keine Stelle mehr, 
an welcher sich Adressen unterscheiden (mit Außnahme einer .debug_str 
section, deren Größe aber 0 ist; ?aus ner lib?).

Vielleicht ist die Info noch nützlich dass ich zunächst tatsächlich das 
elf File erzeuge und mit objcopy dann das hexfile.

Ich hab das Ganze übrigens zum  Test auch mal mit dem IAR-Compiler und 
dessen libs übersetzt. Da sind die hexfiles identisch.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rüdiger F. schrieb:
> Ich hab das Ganze übrigens zum  Test auch mal mit dem IAR-Compiler und
> dessen libs übersetzt. Da sind die hexfiles identisch.

Zwischen Linux und Windows?  Gibt's denn IAR neuerdings für Linux?

von R. F. (ruefo)


Lesenswert?

Naja ne, war nur wine. Hast Recht. Wollte halt nur mal sehen, ob da die 
Umgebung auch Einfluss hat.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rüdiger F. schrieb:
> Wollte halt nur mal sehen, ob da die Umgebung auch Einfluss hat.

Nö, kann keinen Einfluss haben.

Wenn du da Unterschiede rausbekommst jenseits der Debugsymbole, dann
heißt das, dass Atmel trotz gleicher Release-Nummern doch nicht so
ganz die gleiche Basis für ihre veröffentlichten Toolchains benutzt
hat.

Vermutlich sind die Unterschiede harmlos, aber sie deuten natürlich
darauf hin, dass sie da irgendwie ihre Release-Prozesse nicht im
Griff haben.

Wenn euch exakte Gleichheit wichtig ist, bliebe natürlich immer noch,
sich die Toolchains komplett selbst zu compilieren.  Ist ja keine
Raketenwissenschaft …

von R. F. (ruefo)


Lesenswert?

Jörg W. schrieb:

> Wenn euch exakte Gleichheit wichtig ist, bliebe natürlich immer noch,
> sich die Toolchains komplett selbst zu compilieren.  Ist ja keine
> Raketenwissenschaft …

Ich werde es mal versuchen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Rüdiger F. schrieb:
> Habe gerade mal den Code auf eine leere Main-Loop reduziert und dann die
> gleichen Makefiles verwendet (gleiche CFLAGS wie beim vollständigen
> Projekt). Ergebnis: Gleiches Hex-File.

Es wäre natürlich schon geschickt, wenn du das Problem anhand eines
einfachen Beispiels, das nicht der Geheimhaltung unterliegt,
reproduzieren könntest.

Wenn du wieder etwas Zeit hast, könntest du ja das leere Main mal mit
etwas Inhalt füllen, insbesondere mit ein paar Aufrufen von Funktionen
aus der C-Bibliothek, die auch in der eigentlichen Applikation verwendet
werden. Das Programm muss nichts Sinnvolles tun, es geht nur darum, dass
es nicht leer ist und der Linker eine halbwegs repräsentative Auswahl
von Bibliotheksfunktionen anfügt.

Falls du es auf diese Weise schaffst, zwei unterschiedliche Binaries zu
erstellen, postets du am besten die beiden ELF-Dateien. Wenn man diese
disassembliert, sollte man eigentlich erkennen können, wo der Hund
begraben liegt.

Noch zwei Fragen hätte ich:

Verwendet ihr eigene Bibliotheken, die beim Bauen der Software nicht
jedesmal kompiliert, sondern nur als Binärcode hinzugelinkt werden?
Falls ja, könnte es hier einen Versionsunterschied geben?

Und du bist auch sicher, dass beim Bauen sämtliche Quelldateien
kompiliert werden? Nicht, dass da noch ältere .o-Dateien herumliegen,
die – aus welchen Gründen auch immer – durch Make nicht aktualisiert
werden.

von R. F. (ruefo)


Lesenswert?

Yalu X. schrieb:

> Verwendet ihr eigene Bibliotheken, die beim Bauen der Software nicht
> jedesmal kompiliert, sondern nur als Binärcode hinzugelinkt werden?
> Falls ja, könnte es hier einen Versionsunterschied geben?

Nein und nein.

> Und du bist auch sicher, dass beim Bauen sämtliche Quelldateien
> kompiliert werden? Nicht, dass da noch ältere .o-Dateien herumliegen,
> die – aus welchen Gründen auch immer – durch Make nicht aktualisiert
> werden.

Nein, ich lösche jedesmal den kompletten Build-Ordner.

von Bernd K. (prof7bit)


Lesenswert?

warum vergleichst Du nicht einfach die jeweiligen Disassemblies der 
beiden Hex-Dateien und schaust einfach nach worin der Untersschied 
besteht anstatt darüber zu grübeln und zu spekulieren?

von S. R. (svenska)


Lesenswert?

Jörg W. schrieb:
> Wenn die Hex-Dateien unterschiedlich sind, dann müssen es die
> ELF-Dateien auch sein (OK, gleiche Zeilenlänge natürlich mal
> vorausgesetzt).

Dass es einen Unterschied gibt, ist unstrittig. Aber die ELF-Datei kann 
auch sagen, wo es den Unterschied gibt. Genauso kann man auch die 
einzelnen Objectfiles strippen und dann vergleichen, die müssen auch 
identisch sein.

Rüdiger F. schrieb:
> Vielleicht ist die Info noch nützlich dass ich zunächst tatsächlich das
> elf File erzeuge und mit objcopy dann das hexfile.

Davon sind wir, glaube ich, alle ausgegangen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

S. R. schrieb:
> Aber die ELF-Datei kann auch sagen, wo es den Unterschied gibt.

Sinnvolle Möglichkeiten, ELF-Dateien logisch zu vergleichen, kenne
ich nicht.  Physischer Vergleich hilft kaum mehr als bei Hex-Dateien.

Bliebe nur das Disassemblieren und anschließende Vergleichen, aber
das geht mit den Hexdateien auch.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Die ELF-Datei hat den Vorteil, dass man mit Hilfe der Symboltabelle –
zumindest ungefähr – die Funktion (und damit auch das Programmmodul oder
die Bibliothek) ermitteln kann, in der der Unterschied liegt.

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.