Forum: Compiler & IDEs gcc-4.7 -lto -Os funktioniert nicht


von Heiko J. (heiko_j)


Lesenswert?

Hallo,

ich bin gerade dabei ein bisschen mit lto herumzuprobieren und bin dabei 
über ein Problemchen gestolpert. Mein Programm läuft nicht mehr. Es 
hüpft direkt in den HardFaultHandler. Ich hab mit dem Debugger im 
ResetHandler einen Breakpoint auf __asm__("ldr   sp, =__stack") gesetzt, 
der nie erreicht wird. Es scheint als würde die CPU den ResetHandler 
überhaupt nicht angucken. :-( Die nvic table und den ResetHandler hab 
ich mit _attribute_ ((used)) gespickt, wie in den diversen Dokus zu 
lto beschrieben. Der Eintrag für den ResetHandler in der NVIC table 
sieht eigentlich auch gut aus. Der Code liegt da wo er hin sollte. 
Irgendwas mach ich wohl falsch,  hab aber absolut keine Ahnung was, 
sobald ich aber -flto beim comile und link weg lasse läuft wieder alles. 
Keine Warnings beim compilieren und linken. Kein Anhaltspunkt.

Hat von euch jemand ne Idee an was es liegen könnte ?

Gruß Heiko


Compileroptionen:
arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 -Os -fno-builtin 
-ffunction-sections -fdata-sections -flto -c -DUSE_STDPERIPH_DRIVER 
-Iinclude -ILibraries/CMSIS/CM3/CoreSupport 
-ILibraries/STM32F10x_StdPeriph_Driver/inc -mthumb -mcpu=cortex-m3 -Os 
-fno-builtin -ffunction-sections -fdata-sections -flto -MMD -MP -MF

Linkeroptionen (Linken über gcc-frontend):
arm-none-eabi-gcc -Os -Tsrc/stm32f107vct6_flash.ld -nostartfiles 
-Wl,--gc-sections -v -mcpu=cortex-m3 -mthumb -specs=nano.specs 
-specs=rdimon.specs -lc -lnosys -lc -u _printf_float -flto


Toolchain: gcc-arm-none-eabi-4_7-2013q2 (Launchpad)
CPU: stm32F107vct6
1
Disassembly of section .text:
2
3
08000000 <nvic_boot_vector>:
4
 8000000:       00 00 01 20 6d 03 00 08 03 02 00 08 01 02 00 08
5
6
...
7
8
0800036c <stm32f10xCL_Reset_Handler>:
9
 800036c:       b500            push    {lr}
10
 800036e:       b08b            sub     sp, #44 ; 0x2c
11
 8000370:       f8df d54c       ldr.w   sp, [pc, #1356] ; 80008c0 <_close+0x6>
12
...
1
 
2
__attribute__ ((externally_visible,used)) void stm32f10xCL_Reset_Handler(void) {
3
4
    // Adjust sp       
5
    __asm__("ldr   sp, =__stack");
6
7
    unsigned int * ptrDst;
8
    unsigned int * ptrSrc;
9
10
#ifdef DEBUG_IN_RAM        
11
    /* run in ram shit that makes me insane ....*/
12
    unsigned int * vtor = (unsigned int *) VTOR;
13
    *vtor = (unsigned int) &__start_bootnvic_vector;
14
#else
15
    /* Copy data section from flash to RAM */
16
    ptrSrc = &__start_cpy_src;
17
    ptrDst = &__start_cpy_dst;
18
    while (ptrDst < &__end_cpy_dst) {
19
        *ptrDst++ = *ptrSrc++;
20
    }
21
#endif
22
23
    /* Clear the bss section */
24
    ptrDst = &__bss_start__;
25
    while (ptrDst < &__bss_end__) {
26
        *ptrDst++ = 0;
27
    }
28
29
    // Go and launch main
30
    main();
31
32
    // We'll hopefully never ever get here
33
    while (1) {
34
    }
35
}

von (prx) A. K. (prx)


Lesenswert?

Es ist bei diversen ARMs nicht trivial, direkt ab Reset zu debuggen. Der 
Reset löst da nämlich die Verbindung zum Debugger, und bis der die CPU 
wieder eingefangen hat, ist dein LDR schon durch.

Wer sicher gehen will, der legt direkt hinter an den Anfang vom 
Reset-Code eine deutliche Zeitschleife.

von Heiko J. (heiko_j)


Lesenswert?

Also ich hab jetzt direkt hinter das Stackpointer verbiegen
eine Schleife gelegt, die eine weile laufen müsste. Ohne LTO lande ich 
am Breakpoint hinter der Schleife. Mit LTO lande ich direkt wieder im 
HardFault. Irgendwas ist echt oberfaul mit lto.

Debug compilerflags:
-mthumb -mcpu=cortex-m3 -Os -fno-builtin -ffunction-sections 
-fdata-sections -flto   -c -g -DUSE_STDPERIPH_DRIVER -Iinclude 
-ILibraries/CMSIS/CM3/CoreSupport 
-ILibraries/STM32F10x_StdPeriph_Driver/inc -mthumb -mcpu=cortex-m3 -Os 
-fno-builtin -ffunction-sections -fdata-sections -flto -MMD -MP -MF


Debug linkerflags:
-Os -Tsrc/stm32f107vct6_flash.ld -nostartfiles -Wl,--gc-sections -v 
-mcpu=cortex-m3 -mthumb -specs=nano.specs -specs=rdimon.specs -lc 
-lnosys -lc -u _printf_float -flto


1
      // Adjust sp       
2
    __asm__("ldr   sp, =__stack");
3
4
    unsigned int * ptrDst;
5
    unsigned int * ptrSrc;
6
    
7
    register uint32_t foo = 0;
8
    for (foo=0;foo < UINT32_MAX;foo++ ) {
9
        __asm__("nop");
10
    };

von Heiko J. (heiko_j)


Lesenswert?

Kleine Ergänzung:

Packe ich die Schleife ganz an den Anfang des reset handler verhält es 
sich ganz genau gleich. Ohne LTO lande ich im Break, mit LTO im 
HardFault.

von Heiko J. (heiko_j)


Lesenswert?

Sodele, bin jetz ein bisschen weiter gekommen mit dem Problem.

Mit LTO landet die komplette main im ResetHandler. Dadurch kommt LTO 
scheinbar mit dem verbiegen des Stackpointers im Startupcode des 
Resethandlers durcheinander.

_attribute_ ((externally_visible,used)) an die main ranklatschen hilft 
:-)

Jetzt funktioniert alles. Sogar mit LTO

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.