Forum: Compiler & IDEs Attribute used im gcc


von Sebastian K. (seplog)


Lesenswert?

Hallo,

ich bin gerade dabei mich ein wenig mit RISC-V zu beschäftigen. Aber ich 
denke das Problem das ich gerade habe liegt eher beim GCC.
Folgendes. Ich möchte zur Compilezeit eine Liste auf dem Flash 
erstellen. Dazu lege ich Variablen in der rodata-Section an. Ich habe 
dort ein start und ein end und dann die Elemente der Liste. Auf die 
Elemente der Liste verweise ich im Programmcode aber nicht. Aus dem 
Grund werden die leider wegoptimiert. Also dachte ich das wäre genau 
etwas für das attribute used.

https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html#index-g_t_0040code_007bused_007d-attribute_002e-2641

Nur leider wird das immer noch wegoptmiert... :(
1
#include <stddef.h>
2
#include <stdio.h>
3
#include <stdlib.h>
4
5
const char list_start[ 0 ] __attribute__( ( section( ".rodata.list.0-start" ) ) );
6
const char list_end[ 0 ] __attribute__( ( section( ".rodata.list.2-end" ) ) );
7
const char list[] __attribute__( ( used, section( ".rodata.list.1-elements" ) ) ) = "Some data\n";
8
9
int main( void ) {
10
    ptrdiff_t length = &list_end[ 0 ] - &list_start[ 0 ];
11
    printf( "Length: %d\n", length );
12
    return EXIT_SUCCESS;
13
}
1
$ riscv32-unknown-elf-gcc -Os -std=gnu99 -W -Wall -Wstrict-prototypes -Wundef -ffunction-sections -g -fdata-sections -fno-stack-protector -march=rv32imac -mabi=ilp32 -specs=picolibc.specs --oslib=semihost --crt0=hosted -Wl,-Tsifive-e31.ld  -c -MMD -MP -MF"./build/src/main.d" -MT"./build/src/main.d" -c -o "./build/src/main.o" "src/main.c"
2
$ riscv32-unknown-elf-gcc -flto -Wl,-Map,"./build/citest.map" -march=rv32imac -mabi=ilp32 -specs=picolibc.specs --oslib=semihost --crt0=hosted -Wl,-Tsifive-e31.ld  -flto  -o "./build/main.elf" ./build/src/main.o
3
$ qemu-system-riscv32 -chardev stdio,mux=on,id=stdio0 -semihosting-config enable=on,chardev=stdio0,arg=test-file -mon chardev=stdio0,mode=readline -serial chardev:stdio0 -machine sifive_e,revb=true -cpu sifive-e31 -kernel build/main.elf -bios none -nographic
4
Length: 0

Auch in der Map-File ist leider nichts vorhanden, was auf 1-elements 
hinweist. :/ Sobald ich aber auf list verweise funktioniert das... Das 
möchte ich aber nicht! ^^

Wie ihr seht, ich nutze die picolibc und probiere das erst einmal in 
qemu...

Den gcc nutze ich in folgender Version
1
 $ riscv32-unknown-elf-gcc --version
2
riscv32-unknown-elf-gcc (Gentoo 8.5.0-r1 p2) 8.5.0
3
Copyright (C) 2018 Free Software Foundation, Inc.
4
Dies ist freie Software; die Kopierbedingungen stehen in den Quellen. Es
5
gibt KEINE Garantie; auch nicht für MARKTGÄNGIGKEIT oder FÜR SPEZIELLE ZWECKE.

Entweder habe ich dort einen Knoten im Kopf und interpretiere die Doc 
vom used falsch, oder keine Ahnung. Zumindest benötige ich die Daten in 
dieser Section ohne explizit darauf verweisen zu müssen. Für Erklärungen 
wäre ich sehr dankbar! ;)

Viele Grüße

sep

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

Du hast used nur bei list, nicht aber list start und end. Die packst Du 
zwar Linker-mäßig vor und nach list, aber der Compiler kann die bereits 
wegoptimieren und tut das auch.

von Sebastian K. (seplog)


Lesenswert?

Hallo Nop,

