www.mikrocontroller.net

Forum: Compiler & IDEs GCC 4.1.1 + -minit-stack


Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe vor kurzem AVR GCC 4.1.1 installiert. seit dem wird meine 
Option

-minit-stack=0x800400

Ignoriert.

der Aufruf des Compilers der main.c in welcher sich die main funktion 
befindet ist:

avr-gcc -c -fmessage-length=0 -Wall -Wstrict-prototypes 
-Wa,-adhlns=../main.lst -mmcu=atmega128 -minit-stack=0x800400 -Os 
-fshort-enums -fpack-struct -funsigned-char -funsigned-bitfields 
-std=gnu99 -save-temps -dB -DUART_RX_BUFFER_SIZE=512 
-DUART_TX_BUFFER_SIZE=64 -o"main.o" "../main.c" && \
echo -n 'main.d' ./ > 'main.d' && \

Ich nutze Eclipse unter WinXP mit dem AVR Plugin aus dem Thread

Beitrag "Eclipse und WinAVR"

habe mir mal die Assamblerdatei main.s angeschaut. bei GCC version 3.4.6 
steht da

.global  main
  .type  main, @function
main:
/* prologue: frame size=5 */
  ldi r28,lo8(0x800400 - 5)
  ldi r29,hi8(0x800400 - 5)
  out _SP_H_,r29
  out _SP_L_,r28
/* prologue end (size=4) */

GCC 4.1.1 macht daraus

.global  main
  .type  main, @function
main:
/* prologue: frame size=5 */
  push r16
  push r17
  push r28
  push r29
  in r28,__SP_L__
  in r29,__SP_H__
  sbiw r28,5
  in _tmp_reg_,__SREG__
  cli
  out _SP_H_,r29
  out _SREG_,__tmp_reg__
  out _SP_L_,r28
/* prologue end (size=12) */

alles beim gleichen aufruf des compilers

als erstes würde ich sagen, das der Prolog für die main funktion zu 
aufgeblasen ist, scheit als würde der compiler denken, er könne aus ihr 
zurückspringen.

weiterhin habe ich festgestellt, das bei GCC 3.4.6 der Stack 2 mal 
initialiesiert wurde. einmal auf 0x10FF und dann in der main funktion 
auf 0x0400 wie gewünscht.

habt ihr Eine idee wie ich GCC 4.1.1 dazu bringen kann, das er den Stack 
wert übernimmt??


Vielen Dank im Vorraus

Stefan

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

Bewertung
0 lesenswert
nicht lesenswert
Stefan wrote:

> -minit-stack=0x800400

> Ignoriert.

Aus dem Bauch raus würde ich sagen, diese Option hat mittlerweile
keinen Sinn mehr.

> als erstes würde ich sagen, das der Prolog für die main funktion zu
> aufgeblasen ist, scheit als würde der compiler denken, er könne aus
> ihr zurückspringen.

Ja, main() ist eine normale Funktion geworden.

Deklariere sie als

int __attribute__((noreturn))
main(void)
{
  ...
}

Eigentlich sollte es wohl besser noch ein __attribute__((c_task)) oder
sowas geben, das wie noreturn wirkt, aber trotzdem noch einen
return-Wert gestattet.  Der Unterschied hat aber nahezu nur
akademischen Wert.

> weiterhin habe ich festgestellt, das bei GCC 3.4.6 der Stack 2 mal
> initialiesiert wurde. einmal auf 0x10FF und dann in der main
> funktion auf 0x0400 wie gewünscht.

Richtig.  Die zweite Initialisierung (das ist die, die man mit
-minit-stack beeinflussen konnte) ist aber schon lange Kokolorus
gewesen.  Der Stack muss deutlich vor main() initialisiert werden, da
sonst insbesondere die C++-Konstruktoren keinen Stack haben.

Unabhängig davon, ob man nun main() wirklich als normale Funktion
behandelt werden sollte oder nicht (das hat uns in der jetzigen Form
ein wenig kommentarlos der ATmega256x-Patch mitgebracht), die
Geschichte mit der Stack-Initialisierung in main() (und damit auch die
-minit-stack Option) gehört auf den Müllhaufen der AVR-GCC-Geschichte
entsorgt.

