Linker failure with static allocation, overflow of bss?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Panometric
Level 5
Level 5
100 sign-ins 100 replies posted 10 solutions authored

I have a posc6 cm4 app that when I allocate just a few hundred more bytes of static variables, the linker fails. 

The error is:

COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xx7_cm4_dual.ld:318 cannot move location counter backwards (from 08046878 to 08046800)
collect2.exe: error: ld returned 1 exit status

Ironically, the PROGBITS feature doesn't run if the linker fails, so you can't see unless you go back to the smaller size. When  you do it prints:

| .data | 0x0800228c | 7820 |
| PROGBITS | 0x08004118 | 1 |
| .cy_sharedmem | 0x0800411c | 12 |
| .noinit | 0x08004128 | 15572 |
| .bss | 0x08007e00 | 255208 |
| .heap | 0x080462e8 | 1304 |
| .cy_app_signature | 0x100fff00 | 4 |

The variable I am trying to grow in an uninitialized struct with an member array, so it should be in the .bss section which is huge, so I suspect that general understanding is wrong.  I can't figure out why the linker is failing or how to change it.   All the advice on this forum does not appear relevant for Modus Toolbox 2. 4

I am using the DFU linker script (dfu_cm4_app1.ld) from the BLE DFU example. 

Please suggest where to look and what to change. 

0 Likes
1 Solution
Panometric
Level 5
Level 5
100 sign-ins 100 replies posted 10 solutions authored

Alen,

Thanks for the clues. Yes in fact the problem was a lack of RAM, but not because of sloppy programming per se except that almost all my RAM was being allocated by FreeRTOS because of the settings:

#define configHEAP_ALLOCATION_SCHEME (HEAP_ALLOCATION_TYPE4)

#define configTOTAL_HEAP_SIZE 229632

So I really did not have lots of ram available. It was all being preemptively allocated. 

For anyone struggling with memory usage, this tool is invaluable: Open Source MapViewer for Windows 

You are right that it was not using the linker file I provided,  if you look closely at the makefile, that file is used in the release build, but for debug version that I was compiling, we chose to use the default BSP linker file for a single app to ease debuggability.  I'm sorry for adding to the mystery there. 

In the file actually used ram is defined as:

ram (rwx) : ORIGIN = 0x08002000, LENGTH = 0x45800

Which makes sense for the CYBLE-416045 288K if you subtract the stack. 

Issue closed. 

 

View solution in original post

7 Replies
AlenAn14
Moderator
Moderator
Moderator
500 replies posted 100 solutions authored 250 replies posted

Hi @Panometric ,

Can you please elaborate more on this "The variable I am trying to grow in an uninitialized struct with an member array" as in, can you please share the code snippet that you are running that is responsible for causing the linker to fail?

Warm Regards
Alen

0 Likes
Panometric
Level 5
Level 5
100 sign-ins 100 replies posted 10 solutions authored

It's just a global static struct:

Here is the psuedo code for it, when i increase PACKAGES_NUM to 6 the linker fails.  This should only be about  154 bytes more. 

#define PACKAGES_NUM 5

struct raw_config {
    uint8_t state; 
    uint8_t state2; 
    volatile struct data_struct {
        uint8_t count;
        uint8_t countb;
        uint8_t data[146]; 
    } data[PACKAGES_NUM];
    volatile uint32_t sizes[PACKAGES_NUM];
    uint8_t state7;
};

 

 

 

0 Likes
AlenAn14
Moderator
Moderator
Moderator
500 replies posted 100 solutions authored 250 replies posted

Hi @Panometric ,

Can you please let me know if you made any modification in the linker script (dfu_cm4_app1.ld) of the CM4 component?

Also, do let me know where you have declared the above mentioned structure as well.

Warm Regards
Alen

0 Likes
lock attach
Attachments are accessible only for community members.

Here is my make and link file. The declaration is in one our C files that is referenced as a library in mtb_shared. For all of our vendor provided libraries, we created git repos and bring them in using make getlibs. 

 

0 Likes
AlenAn14
Moderator
Moderator
Moderator
500 replies posted 100 solutions authored 250 replies posted

Hi @Panometric ,

I analyzed this and was able to reproduce the issue on my end.

The cause is the fact that you are running out of RAM when you increase the value of PACKAGE_NUM.

So basically when you increase the structure size, the .bss section increases which pushes down the start address of .heap section. And when the start address of .heap section exceeds the allowed RAM size, the below mentioned error appears:
COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xx7_cm4_dual.ld:318 cannot move location counter backwards (from 08046878 to 08046800)

Now an irregularity here is that when I checked the linker script that you shared above, the ram assignment in the same is as shown below.

AlenAn14_1-1660194475815.png

As per the linker script you have shared, the total allowed RAM size is 0x8002400 + 0x8000 = 0x800A400
hence your error should have mentioned the address value 0x8009400  (the ending 0x1000 bytes of RAM is used for stack and when overflow of .heap start address into stack happens, the location counter error is triggered).
I tried putting the structure sudo code in a DFU code example and got the below error:

gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe:./linker_script/TARGET_CY8CKIT-062-BLE/TOOLCHAIN_GCC_ARM/dfu_cm4_app0.ld:362 cannot move location counter backwards (from 080440d8 to 08009400)


But instead of this, the address 0x8046800  is mentioned in your error.

Hence I believe , your code is not using the linker script you shared with me here because the path to the same has not been mentioned in the MakeFile you shared with me. Instead it only mentions the name of the linker file as shown below.

AlenAn14_2-1660195493723.png

Please edit this and put in the complete path (similar to what is shown below )for the same to reflect.

AlenAn14_3-1660197460493.png

Warm Regards
Alen

0 Likes
Panometric
Level 5
Level 5
100 sign-ins 100 replies posted 10 solutions authored

Alen,

Thanks for the clues. Yes in fact the problem was a lack of RAM, but not because of sloppy programming per se except that almost all my RAM was being allocated by FreeRTOS because of the settings:

#define configHEAP_ALLOCATION_SCHEME (HEAP_ALLOCATION_TYPE4)

#define configTOTAL_HEAP_SIZE 229632

So I really did not have lots of ram available. It was all being preemptively allocated. 

For anyone struggling with memory usage, this tool is invaluable: Open Source MapViewer for Windows 

You are right that it was not using the linker file I provided,  if you look closely at the makefile, that file is used in the release build, but for debug version that I was compiling, we chose to use the default BSP linker file for a single app to ease debuggability.  I'm sorry for adding to the mystery there. 

In the file actually used ram is defined as:

ram (rwx) : ORIGIN = 0x08002000, LENGTH = 0x45800

Which makes sense for the CYBLE-416045 288K if you subtract the stack. 

Issue closed. 

 

AlenAn14
Moderator
Moderator
Moderator
500 replies posted 100 solutions authored 250 replies posted

Hi @Panometric ,

Glad your query is resolved!
Please feel free to post any queries or issues you may have on Infineon products in the community and we will be happy to help.

Warm Regards
Alen

 

0 Likes