linkeroverlaygnumemory-addresslinker-scripts

GNU linker and linker script : Linker does not generate correct LMA


I have the following line in my linker script

JumpTable ABSOLUTE(0x2000000C): AT(eROData)
{
    JumpTableStart = .;
    *(.JumpSection);
    . = ALIGN(4);
    JumpTableEnd = .;
} > SRAM

eROData is an address from flash and assumes a value 0x1000xxxx

After linking, I notice that the linker assigns both VMA and LMA to the section JumpTable. This is the listing from the list file.

 2 .rodata       00000004  10001214  10001214  00001214  2**2

              CONTENTS, ALLOC, LOAD, READONLY, DATA

 3 JumpTable     00000140  2000000c  2000000c  00008954  2**2

              CONTENTS, READONLY

No such problems with the .data section.

Is this a known GNU linker problem?

EDIT: I noticed that if the section ".JumpSection" were defined in a C file, the LMA was correctly assigned.

I am facing this problem because the section is defined in an assembly file.

Have you faced this problem before?

EDIT - SOLUTION : It turns out that .JumpSection had to be defined with correct attributes: .section ".JumpSection","ax",%progbits

Only then would the linker behave correctly.


Solution

  • So here is what I found out. Perhaps this could save someone from hours of frustrating debugging.

    My main problem was that there was a piece of assembly code that needed to be linked into SRAM space and loaded from flash space. So the VMA had to be a SRAM address and LMA a flash address.

    In the past, I always succeeded in accomplishing above for functions/data defined in a c file. All I would need to do was assign a section attribute and modify the linker script appropriately.

    INFERENCE 1: The linker allows a different LMA for standard TEXT and DATA sections although they may be named differently using the section attribute.

    No such luck when the same was attempted in an assembly file. The linker refused to acknowledge that input section .JumpTable defined above was actually a user defined TEXT section.

    The solution was then

    1. To move the assembly code to a new file JumpTable.S.

    2. Rename the the input section .JumpTable to .text

    3. Modify the linker file as follows

       .text :
      
      {
      
      *(EXCLUDE_FILE(*JumpTable.o) .text); /* Exclude .text of JumpTable.o and place others */
      
      } > FLASH
      
      
      JumpTable ABSOLUTE(0x2000000C) : AT (eROData) /* Link to SRAM and Load after const data */
      
       {
      
         JumpTableStart = .;
      
         *JumpTable.o(.text); /* Place .text of JumpTable.o into JumpTable output section) */
      
         JumpTableEnd = .;
      
       } > SRAM
      

    Maybe there is a better explanation/another root cause. But this saved my day for sure.