Author Topic: arm cortex-m0 elf file issue  (Read 601 times)

0 Members and 1 Guest are viewing this topic.

Offline trampasTopic starter

  • Regular Contributor
  • *
  • Posts: 52
  • Country: us
arm cortex-m0 elf file issue
« on: December 26, 2024, 09:53:58 pm »
I noticed when I compiler my code with arm-none-eabi-gcc version 10.3.1  I am able to run and step through the code correctly.   However if I use any version of the compiler newer segger ozone and vscode (cortex-debug) thinks the code comes from the wrong source file.  The binary of the code is correct but it thinks code came from a different source file.

I have fought this for a several days now and found that if I take the elf file that does not work and run `objdump -dlr` on it then the output is corrupt.  Specifically the none working elf  file produces:

```

build/debug/lora.elf:     file format elf32-littlearm


Disassembly of section .text:

00000000 <exception_table>:
getStackSize():
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:244
   0:   ff 7f 00 20 95 04 00 00 61 05 00 00 a5 05 00 00     ... ....a.......
   ...
getStackUsed():
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:254
  2c:   61 05 00 00 00 00 00 00 00 00 00 00 61 05 00 00     a...........a...
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:257
  3c:   a5 08 00 00 61 05 00 00 b1 0b 00 00 6d 06 00 00     ....a.......m...
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:250
  4c:   61 05 00 00 61 05 00 00 61 05 00 00 61 05 00 00     a...a...a...a...
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:267
  5c:   61 05 00 00 79 07 00 00 9d 07 00 00 c1 07 00 00     a...y...........
  6c:   e5 07 00 00 09 08 00 00 2d 08 00 00 61 05 00 00     ........-...a...
_ZN10I2C_MASTER4syncEv():
D:\Projects\SECA\LoRa\firmware/src/drivers/i2c_master/i2c_master.cpp:90
  7c:   61 05 00 00 61 05 00 00 c9 09 00 00 09 0a 00 00     a...a...........
_sfixed():
D:\Projects\SECA\LoRa\firmware/src/drivers/i2c_master/i2c_master.cpp:90
  8c:   49 0a 00 00 89 0a 00 00 c9 0a 00 00 61 05 00 00     I...........a...
D:\Projects\SECA\LoRa\firmware/src/drivers/i2c_master/i2c_master.cpp:91
  9c:   61 05 00 00 61 05 00 00 61 05 00 00 61 05 00 00     a...a...a...a...
_ZN10I2C_MASTER9read_byteEPh():
D:\Projects\SECA\LoRa\firmware/src/drivers/i2c_master/i2c_master.cpp:93
  ac:   61 05 00 00 00 00 00 00                             a.......
```

Where the working elf file produces:
```

build/debug/lora.elf:     file format elf32-littlearm


Disassembly of section .text:

00000000 <exception_table>:
_sfixed():
   0:   ff 7f 00 20 45 04 00 00 0d 05 00 00 4d 05 00 00     ... E.......M...
   ...
  2c:   0d 05 00 00 00 00 00 00 00 00 00 00 0d 05 00 00     ................
  3c:   55 08 00 00 0d 05 00 00 75 0b 00 00 09 06 00 00     U.......u.......
  4c:   0d 05 00 00 0d 05 00 00 0d 05 00 00 0d 05 00 00     ................
  5c:   0d 05 00 00 29 07 00 00 4d 07 00 00 71 07 00 00     ....)...M...q...
  6c:   95 07 00 00 b9 07 00 00 dd 07 00 00 0d 05 00 00     ................
  7c:   0d 05 00 00 0d 05 00 00 79 09 00 00 b9 09 00 00     ........y.......
  8c:   f9 09 00 00 39 0a 00 00 79 0a 00 00 0d 05 00 00     ....9...y.......
  9c:   0d 05 00 00 0d 05 00 00 0d 05 00 00 0d 05 00 00     ................
  ac:   0d 05 00 00 00 00 00 00                             ........
```

Note that the getStackSize(): function referenced in the first output does not exist in the binary, that is the function was never called and it was removed using `-ffunction-sections -fdata-sections ` and `-Wl,--gc-sections`. 