Lt Map-File sind list-start/end aber vorhanden. Diese sollten dort 
eigentlich nicht wegoptimiert werden. Trotzdem habe ich das einmal 
probiert. Und es funktioniert leider nicht.
1
#include <stddef.h>
2
#include <stdio.h>
3
#include <stdlib.h>
4
5
const char list_start[ 0 ] __attribute__( ( used, section( ".rodata.list.0-start" ) ) );
6
const char list_end[ 0 ] __attribute__( ( used, section( ".rodata.list.2-end" ) ) );
7
const char list[] __attribute__( ( used, section( ".rodata.list.1-elements" ) ) ) = "Some data\n";
8
9
int main( void ) {
10
    ptrdiff_t length = &list_end[ 0 ] - &list_start[ 0 ];
11
    printf( "Length: %d\n", length );
12
    return EXIT_SUCCESS;
13
}
1
$ qemu-system-riscv32 -chardev stdio,mux=on,id=stdio0 -semihosting-config enable=on,chardev=stdio0,arg=test-file -mon chardev=stdio0,mode=readline -serial chardev:stdio0 -machine sifive_e,revb=true -cpu sifive-e31 -kernel build/main.elf -bios none -nographic
2
Length: 0

Danke trotzdem ;)

Viele Grüße

sep

von Nop (Gast)


Lesenswert?

Sebastian K. schrieb:

> Lt Map-File sind list-start/end aber vorhanden.

Du könntest ja mal Mapfile und Linkerfile posten, vieleicht sieht jemand 
da ja noch was?

von Sebastian K. (seplog)


Angehängte Dateien:

Lesenswert?

Eigentlich wollte ich das auch. Dann einmal hier beide die Dateien. ;)

von Sebastian K. (seplog)


Angehängte Dateien:

Lesenswert?

Vielleicht ist diese ja auch noch von Interesse...
Das ist das std-linker file

von Sebastian K. (seplog)


Lesenswert?

Hm. Das ist gerade mir gerade aufgefallen. In der erzeugten main.o Datei 
ist das noch vorhanden...
1
$ riscv32-unknown-elf-strings build/src/main.o
2
Some data
3
...
4
.rodata.list.1-elements
5
...

Erst beim Linken wird es weg geschmissen. Ich habe das nun auch einmal 
ohne -flto beim linken probiert, da fliegt es trotzdem weg.

von Nop (Gast)


Lesenswert?

Aus dem Mapfile:
1
Discarded input sections
2
3
 .rodata.list.1-elements
4
                0x0000000000000000        0xb ./build/src/main.o
5
(...)
6
7
Linker script and memory map
8
9
 .rodata.list.0-start
10
                0x0000000020012068        0x0 ./build/src/main.o
11
                0x0000000020012068                list_start
12
 .rodata.list.2-end
13
                0x0000000020012068        0x0 ./build/src/main.o
14
                0x0000000020012068                list_end

Das bestätigt zumindest mal die Nulldifferenz, weil "list" verworfen 
wird.

Was mir aus dem Linkerfile nicht klar wird: Wo kommen eigentlich die 
Sections für .rodata.list.xyz her? Funktioniert sowas automatisch mit 
alphabetischer Sortierung? Oder muß man sowas deklarieren?

von Sebastian K. (seplog)


Lesenswert?

Das sollte eigentlich dies hier aus der picolibc.ld (Zeile 83) sein.
1
                *(.rodata .rodata.*)
Soweit ich das immer verstanden habe wird das sortiert. Kann mich aber 
auch irren... ...

von Nop (Gast)


Lesenswert?

Ah, das ergibt Sinn. Ich habe allerdings in meinem Linkerfile für die 
ISR-Tabelle noch sowas stehen:
1
KEEP(*(.isr_vector))

Ich vermute, daß "used" zwar den Compiler instruiert, nicht aber den 
Linker.

von Sebastian K. (seplog)


Lesenswert?

