Forum: Compiler & IDEs Linker Problem wegen _sbrk() trotz newlib_stubs.c/mini_cpp.cpp


von U. E. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich kämpfe gerade mit dem Problem, mit CodeSourcery 4.5.1 für den 
STM32F103RE ein C++ ein kleines Programm zu erstellen.
Die Compilation des Programms (blinkende LED mit einem new Statement, um 
den g++ zu "provozieren") klappt, beim Linken gibt es die in vielen 
Threads beschriebenen Probleme mit der newlib (u.a. fehlende _sbrk()).

Deshalb habe ich zwei Dateien dazugelinkt: newlib_stubs.c (für _sbrk()) 
und mini_cpp.cpp ( new und delete Ersatz, der malloc und free direkt 
aufruft).
Quellen:
https://sites.google.com/site/stm32discovery/open-source-development-with-the-stm32-discovery/getting-newlib-to-work-with-stm32-and-code-sourcery-lite-eabi
http://svnmios.midibox.org/filedetails.php?repname=svn.mios32&path=%2Ftrunk%2Fprogramming_models%2Ftraditional%2Fmini_cpp.cpp&rev=846&sc=1

Allerdings, das Problem bleibt. Es ist, als ob er Linker die Dateien 
glatt ignoriert. Hier der Aufruf:
1
 arm-none-eabi-g++ -v -o elf/main.elf obj/main.o obj/system_stm32f10x.o  
2
obj/startup_stm32f10x.o obj/stm32f10x_rcc.o  obj/stm32f10x_gpio.o  obj/newlib_stubs.o obj/core_cm3.o obj/mini_cpp.o -TSTM32F10x_512k_64.ld 
3
-LC:/Entwicklung/CodeSourcery/arm-none-eabi/lib/thumb2 
4
-LC:/Entwicklung/CodeSourcery/lib/gcc/arm-none-eabi/4.5.1/thumb2 -nostartfiles -Wl--cref,--gc-sections
Die Ausgabe des Linkers ist im Attachment. Hat jemand eine Idee?

Grüße
schnack

von klaus (Gast)


Lesenswert?

Lass dir mal eine .map file generieren und schaue dort ob die Funktion 
_sbrk() wirklich vorhanden ist. evtl. Kannst du ja mal dann die .map 
file posten

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?


von U. E. (Gast)


Lesenswert?

Hallo Martin,
den Link auf Deine Seite habe ich (natürlich :-) schon in anderen 
Threads gefunden und - nach bestem Wissen und Gewissen - genutzt. Die 
newlib_stubs.c entspricht ja Deiner syscalls.c - soweit ich das sehen 
kann. Das Verständnis Deines Makefile erfordert allerdings etwas 
solidere Erfahrung, als ich sie derzeit mitbringe. Deshalb bin ich mir 
auch nicht sicher, ob ich beim "Übertragen" der Linker Optionen etwas 
wichtiges übersehen habe.

Ich bin schon am Grübeln, ob ich die Nutzung der newlib mit den Stubs 
gleich ganz sein lasse und statt malloc/free aus der Lib eine eigene 
"primitiv"-Allokation aufmache. Denn im Grunde will ich ja nur in der 
Lage sein, Speicher zur Laufzeit zu allokieren, um aus 
Konfigurationsdaten Objekte zu erzeugen, die dann aber ständig erhalten 
bleiben. Eine Freigabe per free() muß noch nicht einmal unterstützt 
werden. Ich frage mich nur, ob ich damit (für meine Kenntnisse) ein zu 
großes großes Fass aufmache.., habe aber dennoch schon mal 
http://developers.stf12.net/cpp-demo/gcc-linker-script-and-stm32-a-tutorial 
angelesen.

Ich mache mich jetzt mal an den Vorschlag, die .map Datei zu erzeugen.

Grüße
schnack

von U. E. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
hier ist die .map-Datei. Darin ist auch die _sbrk() aus der 
newlib_stubs.o aufgeführt..
Grüße
schnack

von klaus (Gast)


Lesenswert?

Evtl. werden die Versionen mit _reent Argument benutzt. Probier mal 
folgende Signatur:
1
void* _sbrk_r(struct _reent* r, ptrdiff_t size)

Diese habe ich in einem meiner ARM GCC Projekte verwendet.

von U. E. (Gast)


Lesenswert?