I figure since 10.3.1 version of compiler is 3 years old, that I am doing something wrong in my build process.  That is I assume it is more likely a problem I have than a problem with gcc, like maybe I need a new compiler/linker option to clean up elf file correctly?

Thanks
 

Offline trampasTopic starter

  • Regular Contributor
  • *
  • Posts: 52
  • Country: us
Re: arm cortex-m0 elf file issue
« Reply #1 on: December 27, 2024, 12:26:19 am »
From what I have been able to determine, with GCC 11 and later the unused functions (unused symbols in elf) are being mapped to address zero.  That is gdb and objdump thinks all the unused functions are linked in at address zero and then seemly random picks out which function to show as source (maybe based on link order?).   The net result is that when debugging with gdb based debugger the debugger can not resolve the true source file for the code, and will randomly pick which line of which random function it will show you during debug.

I will keep you posted with any updates. 
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11853
  • Country: us
    • Personal site
Re: arm cortex-m0 elf file issue
« Reply #2 on: December 27, 2024, 12:28:42 am »
GCC at some point switched to DWARF version 5, which may affect how tools understand debug information. So, this would be the first thing I check. And I think there is an option to force older versions.

Although I don't know if it will be messed up to that extent.
Alex
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11853
  • Country: us
    • Personal site
Re: arm cortex-m0 elf file issue
« Reply #3 on: December 27, 2024, 12:30:31 am »
From what I have been able to determine, with GCC 11 and later the unused functions (unused symbols in elf) are being mapped to address zero.
This would be really strange. But also, if you collect unused functions, then they would not be in the binary anyway.
Alex
 

Offline trampasTopic starter

  • Regular Contributor
  • *
  • Posts: 52
  • Country: us
Re: arm cortex-m0 elf file issue
« Reply #4 on: December 27, 2024, 01:09:25 am »
The did switch to dwarf 5 at the same time, I tried setting the system dwarf 4 and it had no change in results.

The unused functions are not in the binary, but then gdb appears to think they exist in the binary and places them all at address 0x00.  As such as I step through my code it will randomly jump to the incorrect source file into a random line of code.   The binary is correct and runs, but trying to step through code it goes off into random places.

As shown below in the objdump the getStackSize() function is not in the binary, but objdump thinks it exists at address 0x000 and shows it in the dump.

build/debug/lora.elf:     file format elf32-littlearm


Disassembly of section .text:

00000000 <exception_table>:
getStackSize():
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:244
   0:   ff 7f 00 20 95 04 00 00 61 05 00 00 a5 05 00 00     ... ....a.......
   ...
getStackUsed():
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:254
  2c:   61 05 00 00 00 00 00 00 00 00 00 00 61 05 00 00     a...........a...
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:257
  3c:   a5 08 00 00 61 05 00 00 b1 0b 00 00 6d 06 00 00     ....a.......m...
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:250
  4c:   61 05 00 00 61 05 00 00 61 05 00 00 61 05 00 00     a...a...a...a...
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15716
  • Country: fr
Re: arm cortex-m0 elf file issue
« Reply #5 on: December 27, 2024, 01:20:27 am »
So, are you seeing that your linked ELF files contain code that should have been pruned by the linker to begin with?
 

Offline trampasTopic starter

  • Regular Contributor
  • *
  • Posts: 52
  • Country: us
Re: arm cortex-m0 elf file issue
« Reply #6 on: December 27, 2024, 01:27:42 am »
The elf file binary is correct.  However it think some of the code is from random source files where the code is removed.


For example the configure_clocks function is in startup_wlr089.c  file.  However the objdump and gdb thinks the code come from sercom.cpp, see below