> habt ihr Eine idee wie ich GCC 4.1.1 dazu bringen kann, das er den
> Stack wert übernimmt??

Ja, so wie auch schon die früheren Compiler, vermutlich mehrere Jahre
lang bereits:

-Wl,--defsym=__stack=0x800400

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg!

Vielen Dank für die Promte Antwort!

Funktioniert!

Habe auch das mit dem

int __attribute__((noreturn))
main(void)
{
  ...
}

Versucht, ändert aber nicht viel an dem Prolog der main funktion. auser 
das 2 push weniger sind. wenn mir mal die paar bytes fehelen, kann ich 
mich ja daran nochmalmachen.



Danke Stefan

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

Bewertung
0 lesenswert
nicht lesenswert
Stefan wrote:

> Habe auch das mit dem
>
> int __attribute__((noreturn))
> main(void)
> {
>   ...
> }
>
> Versucht, ändert aber nicht viel an dem Prolog der main funktion. auser
> das 2 push weniger sind.

Sorry, ja, das muss auch
int __attribute__((noreturn, naked)) main(void) ...

sein.

Ich weiß, der GCC klagt dann darüber dass eine noreturn-Funktion
einen return-Wert hätte bzw. bei Deklaration mit void umgekehrt,
dass main() nicht vom Typ int ist.  Damit muss man bis zu einer
,,richtigen'' Reparatur wohl erstmal leben.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg!

wenn ich das naked dazu nehme, dann wirds ganz wild, und der Compiler 
jammert:

../main.c:31: internal compiler error: in start_function, at 
c-decl.c:6014
Please submit a full bug report,
with preprocessed source if appropriate.


wers bei no return belassen, vielleicht klappts bei der nächsten GCC 
version. ich werds mir merken.


Gruß Stefan

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

Bewertung
0 lesenswert
nicht lesenswert
Stefan wrote:

> ../main.c:31: internal compiler error: in start_function, at
> c-decl.c:6014
> Please submit a full bug report,
> with preprocessed source if appropriate.

Dann bitte tu genau das.  Streich dein Programm so weit zusammen, dass
der ICE (internal compiler error) reproduzierbar ist, und reiche einen
Bugreport bei gcc.gnu.org ein.

> vielleicht klappts bei der nächsten GCC version.

Wenn es keiner als Bug berichtet, warum sollte sich was ändern?

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg!

Wollte den Bug gerade posten, ist aber schon von jemand anders gemacht 
worden.

http://sourceforge.net/tracker/index.php?func=deta...


Gruß Stefan

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

Bewertung
0 lesenswert
nicht lesenswert
Hmm, als WinAVR-Bugreport kommt er nicht zu den GCC-Entwicklern.

Anyway, ich kann das für meinen Compiler nicht reproduzieren.  Wenn du
einen Sourcecode hast, mit dem es reproduzierbar ist, dann würde ich
mich weiter drum kümmern wollen.  Bitte häng' das einfach an den
WinAVR-Bugreport dran.

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

Bewertung
0 lesenswert
nicht lesenswert
Ich hab's hier mit verschiedenen Projekten probiert, ich bekomme den
Bug nicht getriggert.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int __attribute__((noreturn, naked)) main(void)
{
    return 0; // for the compiler...
}

../Main.c:4: internal compiler error: in start_function, at c-decl.c:6014
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://sourceforge.net/tracker/?atid=520074&group_id=68108&func=browse> for instructions.
make: *** [Main.o] Error 1
Build failed with 1 errors and 0 warnings...

gcc 4.1.1


Oliver

