www.mikrocontroller.net

Forum: Compiler & IDEs Linker linkt inkonsistent


Autor: Simon Huwyler (simi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich habe ein Problem, das mich langsam in den Wahnsinn treibt. Vielleich
fällt dem Einen oder Andern ja etwas ein, was ich noch checken könnte.

Also:

Ich habe ein Makefile-basiertes STM32-C++Projekt in Eclipse neu
aufgesetzt.
crt0 und linker Script von ST, modifiziert von Matrin Thomas. Makefile
auch von der selben Quelle.

Das hat mal ganz ordentlich funktioniert, zumindest insofern, dass die
statischen Konstruktoren ausgeführt wurden. Malloc von Newlib konnte ich
auch einbinden, alles wunderbar. Dann habe ich FreeRTOS eingebaut (hat
in einem anderen Projekt perfekt funktioniert).

Und jetzt habe ich plötzlich folgendes Problem:

crt0 wird ausgeführt, aber beim Aufruf von main() springt der mir an die
total falsche Stelle. Will heissen: main() ist laut Map- und Listfile an
einer bestimmten Adresse A zu finden. crt0 springt aber an 'ne total
(wirklich völlig) andere Adresse B. Wenn ich den Debuger vor dem
main()-Aufruf stoppe und von Hand die Adresse A in's R3-Register
schreibe, springt er dahin, wo er hinsoll, nämlich zu main().

Was ich schon versucht habe: Neues Projekt aufsetzen und alle Files neu
einlesen. Natürlich make clean, mindestens ein Dutzend Mal gecheckt,
dass alle Object Files gelöscht sind, main mit extern "C" deklariert,
main mal als c-File statt cpp compiliert (natürlich im Makefile
angepasst), Code-Optimierungen rausgenommen. Wenn ich main.cpp ganz
lösche, moost der Linker, er fände main() nicht. Also sollte da auch
keine Leiche rumliegen.

So. Ich weiss, das schreit jetzt nach der Kristallkugel. Ich erwarte
natürlich auch keine Antwort im Sinne von: "Hey, diesen Knopf musst Du
drücken", sondern eher Tipps, in welche Richtung man denn eventuell noch
suchen könnte (z.B. irgendwelche Projekt-Einträge im Eclipse???)

Gruss
Simon

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon Huwyler schrieb:
> crt0 springt aber an 'ne total
> (wirklich völlig) andere Adresse B.

Wohin denn?  Kannst du über die Symboltabelle rausfinden, was an
dieser Stelle ist?

Ansonsten bleibt dir wohl nicht viel anderes übrig als zu analysieren
(auf Ebene des Disassemblers), was genau bis zu diesem Punkt passiert.

Autor: Simon Huwyler (simi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist ja gerade das Merkwürdige: Er springt irgendwo hin, wo weit und 
breit kein Symbol ist. Ich weiss gerade nicht auswendig, in welchches 
Modul, aber eben, einfach mittig irgendwo hinein.

Auf Ebene des Disassemblers ist alles wunderbar nachvollziehbar. Er lädt 
R3 mit 'ner Adresse, die er für die richtige Einsprungadresse hält und 
springt diese dann an. Im List-File lügt er mich sogar fadengerade und 
explizit an, dass das die Adresse von "main" sei. Und im selben 
List-File steht main an einer total anderen Adresse.

Irgendwie schon seeeeeehr merkwürdig...

Ich bin fast überzeugt, dass irgendwo irgendeine Leiche rumliegt. Nur - 
was ausser den Object-Files kann ich noch bereinigen?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann wirst du dir wohl oder übel mal ein Linkermapfile erzeugen müssen.
Die Dinger sind zwar "close to unreadable", aber recht ausführlich.

Autor: Simon Huwyler (simi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmmm, ja. Was mir noch eingefallen ist: Der Linker kann ja angewiesen 
werden, Code, "versetzt" abzulegen, z.B. den Code in's Rom ablegen, aber 
Referenzen dazu in's Ram zeigen zu lassen, in der Hoffnung, dass die 
crt0-Fee den Code nach dem Startup rüberkopiert (>RAM at >ROM).
Vielleicht ist da ausversehen irgendein Schalter umgelegt worden, ohne 
dass ich's gemerkt habe. Merkwürdig ist nur, dass der Sprung ins Flash 
geht und nicht ins RAM. Da müsste das Linkerscript (das ja für STM32 
gebaut wurde) schon ziemlich durcheinander geraten sein...
Muss das mal checken, wenn ich zu Hause bin.

Vielen Dank schon mal!

Simon

Autor: Simon Huwyler (simi)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Grrrrrr, es wird immer merkwürdiger! Schaut Euch mal diesen Screenshot 
an und sagt mir, was das denn soll!?!

Ich habe zweimal einen Aufruf von __init_Data(), und der Lümmel springt 
zweimal wo anders hin (siehe Disassembly)!

Ich kann mir das schlicht nicht mehr erklären! Da kann ich doch machen, 
was ich will, ein Label sollte doch immer die gleiche Adresse haben?

Kann sich jemand von Euch so was auf irgendeine Art erklären?

Übrigens: Weder die erste Adresse noch die zweite stimmt - zumindest 
insofern ist der Linker konsistent! ;-)

Autor: Simon Huwyler (simi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
GRRRRR.... Ich tat dem Linker unrecht!

  /* Initialize data and bss */
  __Init_Data();
 8000068:  f240 0395   movw  r3, #149  ; 0x95
 800006c:  f6c0 0300   movt  r3, #2048  ; 0x800
 8000070:  4798        blx  r3
  __Init_Data();
 8000072:  f240 0395   movw  r3, #149  ; 0x95
 8000076:  f6c0 0300   movt  r3, #2048  ; 0x800
 800007a:  4798        blx  r3

.
.
.

void __Init_Data(void) {
 8000094:  b480        push  {r7}

Die Adresse stimmt (bis auf das LSB, das ist für THUMB).


Warum zum Geier aber sagt mir de Debugger was anderes??

Autor: Roland Praml (pram)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Optimierung?
Da passt dann IMHO nichts mehr zusammen, weil teilweise Fuunktionen 
sogar in falscher Reihenfolge als im C++ Code ausgeführt werden.

Gruß
Roland

Autor: Simon Huwyler (simi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jup, das hatte ich zuerst. Sah lustig aus, wie der rumhopste! :-)

Aber die habe ich ausgeschaltet.

Merkwürdig ist, dass der Prozi wirklich an die falsche Stelle springt 
(es sei denn, der Debugger lügt mich EXTREM dreist an).

---> List File stimmt. Debugger "sieht" das aktuelle File (den doppelten 
Aufruf von __init_Data(). Im Flash steht tatsächlich ein doppelter 
bx-Befehl, wo er stehen sollte. Aber mit einer anderen Adresse als im 
List-File.

Was also inzwischen klar ist: Im Prozi-Flash steht was, was da nicht 
stehen sollte. Aber nur etwas ganz bischenbischen anderes. Nur die 
Adressen sind falsch....

..... inzwischen fange ich an, zu glauben, dass das Flash durch ist...

Autor: Simon Huwyler (simi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, ich sehe das Problem... naja, es ist jetzt zumindest nicht mehr 
soooo merkwürdig.

Meine letzte Aussage stellte sich als falsch heraus. Da ist halt doch 
etwas GANZ anderes im Flash als im Ram. Nämlich "alter" Code. Der wird 
gar nicht neu geflashed. Dann muss ich mal schauen, warum. Auf jeden 
Fall klärt das, warum der Sprünge an Adressen macht, die laut 
Source-File, Linker-Script und Map-File völlig falsch sind.

Nichts für Ungut
Simon

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.