0000016c <configure_clocks>:
D:\Projects\SECA\LoRa\firmware/src/drivers/sercom/sercom.cpp:101
 16c:   b500         push   {lr}
 16e:   4b98         ldr   r3, [pc, #608]   ; (3d0 <HEAP_SIZE+0x1d0>)
 170:   2280         movs   r2, #128   ; 0x80
D:\Projects\SECA\LoRa\firmware/src/drivers/sercom/sercom.cpp:105
 172:   0052         lsls   r2, r2, #1
 174:   609a         str   r2, [r3, #8]
D:\Projects\SECA\LoRa\firmware/src/drivers/sercom/sercom.cpp:106
 176:   4b97         ldr   r3, [pc, #604]   ; (3d4 <HEAP_SIZE+0x1d4>)
 178:   3afd         subs   r2, #253   ; 0xfd
D:\Projects\SECA\LoRa\firmware/src/drivers/sercom/sercom.cpp:107
 17a:   609a         str   r2, [r3, #8]
 17c:   4a96         ldr   r2, [pc, #600]   ; (3d8 <HEAP_SIZE+0x1d8>)
D:\Projects\SECA\LoRa\firmware/src/drivers/sercom/sercom.cpp:108

The reason is that all the functions in sercom.cpp are not used as such they have been removed from binary.  Objdump and gdb then assumes every function in sercom.cpp is actually placed in memory at 0x000.  Since the configure_clocks() function is placed in memory at 0x16C gdb and objdump picked that the configure_clocks() function must be one of the functions in sercom.cpp.  So as you step through the configure_clocks() code the debugger is showing random source files from sercom.cpp. 
 

Offline trampasTopic starter

  • Regular Contributor
  • *
  • Posts: 52
  • Country: us
Re: arm cortex-m0 elf file issue
« Reply #7 on: December 27, 2024, 01:31:56 am »
Now if change my compiler toolchain to 10.3.1-2.2.1 and rebuild the same code, same make file, etc.  Then gdb and objdump are correct. 
NOTE the code is different because it is using a different version of compiler, as such binary is different.

configure_clocks():
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:321
 154:   4a8d         ldr   r2, [pc, #564]   ; (38c <HEAP_SIZE+0x18c>)
 156:   6953         ldr   r3, [r2, #20]
 158:   2440         movs   r4, #64   ; 0x40
 15a:   4323         orrs   r3, r4
 15c:   6153         str   r3, [r2, #20]
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:323
 15e:   4b8c         ldr   r3, [pc, #560]   ; (390 <HEAP_SIZE+0x190>)
 160:   2200         movs   r2, #0
 162:   615a         str   r2, [r3, #20]
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:324
 164:   6959         ldr   r1, [r3, #20]
 166:   488b         ldr   r0, [pc, #556]   ; (394 <HEAP_SIZE+0x194>)
 168:   4008         ands   r0, r1
 16a:   2180         movs   r1, #128   ; 0x80
 16c:   00c9         lsls   r1, r1, #3
 16e:   4301         orrs   r1, r0
 

Offline trampasTopic starter

  • Regular Contributor
  • *
  • Posts: 52
  • Country: us
Re: arm cortex-m0 elf file issue
« Reply #8 on: December 27, 2024, 02:00:01 am »
Here is another example with 11.2.1-1.1.1.  When I compile with -O0 it seems to get the configure_clocks() function has correct source file:

00000198 <configure_clocks>:
configure_clocks():
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:306
 198:   b580         push   {r7, lr}
 19a:   b082         sub   sp, #8
 19c:   af00         add   r7, sp, #0
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:311
 19e:   4bb1         ldr   r3, [pc, #708]   ; (464 <STACK_SIZE+0x64>)
 1a0:   2280         movs   r2, #128   ; 0x80
 1a2:   0052         lsls   r2, r2, #1
 1a4:   609a         str   r2, [r3, #8]
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:312
 1a6:   4bb0         ldr   r3, [pc, #704]   ; (468 <STACK_SIZE+0x68>)
 1a8:   2203         movs   r2, #3
 1aa:   609a         str   r2, [r3, #8]
D:\Projects\SECA\LoRa\firmware/src/CMSIS/wlr089/source/gcc/startup_wlr089.c:315
 1ac:   4baf         ldr   r3, [pc, #700]   ; (46c <STACK_SIZE+0x6c>)
 1ae:   685a         ldr   r2, [r3, #4]
 1b0:   4bae         ldr   r3, [pc, #696]   ; (46c <STACK_SIZE+0x6c>)
 1b2:   2104         movs   r1, #4
 1b4:   430a         orrs   r2, r1
 1b6:   605a         str   r2, [r3, #4]

with compile option of -O1:

0000016c <configure_clocks>:
D:\Projects\SECA\LoRa\firmware/src/drivers/sercom/sercom.cpp:102
 16c:   b500         push   {lr}
 16e:   4b98         ldr   r3, [pc, #608]   ; (3d0 <HEAP_SIZE+0x1d0>)
 170:   2280         movs   r2, #128   ; 0x80
D:\Projects\SECA\LoRa\firmware/src/drivers/sercom/sercom.cpp:106
 172:   0052         lsls   r2, r2, #1
 174:   609a         str   r2, [r3, #8]
D:\Projects\SECA\LoRa\firmware/src/drivers/sercom/sercom.cpp:107
 176:   4b97         ldr   r3, [pc, #604]   ; (3d4 <HEAP_SIZE+0x1d4>)
 178:   3afd         subs   r2, #253   ; 0xfd
D:\Projects\SECA\LoRa\firmware/src/drivers/sercom/sercom.cpp:108
 17a:   609a         str   r2, [r3, #8]
 17c:   4a96         ldr   r2, [pc, #600]   ; (3d8 <HEAP_SIZE+0x1d8>)
D:\Projects\SECA\LoRa\firmware/src/drivers/sercom/sercom.cpp:109
 17e:   6853         ldr   r3, [r2, #4]
 180:   2104         movs   r1, #4
 182:   430b         orrs   r3, r1
D:\Projects\SECA\LoRa\firmware/src/drivers/sercom/sercom.cpp:113
 184:   6053         str   r3, [r2, #4]
 186:   2380         movs   r3, #128   ; 0x80
D:\Projects\SECA\LoRa\firmware/src/drivers/sercom/sercom.cpp:114
 188:   05db         lsls   r3, r3, #23
 18a:   789b         ldrb   r3, [r3, #2]

 

Offline xvr

  • Frequent Contributor
  • **
  • Posts: 542
  • Country: ie
    • LinkedIn
Re: arm cortex-m0 elf file issue
« Reply #9 on: December 27, 2024, 01:20:52 pm »
May be you turn on LTO optimization in compilation process? It looks like that some functions was cross inlined from one file into another.
 

Offline trampasTopic starter

  • Regular Contributor
  • *
  • Posts: 52
  • Country: us
Re: arm cortex-m0 elf file issue
« Reply #10 on: December 27, 2024, 01:40:04 pm »
I tried with -flto and every other option I could think of.   It appears this is a 'bug' in GCC 11 and later. 

Note I worked on this issue for several days, because the odds of finding a bug in GCC after almost 3 years that no one else found is low.  However I suspect that few have large amounts of functions being removed with the '-ffunction-sections -fdata-sections -Wl,--gc-sections'  who are also trying to step through code close to address zero. 

I did noticed that GCC 11 switched to DWARF 5, so I tried option to generate DWARF 4 but the elf had the same result.  I also noticed a lot of work was done in GCC 11 for link time optimizations (LTO),  however again nothing I could change with command line options.

Again it only is a problem when you are using gdb to debug code, the binary is fine.  As such I suspect many might have seen strange results and assumed it was an issue for them and never root caused to figure out the problem.  Also many developers try to remove unused functions from source code, again reducing the chances of finding the problem.   

On a more interesting note, my google foo is not great as there is almost no terms I could search to help aid in this problem without finding other issues.  For example 'gdb unused functions' talks about how find unused functions.  Also equally as interesting is that there are few people, and hard to reach them, that would be able to duplicate the issue and help you resolve it.  That is most embedded developers never get detailed in how the tools work, and the few that do are hard to come by. 

Finally there is the question about how do you duplicate this issue.  That is I assume my objdump outputs being messed up is also why gdb is messed up.  However if I have to create an example with gdb that shows error it is hard to do when you use gdb with hardware in the loop.   So it has been an interesting learning experience. 

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf