rustlinkerllvmzephyr-rtos

Is it possible to relocate MergedGlobals to specific bss/data regions?


I am using the MPU to grant access to specific regions of memory. (Target is a microcontroller + zephyr-rtos, rust compiled as a static lib). The app crashes with an MPU Fault. I have traced the memory it tries to access to globals put into merged memory regions which are outside of the memory granted access to. See the following snippet from the map file:

.bss..L_MergedGlobals.510
                0x0000000020425038       0x60 /home/marius/...
...
.data..L_MergedGlobals
                0x0000000020456d54        0x8 /home/marius/...
 

I could not find much information about these merged globals, only a small mention of it in the llvm docs

Global variables can be marked with unnamed_addr which indicates that the address is not significant, only the content. Constants marked like this can be merged with other constants if they have the same initializer. Note that a constant with significant address can be merged with a unnamed_addr constant, the result being a constant whose address is significant.

However the address is significant in my case.

So my questions are:

  1. In the code I wrote myself I can instruct the linker to put values in a specific region
    #[link_section=stringify!(some_region)]
    However, code I did not write myself I do not have control over this in the same way, is there a way to tell rustc/llvm to put all these merged values into a specific named region so that I can grant access to the thread to the named region?

  2. How do I find out where these merged globals are located in the rust code? I suspect they are from some external library, maybe even the core library.

Thanks!


Solution

  • Found out what was going on here.

    I looked the the rust disassembly and saw a bunch of lines like this:

    ...$core..ops..deref..Deref$GT$5deref11__stability4LAZY..., .L_MergedGlobals+16
    

    So I looked at places where I was de referencing things. Turns out that the object I was trying to access was within an accessible region but the reference to that object was also a global and access to it was not granted. The reference was a &'static reference. After changing the code so that the refrence was not static, the MergedGlobals disappeared.

    Seems like &'static references are flagged as as unnamed_addr by the compiler, hence them being in a MergedGlobals region