Jo. Im object drin, nach dem Linken nicht mehr. Mir ist nun aufgefallen, 
dass ein einziger Verweis auf irgendein Objekt in dem Speicherbereich 
komplett reicht. Dann wird die komplette section mit gelinkt. Also hab 
ich einmal folgendes probiert...
1
#include <stddef.h>
2
#include <stdio.h>
3
#include <stdlib.h>
4
5
const char list_start[ 0 ] __attribute__( ( used, section( ".rodata.list.0-start" ) ) );
6
const char list_end[ 0 ] __attribute__( ( used, section( ".rodata.list.2-end" ) ) );
7
const char list_ref[ 0 ] __attribute__( ( used, section( ".rodata.list.1-elements" ) ) );
8
9
const char list[] __attribute__( ( used, section( ".rodata.list.1-elements" ) ) ) = "Some data\n";
10
const char more[] __attribute__( ( used, section( ".rodata.list.1-elements" ) ) ) = "More data\n";
11
const char hello[] __attribute__( ( used, section( ".rodata.list.1-elements" ) ) ) = "Hm, here is a Hello World!\n";
12
13
int main( void ) {
14
    ptrdiff_t length = &list_end[ 0 ] - &list_start[ 0 ];
15
    printf( "Length: %d\n", length );
16
    return EXIT_SUCCESS;
17
}
Hier habe ich einmal list_ref hinzugefügt.
1
$ riscv32-unknown-elf-gcc -u list_ref -Wl,-Map,"./build/main.map" -march=rv32imac -mabi=ilp32 -specs=picolibc.specs --oslib=semihost --crt0=hosted -Wl,-Tsifive-e31.ld  -flto  -o "./build/main.elf" ./build/src/main.o

Bleibt die section auch erhalten.
1
 .rodata.list.0-start
2
                0x0000000020012068        0x0 ./build/src/main.o
3
                0x0000000020012068                list_start
4
 .rodata.list.1-elements
5
                0x0000000020012068       0x34 ./build/src/main.o
6
                0x0000000020012068                hello
7
                0x0000000020012084                more
8
                0x0000000020012090                list
9
                0x000000002001209c                list_ref
10
 .rodata.list.2-end
11
                0x000000002001209c        0x0 ./build/src/main.o
12
                0x000000002001209c                list_end

Dann läuft es auch.
1
 $ qemu-system-riscv32 -chardev stdio,mux=on,id=stdio0 -semihosting-config enable=on,chardev=stdio0,arg=test-file -mon chardev=stdio0,mode=readline -serial chardev:stdio0 -machine sifive_e,revb=true -cpu sifive-e31 -kernel build/main.elf -bios none -nographic
2
Length: 52

Ich finde das zwar ein wenig "Würgaround" aber funktionieren tut das 
erst einmal. Vielleicht fällt jemandem ja noch was schöneres ein dem 
Linker iwie kundzutun bestimmte sections nicht wegzuwerfen.

Ansonsten vielen vielen Dank für die Diskussion. Die hat sehr geholfen 
;)

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


Lesenswert?

Sebastian K. schrieb:
> bestimmte sections nicht wegzuwerfen

Zum Beispiel, indem man einfach auf --gc-sections verzichtet und 
stattdessen nur das linkt, was auch benötigt wird?

von Sebastian K. (seplog)


Lesenswert?

Jörg W. schrieb:
> indem man einfach auf --gc-sections verzichtet

Das wäre auch was und das steht ja in den spec drin... Wobei das ja auch 
einige Vorteile hat speziell wenn Daten wirklich mal nicht benötigt 
werden.

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


Lesenswert?

Sebastian K. schrieb:
> Wobei das ja auch einige Vorteile hat

Klar, man kann mehr herum schlampern, der Linker wird es dann schon 
richten. ;-)

--gc-sections ist seinerzeit wohl insbesondere hinsichtlich C++ 
eingeführt worden, weil man dort eben über manche Gebilde (Konstruktoren 
/ Destruktoren) nicht im Quelltext selbst entscheiden kann, sondern der 
Compiler verpflichtet ist, sie anzulegen. Da hilft es dann, wenn der 
Compiler sie in separate sections ablegen kann und der Linker alle die, 
die am Ende nicht referenziert werden, entfernt werden.

Also Option für "ich schreibe einfach mal alles hin, was mir einfällt, 
egal, ob's am Ende gebraucht wird oder nicht" war es eigentlich nicht 
gedacht.

von Sebastian K. (seplog)


Lesenswert?

Jörg W. schrieb:
> Klar, man kann mehr herum schlampern, der Linker wird es dann schon
> richten. ;-)
>

*Hust...
Das dachte ich mir auch gerade als ich senden geklickt habe! :D