Hallo Klaus,
an der Signatur hat es anscheinend nicht gelegen. Ich habe sie etwas 
modifizieren müssen (size -> incr):
1
void* _sbrk_r(struct _reent* r, ptrdiff_t incr) {
2
    //caddr_t _sbrk(int incr) {
3
4
    extern char _ebss; // Defined by the linker
5
    static char *heap_end;
6
    char *prev_heap_end;
7
[..]

Leider hat dies nichts geändert.. schade - aber danke!
Grüße
schnack

von U. E. (Gast)


Lesenswert?

Hi,
ich habe noch einmal nachgeschaut. Der Linker-Fehler ist:

1
C:/Entwicklung/CodeSourcery/arm-none-eabi/lib/thumb2\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
2
sbrkr.c:(.text+0x12): undefined reference to `_sbrk'

In der newlib gibt es die Datei sbrkr.c mit dem Abschnitt:
1
void *
2
_DEFUN (_sbrk_r, (ptr, incr),
3
     struct _reent *ptr _AND
4
     ptrdiff_t incr)
5
{
6
  char *ret;
7
  void *_sbrk(ptrdiff_t);
8
9
  errno = 0;
10
  if ((ret = (char *)(_sbrk (incr))) == (void *) -1 && errno != 0)
11
    ptr->_errno = errno;
12
  return ret;
13
}

Demnach war die alte Signatur wohl doch passend, hm.
Grüße
schnack

von Oliver (Gast)


Lesenswert?

C. D. schrieb:
> Demnach war die alte Signatur wohl doch passend, hm.
> Grüße

Das erklärt aber immer noch nicht, warum dein linker die von dir zur 
Verfügung gestellte _sbrk ingnoriert.

Was passiert, wenn du statt des g++ den gcc zum zum linken aufrufst?

Oliver

von U. E. (Gast)


Angehängte Dateien:

Lesenswert?

Hi,
inzwischen habe ich das Problem dadurch "umgangen", daß ich nun 
tatsächlich einen ersten Wurf gebaut habe, um new() minimal zu 
implementieren.
Dazu habe ich einen kleinen Teil aus der core_cm3.c und dem Code für 
_sbrk() verwendet (siehe Anhang: mini_cpp.cpp).
Das Linken damit klappt. Ein Code wie:
1
int main(void)
2
{
3
  int* g1 = new int;
4
  *g1 = 34;
5
6
  int* g2 = new int;
7
  *g2 = 898;
8
[..]
läßt sich damit korrekt compilieren und ausführen (im Debugger geprüft). 
Weitere Tests müssen natürlich folgen.

Irritierend:
1. In Eclipse Galileo läßt sich mit dem Debugger arm-none-eabi-gdb.exe 
(Version 4.5.1) mit dem JLink EDU nicht arbeiten (Fehlermeldungen), nach 
dem Übergang auf die CodeSourcery Version 4.4.1 klappte das durchaus 
(bei absolut gleichem Setup des HW Debugging).
2. Wenn ich den arm-none-eabi-g++/gcc zum Linken einsetze (Version 
4.4.1) , klappt das Linken, wie  beschrieben. Ein Linken mit 
arm-none-eabi-ld klappt auf spektakuäre Weise nicht : Der Linker 
erzeugt keine elf-Datei, liefert auch keinen Fehler- er macht einfach 
nichts.. (??). Es sieht dann so aus - der Fehler wird erst im zweiten 
Befehl offenbar:
1
make all 
2
..linking
3
arm-none-eabi-ld -v -o elf/main.elf  obj/main.o obj/system_stm32f10x.o  obj/startup_stm32f10x.o obj/stm32f10x_rcc.o  obj/stm32f10x_gpio.o obj/mini_cpp.o -TSTM32F10x_512k_64.ld -nostartfiles     
4
GNU ld (Sourcery G++ Lite 2010q1-188) 2.19.51.20090709
5
arm-none-eabi-objdump -S elf/main.elf > elf/main.lst
6
c:\Entwicklung\CodeSourcery\bin\arm-none-eabi-objdump.exe: 'elf/main.elf': No such file
7
make: *** [target] Error

Grüße
schnack

von 900ss (900ss)


Lesenswert?

C. D. schrieb:
> Ein Linken mit
> arm-none-eabi-ld klappt auf spektakuäre Weise nicht

Es ist auch unüblich, den Linker direkt aufzurufen. Der soll eigentlich 
über den GCC aufgerufen werden. Die Optionen unterscheiden sich auch. 
Wenn du direkt den gcc mit ld tauscht ohne die Optionen anzupassen, dann 
geht das schief.

von U. E. (Gast)


Lesenswert?

> Es ist auch unüblich, den Linker direkt aufzurufen
Ok.
> Wenn du direkt den gcc mit ld tauscht ohne die Optionen anzupassen, dann
> geht das schief.
Nun ja. Ich kann ja schlecht das Gegenteil behaupten. Allerdings 
verstehe ich nicht, wieso der Linker still und leise abschmiert. Das ist 
doch kein Problem der Optionen..?
Grüße
schnack

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.