[llvm-bugs] [Bug 51481] New: Wrong offsets calculation when compiling embedded arm read/write pic code (-frwpi)

via llvm-bugs llvm-bugs at lists.llvm.org
Sun Aug 15 01:00:05 PDT 2021


https://bugs.llvm.org/show_bug.cgi?id=51481

            Bug ID: 51481
           Summary: Wrong offsets calculation when compiling embedded arm
                    read/write pic code (-frwpi)
           Product: lld
           Version: unspecified
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: ELF
          Assignee: unassignedbugs at nondot.org
          Reporter: davidstdio at gmail.com
                CC: llvm-bugs at lists.llvm.org, smithp352 at googlemail.com

I'm compiling with -frwpi flag (for STM32L486 mcu), which generates static base
relative read-write data access. By default, lld generated for me separate
segments for .data and .bss sections. So offsets in .data section were
calculated relatively to ".data" segment base, and offsets in .bss section were
calculated relatively to .bss segment base. 

 Section to Segment mapping:
   ...

   04     .data
   05     .bss ._user_heap_stack

So for example for following function 

    uint32_t uwTick;
    uint32_t uwTickFreq = 1U;  /* 1KHz */

    void HAL_IncTick(void)
    {
         uwTick += (uint32_t)uwTickFreq;
    }

Following assembly was generated:

0800a1ee <HAL_IncTick>:
 800a1ee: 40 f2 20 00   movw    r0, #0x20
 800a1f2: c0 f2 00 00   movt    r0, #0x0
 800a1f6: 49 46         mov     r1, r9
 800a1f8: 0b 58         ldr     r3, [r1, r0]
 800a1fa: 45 f6 c8 62   movw    r2, #0x5ec8
 800a1fe: c0 f2 00 02   movt    r2, #0x0
 800a202: 88 58         ldr     r0, [r1, r2]
 800a204: 18 44         add     r0, r3
 800a206: 88 50         str     r0, [r1, r2]
 800a208: 70 47         bx      lr

Where #20 is the correct offset of uwTickFreq inside the .data segment  :

   Disassembly of section .data:

   20000000 <_sdata>:
   ....
   20000020 <uwTickFreq>:

and #5ec8 is the correct offset of uwTick inside the .bss segment  :

    Disassembly of section .bss:

    20000458 <completed.1>:
    ....
    20006320 <uwTick>:

But they both accessed with the same base which can be either 0x20000000 or
0x20000458. 

The workaround I used was to add PHDRS command in my linker script with custom
rwdata segment and put there .data and .bss sections. 
--------

This is the default behavior in gcc by the way. Same code compiled and linked
with gcc before I used PHDRS gave following placement :

     Section to Segment mapping:
      Segment Sections...
       00     isr_vector .text .rodata .ARM .init_array .fini_array
       01     .data .bss

Thanks.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210815/c58fae73/attachment-0001.html>


More information about the llvm-bugs mailing list