Der Compiler ist aber unter anderem für solche Optimierungen da. Wäre ja 
zu schön, wenn man sich um alles selber kümmern müsste. ;)
Ich denke zu totem Code kommt man schnell und nicht immer direkt 
sichtbar. Der Compiler kann das besser analysieren und den toten Code 
dann raushauen. Zusätzlich dann auch die Sections, welche nicht 
dazugehören. Immerhin ist der Compiler bei sowas um einiges 
zuverlässiger als der Mansch. :) Viel mit "rumschlampen" hat das dann 
nicht zu tun.

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


Lesenswert?

Sebastian K. schrieb:
> Ich denke zu totem Code kommt man schnell und nicht immer direkt
> sichtbar.

Naja, ist ein Qualitätsmerkmal der Softwareentwicklung.

Es ist ja nicht nur der eingesparte Platz. Der tote Code verrottet 
unbemerkt, da er ja nicht benutzt wird. Zwei Jahre später braucht mal 
jemand die Funktionalität, die der tote Code verspricht zu 
implementieren, benutzt die Funktion wieder – und sucht sich einen Wolf, 
warum das nicht (mehr) klappt, bis er dann begreift, dass der Code schon 
ewig nicht mehr benutzt worden war zuvor.

Bei uns ist sowas jedenfalls im Codereview rausgeflogen. Die History zu 
erhalten ist Aufgabe des VCS.

von Nop (Gast)


Lesenswert?

Sebastian K. schrieb:
> Vielleicht fällt jemandem ja noch was schöneres ein dem
> Linker iwie kundzutun bestimmte sections nicht wegzuwerfen.

Indem man sie im Linkerfile mit KEEP aufführt, das wäre mein Ansatz 
(siehe oben).


Jörg W. schrieb:

> Naja, ist ein Qualitätsmerkmal der Softwareentwicklung.

Oftamals ja. Aber wenn Du Libraries hast, die man projektübergreifend 
nutzt und pflegt, dann ist es normal, daß sowohl Code als auch Daten 
nicht in jedem Projekt komplett genutzt werden. Könnte man alternativ 
natürlich mit einem Zoo an #ifdefs in den Griff kriegen.

Aber wie kamst Du eigentlich darauf, als Lösung --gcsections 
wegzulassen? In den Compiler-Aufrufen sehe ich das ohnehin nicht?

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


Lesenswert?

Nop schrieb:

> Aber wenn Du Libraries hast, die man projektübergreifend
> nutzt und pflegt, dann ist es normal, daß sowohl Code als auch Daten
> nicht in jedem Projekt komplett genutzt werden. Könnte man alternativ
> natürlich mit einem Zoo an #ifdefs in den Griff kriegen.

Oder richtige Libraries draus machen: eine Funktion (oder eine wirklich 
zusammen gehörige Gruppe von Funktionen) pro Objektmodul, und dann den 
Archivar benutzen.

Der Linker pickt sich dann nur die Module, die er braucht.

> Aber wie kamst Du eigentlich darauf, als Lösung --gcsections
> wegzulassen?

Weil es ja offensichtlich das Problem verursacht (hat).

> In den Compiler-Aufrufen sehe ich das ohnehin nicht?

Steht im .specs File, welches oben auch gepostet worden ist.

von Sebastian K. (seplog)


Lesenswert?

Danke euch beiden auf alle Fälle!

Nop schrieb:
> Indem man sie im Linkerfile mit KEEP aufführt, das wäre mein Ansatz
> (siehe oben).

Das ist mir auch noch als Idee gekommen als ich darüber ein wenig weiter 
sinniert habe. Nun ist ja aber die Sache, dass ich nicht das komplette 
ld-script kopieren wollen würde. Da habe ich dann auch was zu gefunden.

http://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html#Miscellaneous-Commands

Wenn ich mir nun dort einmal das Bsp für Insert [AFTER|BEFORE] anschaue 
und das für mich adaptiere erstelle ich mir folgendes:
1
$ cat main.ld 
2
SECTIONS
3
{
4
  .rodata.list :
5
  {
6
    *(.list*)
7
  }
8
}
9
INSERT AFTER .rodata;