Autor: Oliver (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier nochmal mit makefile.

Oliver

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

Bewertung
0 lesenswert
nicht lesenswert
Tja, ich habe das mittlerweile auch schon mit Eric Weddington
diskutiert, irgendwas scheint beim WinAVR-Compiler anders zu sein
als bei meinem.  Ist auch ein GCC 4.1.1, aber ich bekomme diesen
Bug nicht getriggert, egal womit.  Es gibt zwar minimale Differenzen
in den Patches zwischen WinAVR und FreeBSD, aber ich habe die
Patches seinerzeit verglichen und hätte nicht gedacht, dass bei
WinAVR einer dabei ist, der zu solchen Effekten führen könnte...

Wir haben auch nochmal die formale Syntaxbeschreibung der
Attribute im GCC-Handbuch nachgelesen, ich bin mittlerweile der
Meinung, dass aus GCC-Sicht folgendes technisch exakter wäre:
__attribute__((noreturn, naked)) int main(void) {
   ...
}

also die Attribute vor der Funktion.  Kannst du mal probieren, ob
das ein Unterschied ist für dich?

Ansonsten, was offenbar auf jeden Fall funktioniert ist, dass man
die Attribute nur in eine Prototypdeklaration steckt:
int main(void) __attribute__((noreturn, naked));
int
main(void) {
  ...
}

Idealerweise sollte man auch schreiben können
int
main(void) __attribute__((noreturn, naked))
{
  ...
}

aber dafür sagt das GCC-Handbuch ausdrücklich ``not yet implemented''.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
__attribute__((noreturn, naked)) int main(void) {
   ...
}
ergibt den selben Fehler wie oben.
int main(void) __attribute__((noreturn, naked));
int
main(void) {
  ...
}
funktioniert, ist aber auch nur 2 bytes kleiner als ein normales int 
main().
int
main(void) __attribute__((noreturn, naked))
{
  ...
}
bringt
>../Main.c:3: error: expected ',' or ';' before '{' token


Oliver

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

Bewertung
0 lesenswert
nicht lesenswert
Oliver wrote:

>
__attribute__((noreturn, naked)) int main(void) {
>    ...
> }
> ergibt den selben Fehler wie oben.

OK.

> ..., ist aber auch nur 2 bytes kleiner als ein normales int
> main().

Naja, mehr scheint's dann nicht zu sparen zu geben.  Ich habe
damit jedenfalls (wie gewünscht) keinen Prolog mehr in main().

naked allein genügt eigentlich auch.

>>../Main.c:3: error: expected ',' or ';' before '{' token

Ja, ``currently not supported'' eben.

Autor: Jörg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann den Crash von WinAVR gcc 4.1.1 bestätigen, ich bekomme das auch 
wenn ich
__attribute__((noreturn, naked)) int main(void)
{
}
verwende.
Alternativ auch bei meiner Hauptschleife (Unterfunktion von main), die 
habe ich wahlweise auch so dekoriert.

Wenn ich hingegen nur den Prototypen dekoriere, also
__attribute__((noreturn, naked)) int main(void);
int main(void)
{
}
dann klappts. Spart bei bei main() nur 2 Bytes, hingegen bei der 
Hauptschleife 18 Bytes! Anscheinend hat er bei main() schon was erkannt. 
Ich habe noch nicht ins Disassembly geguckt.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Mit dem Prototype

int main(void) __attribute__((noreturn, naked));

und dann:

int main(void) {

}

funktioniert es bei mir, und der Prolog wird auf 0 Byte 
zusammengestrichen, jedoch wie schon befürchtet mit der Warnung:

../main.c: In function 'main':
../main.c:102: warning: function declared 'noreturn' has a 'return' 
statement
Finished building: ../main.c

ansonnsten hast du ja deine Informationen die du brauchst, oder Jörg.


Gruß Stefan

Autor: Veit Wehner (veitwehner)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich hab die haessliche warning: `noreturn' function does return so 
wegbekommen, allerdings in einer beliebigen Fkt, nicht unbedingt main. 
Der Compiler meckert sonst, wenn er nicht eine Funktion erkennt, von der 
er weiss, dass sie nie zurueckkommt (wie zB exit)

#if !defined(_lint_)
#define _NORETURN_    for (;;) continue
#else
#define _NORETURN_
#endif

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.