Leider mag das aber nicht. .rodata ist aber auf alle Fälle vorhanden. 
Kann mir jmd dort sagen warum?
1
riscv32-unknown-elf-gcc -Wl,-Map,"./build/main.map" -march=rv32imac -mabi=ilp32 -specs=picolibc.specs --oslib=semihost --crt0=hosted -Wl,-Tsifive-e31.ld  -flto -Wl,-Tmain.ld  -o "./build/main.elf" ./build/src/main.o   
2
/usr/libexec/gcc/riscv32-unknown-elf/ld: .rodata not found for insert
3
collect2: Fehler: ld gab 1 als Ende-Status zurück

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


Lesenswert?

Sebastian K. schrieb:
> .rodata ist aber auf alle Fälle vorhanden

Wenn das da oben dein kompletter Linkerscript ist – nö, da ist kein 
.rodata drin. Auch sonst nicht viel.

Du musst den Linkerscript schon, wenn du ihn anpassen willst, komplett 
selbst schreiben und pflegen.

von Sebastian K. (seplog)


Lesenswert?

Jörg W. schrieb:
> Du musst den Linkerscript schon, wenn du ihn anpassen willst, komplett
> selbst schreiben und pflegen.

Das dachte ich auch bisher. Nun hab ich aber diese beiden Sachen 
gefunden.
http://www.kaizou.org/2016/08/decentralized-modules-c-elf-sections.html
https://stackoverflow.com/questions/6877922/injecting-sections-into-gnu-ld-script-script-compatibility-between-versions-of

sobald ich das für x86 übersetze macht der das auch. Leider aber nicht 
für riscv. Von der ersten Seite ist hier einmal ein Testprojekt...
https://github.com/kaizouman/c_modules_section_sample

Auch wenn ich einmal gucke...
1
$ riscv32-unknown-elf-gcc -flto -Wl,-Map,"./build/citest.map" -march=rv32imac -mabi=ilp32 -specs=picolibc.specs --oslib=semihost --crt0=hosted -Wl,-Tsifive-e31.ld  -flto  -o "./build/main.elf" ./build/src/main.o

Selbst hier übersetzte ich schon mit einer weiteren ld-Datei... Der 
Inhalt:
1
$ cat sifive-e31.ld 
2
__flash = 0x20010000;
3
__flash_size = 0x1fff0000;
4
__ram = 0x80000000;
5
__ram_size = 0x4000;
6
__stack_size = 1k;
Auch hier ist kein Verweis auf die std-linker-Datei... Und wenn das mit 
x86 funktioniert... warum dann nicht mit riscv?

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


Lesenswert?

Hmm, OK, jetzt verstehe ich, was das "INSERT AFTER" da macht.

Aber sorry, damit habe ich auch keine Erfahrung.

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


Lesenswert?

Achso, wenn du -v zu den Compileroptionen hinzu fügst, zeigt er dir die 
kompletten Aufrufe der nachgeordneten Tools an.

von Sebastian K. (seplog)


Lesenswert?

1
$ riscv32-unknown-elf-gcc -Wl,-Map,"./build/main.map" -march=rv32imac -mabi=ilp32 -specs=picolibc.specs --oslib=semihost --crt0=hosted -Wl,-Tsifive-e31.ld  -flto -Wl,-Tmain.ld  -o "./build/main.elf" ./build/src/main.o -v
2
Es werden eingebaute Spezifikationen verwendet.
3
Lesen der Spezifikationen von picolibc.specs
4
Spezifikation wird von link nach picolibc_link umbenannt
5
Spezifikation wird von cpp nach picolibc_cpp umbenannt
6
Spezifikation wird von cc1 nach picolibc_cc1 umbenannt
7
Spezifikation wird von cc1plus nach picolibc_cc1plus umbenannt
8
COLLECT_GCC=/usr/bin/riscv32-unknown-elf-gcc
9
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/riscv32-unknown-elf/8.5.0/lto-wrapper
10
Ziel: riscv32-unknown-elf
11
Konfiguriert mit: /var/tmp/portage/cross-riscv32-unknown-elf/gcc-8.5.0-r1/work/gcc-8.5.0/configure --host=x86_64-pc-linux-gnu --target=riscv32-unknown-elf --build=x86_64-pc-linux-gnu --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/riscv32-unknown-elf/gcc-bin/8.5.0 --includedir=/usr/lib/gcc/riscv32-unknown-elf/8.5.0/include --datadir=/usr/share/gcc-data/riscv32-unknown-elf/8.5.0 --mandir=/usr/share/gcc-data/riscv32-unknown-elf/8.5.0/man --infodir=/usr/share/gcc-data/riscv32-unknown-elf/8.5.0/info --with-gxx-include-dir=/usr/lib/gcc/riscv32-unknown-elf/8.5.0/include/g++-v8 --with-python-dir=/share/gcc-data/riscv32-unknown-elf/8.5.0/python --enable-languages=c,c++ --enable-obsolete --enable-secureplt --disable-werror --with-system-zlib --enable-nls --without-included-gettext --disable-libunwind-exceptions --enable-checking=release --with-bugurl=https://bugs.gentoo.org/ --with-pkgversion='Gentoo 8.5.0-r1 p2' --disable-esp --enable-libstdcxx-time --enable-poison-system-directories --disable-libstdcxx-time --with-sysroot=/usr/riscv32-unknown-elf --disable-bootstrap --with-newlib --enable-multilib --disable-fixed-point --with-abi=ilp32d --disable-libgomp --disable-libssp --disable-libada --disable-libmpx --disable-systemtap --disable-vtable-verify --disable-libvtv --enable-lto --without-isl --disable-libsanitizer --disable-default-pie --enable-default-ssp
12
Thread-Modell: single
13
gcc-Version 8.5.0 (Gentoo 8.5.0-r1 p2) 
14
COMPILER_PATH=/usr/libexec/gcc/riscv32-unknown-elf/8.5.0/:/usr/libexec/gcc/riscv32-unknown-elf/8.5.0/:/usr/libexec/gcc/riscv32-unknown-elf/:/usr/lib/gcc/riscv32-unknown-elf/8.5.0/:/usr/lib/gcc/riscv32-unknown-elf/
15
LIBRARY_PATH=/usr/lib/gcc/riscv32-unknown-elf/8.5.0/rv32imac/ilp32/:/usr/lib/gcc/riscv32-unknown-elf/8.5.0/../../../../riscv32-unknown-elf/lib/rv32imac/ilp32/:/usr/riscv32-unknown-elf/lib/rv32imac/ilp32/:/usr/lib/gcc/riscv32-unknown-elf/8.5.0/:/usr/lib/gcc/riscv32-unknown-elf/8.5.0/../../../../riscv32-unknown-elf/lib/:/usr/riscv32-unknown-elf/lib/:/usr/riscv32-unknown-elf/usr/lib/
16
COLLECT_GCC_OPTIONS='-march=rv32imac' '-mabi=ilp32' '-specs=picolibc.specs' '--oslib=semihost' '--crt0=hosted' '-flto' '-o' './build/main.elf' '-v'
17
 /usr/libexec/gcc/riscv32-unknown-elf/8.5.0/collect2 -plugin /usr/libexec/gcc/riscv32-unknown-elf/8.5.0/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/riscv32-unknown-elf/8.5.0/lto-wrapper -plugin-opt=-fresolution=/tmp/ccqgGMbt.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lsemihost -plugin-opt=-pass-through=-lgcc -flto -L/usr/local/picolibc/riscv32-unknown-elf/lib/rv32imac/ilp32 -L/usr/local/picolibc/riscv32-unknown-elf/lib -Tpicolibc.ld --sysroot=/usr/riscv32-unknown-elf -melf32lriscv --gc-sections -o ./build/main.elf /usr/local/picolibc/riscv32-unknown-elf/lib/rv32imac/ilp32/crt0-hosted.o -L/usr/lib/gcc/riscv32-unknown-elf/8.5.0/rv32imac/ilp32 -L/usr/lib/gcc/riscv32-unknown-elf/8.5.0/../../../../riscv32-unknown-elf/lib/rv32imac/ilp32 -L/usr/riscv32-unknown-elf/lib/rv32imac/ilp32 -L/usr/lib/gcc/riscv32-unknown-elf/8.5.0 -L/usr/lib/gcc/riscv32-unknown-elf/8.5.0/../../../../riscv32-unknown-elf/lib -L/usr/riscv32-unknown-elf/lib -L/usr/riscv32-unknown-elf/usr/lib -Map ./build/main.map -Tsifive-e31.ld -Tmain.ld ./build/src/main.o -lgcc --start-group -lgcc -lc -lsemihost --end-group -lgcc
18
/usr/libexec/gcc/riscv32-unknown-elf/ld: .rodata not found for insert
19
collect2: Fehler: ld gab 1 als Ende-Status zurück

von Sebastian K. (seplog)


Lesenswert?

Sry. Wollte das nun nicht kommentarlos posten. Also die picolibc.ld ist 
dort als Linkerscript mit angegeben. Dann sollte ja auch die rodata 
vorhanden sein... Ich schau mir das noch einmal an wie das bei x86 
ausschaut...

von Sebastian K. (seplog)


Angehängte Dateien:

Lesenswert?

Hey,
Also ich hab ein paar neue Erkenntnisse, es läuft aber noch nicht so wie 
ich das will... ... Also der Fehler kommt immer noch, wenn ich das via 
INSERT AFTER mache.
Ich habe ja h´gesagt, bei x86 funktioniert das alles wenn ich die neue 
section hinter .rodata anhänge. Ich habe dann einmal geschaut nach der 
Compilerversion, der Binutils-Version und den Aufrufen. Dort konnte ich 
leider nichts finden.

Anschließend dachte ich mir ich versuche das einmal mit der AVR 
Toolchain. Auch dort bekam ich beim INSERT AFTER .rodata; den selben 
Fehler. Was aber funktioniert ist INSERT AFTER .data;.

Nun bin ich in LD-Scripte schreiben nun nicht so die Leuchte. Da muss 
ich mich erst einmal einlesen. Aber vielleicht hat ja hier jmd. ein 
guten Tipp, wie ich das vielleicht hin bekomme?

Ich denke wenn wir dort was hinbekommen werde ich auch bei der picolib 
ein PR aufmachen dazu. Denn dynamischer ist ja immer schöner ;)

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


Lesenswert?

http://sourceware.org/binutils/docs-2.21/ld/Miscellaneous-Commands.html#index-INSERT-377
1
INSERT [ AFTER | BEFORE ] output_section

Dein .rodata muss folglich eine output_section sein, damit das 
funktioniert.

Die output sections beim AVR sind aber nur text, data und eeprom.

von Sebastian K. (seplog)


Lesenswert?

Hallo,

Also so ganz verstehe ich das nicht. Generell werden Output-Sections 
doch in dem SECTIONS-Command definiert. Dort dann:
1
SECTIONS {
2
    .outputname : {
3
        .inputname
4
    }
5
}

Das würde heißen, dass .text in der picolibc ja eine output-section ist. 
Aber auch dort kann ich nicht das INSERT nutzen. Zum Ersten hätte ich 
dort vorgehabt das .text in .text und .data aufzutrennen. Aber jede 
Section, welche ich definiere wird von dem INSERT nicht erkannt.

Ich dachte schon, dass liegt an den PHDRS aber diese definieren ja nur 
die Header. Bei dem Linker-script vom AVR funktioniert das ja auch. 
Jedoch fällt mir dort bei vielen "ersten" Blicken kein bedeutender 
Unterschied auf... ...

Hat jemand dort eine Erklärung?
Danke und Viele Grüße

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


Lesenswert?

Sebastian K. schrieb:
> Das würde heißen, dass .text in der picolibc ja eine output-section ist.

Die heißt allerdings .text, nicht .rodata.

> das .text in .text und .data aufzutrennen

Vorsicht: .data wird sowohl im RAM als auch im Flash benötigt; letzteres 
sind die Initialwerte, die vom Startup-Code in den RAM kopiert werden.

von Sebastian K. (seplog)


Lesenswert?

Was mich zuerst einmal wundert ist wenn ich
1
INSERT AFTER .text
 eingebe auch der Fehler kommt, das die .text section nicht vorhanden 
ist. Diese sollte doch aber da sein. Laut dem linker-Script von der 
picolibc.

Oder verstehe ich dort etwas falsch?

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


Lesenswert?

Sebastian K. schrieb:
> Oder verstehe ich dort etwas falsch?

Sorry, ich habe mit diesem INSERT auch keine Ahnung.

Kannst noch Mapfiles vergleichen, aber da die relevanten Unterschiede zu 
finden hat was von Nadel im Heuhaufen.

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.