-
Notifications
You must be signed in to change notification settings - Fork 119
Description
I have the following in my platformio.ini:
[env:adafruit_circuitplayground_m0]
platform = atmelsam
board = adafruit_circuitplayground_m0
framework = arduino
Unfortunately this results in a segmentation fault (error -11 is a segmentation fault):
$ pio run -j1 -v
Processing adafruit_circuitplayground_m0 (platform: atmelsam; board: adafruit_circuitplayground_m0; framework: arduino)
---------------------------------------------------------------------------------------------------------------
CONFIGURATION: https://docs.platformio.org/page/boards/atmelsam/adafruit_circuitplayground_m0.html
PLATFORM: Atmel SAM (8.2.1) > Adafruit Circuit Playground Express
HARDWARE: SAMD21G18A 48MHz, 32KB RAM, 256KB Flash
DEBUG: Current (atmel-ice) External (atmel-ice, blackmagic, jlink)
PACKAGES:
- framework-arduino-samd-adafruit @ 1.7.13
- framework-cmsis @ 2.50400.181126 (5.4.0)
- framework-cmsis-atmel @ 1.2.2
- toolchain-gccarmnoneeabi @ 1.90301.200702 (9.3.1)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 11 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
arm-none-eabi-g++ -o .pio/build/adafruit_circuitplayground_m0/src/main.cpp.o -c -fno-rtti -fno-exceptions -std=gnu++11 -fno-threadsafe-statics -mcpu=cortex-m0plus -mthumb -Os -ffunction-sections -fdata-sections -Wall -nostdlib --param max-inline-insns-single=500 -Wno-expansion-to-defined -DPLATFORMIO=60114 -D__SAMD21G18A__ -DCRYSTALLESS -DARM_MATH_CM0PLUS -DARDUINO_SAMD_ZERO -DADAFRUIT_CIRCUITPLAYGROUND_M0 -DARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS -DARDUINO=10805 -DF_CPU=48000000L -DUSBCON -DUSB_VID=0x239A -DUSB_PID=0x8018 "-DUSB_PRODUCT=\"Circuit Playground Expresso\"" -DUSB_MANUFACTURER=\"Adafruit\" -DARDUINO_ARCH_SAMD -DUSB_CONFIG_POWER=100 -DARDUINO_SAMD_ADAFRUIT -Iinclude -Isrc -I/home/ayke/.platformio/packages/framework-cmsis/CMSIS/Core/Include -I/home/ayke/.platformio/packages/framework-cmsis-atmel/CMSIS/Device/ATMEL -I/home/ayke/.platformio/packages/framework-arduino-samd-adafruit/cores/arduino -I/home/ayke/.platformio/packages/framework-arduino-samd-adafruit/libraries/Adafruit_TinyUSB_Arduino/src/arduino -I/home/ayke/.platformio/packages/framework-cmsis/CMSIS/DSP/Include -I/home/ayke/.platformio/packages/framework-arduino-samd-adafruit/variants/circuitplay src/main.cpp
*** [.pio/build/adafruit_circuitplayground_m0/src/main.cpp.o] Error -11
========================================= [FAILED] Took 0.49 seconds =========================================
Testing the compiler manually makes it more clear:
$ ~/.platformio/packages/toolchain-gccarmnoneeabi/bin/arm-none-eabi-g++ --version
fish: Job 1, '~/.platformio/packages/toolchai…' terminated by signal SIGSEGV (Address boundary error)
I tracked it down to a page alignment issue in the binary. When I read the program headers, I get the following:
$ readelf --program-headers ~/.platformio/packages/toolchain-gccarmnoneeabi/bin/arm-none-eabi-g++
Elf file type is EXEC (Executable file)
Entry point 0x402c80
There are 11 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x00000000003ff040 0x00000000003ff040 0x000268 0x000268 R 0x8
GNU_STACK 0x001000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10
LOAD 0x000000 0x00000000003ff000 0x00000000003ff000 0x001000 0x001000 RW 0x1000
DYNAMIC 0x0002a8 0x00000000003ff2a8 0x00000000003ff2a8 0x000200 0x000200 RW 0x8
LOAD 0x001000 0x0000000000400000 0x0000000000400000 0x0ca4e4 0x0ca4e4 R E 0x1000
NOTE 0x00128c 0x000000000040028c 0x000000000040028c 0x000044 0x000044 R 0x4
INTERP 0x001570 0x0000000000400570 0x0000000000400570 0x00001b 0x00001b R 0x1
[Requesting program interpreter: /lib/ld-linux-aarch64.so.1]
GNU_EH_FRAME 0x0be928 0x00000000004bd928 0x00000000004bd928 0x0018f4 0x0018f4 R 0x4
LOAD 0x0cc130 0x00000000004db130 0x00000000004db130 0x002e68 0x0056e0 RW 0x1000
TLS 0x0cc130 0x00000000004db130 0x00000000004db130 0x000000 0x000010 R 0x8
GNU_RELRO 0x0cc130 0x00000000004db130 0x00000000004db130 0x001ed0 0x001ed0 R 0x1
Section to Segment mapping:
Segment Sections...
00
01
02 .dynamic .dynstr
03 .dynamic
04 .gnu.hash .interp .note.ABI-tag .note.gnu.build-id .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame .gcc_except_table
05
06 .interp
07 .eh_frame_hdr
08 .init_array .fini_array .data.rel.ro .got .got.plt .data .bss
09 .tbss
10 .init_array .fini_array .data.rel.ro .got
None .dynsym .comment .symtab .strtab .shstrtab
In particular, this LOAD header assumes a 4kB page system (the virtual address is aligned to 4kB and the alignment itself says 0x1000 which is 4kB):
LOAD 0x000000 0x00000000003ff000 0x00000000003ff000 0x001000 0x001000 RW 0x1000
My system is Asahi Linux (Linux on ARM Macbooks) which use 16kB pages, not 4kB. So of course trying to map files on 4kB boundaries is going to fail. In fact, aarch64 systems can have up to 64kB page sizes.
Bumping the toolchain version up to 1.100301.220327 fixes the issue:
[env:adafruit_circuitplayground_m0]
platform = atmelsam
board = adafruit_circuitplayground_m0
framework = arduino
platform_packages = toolchain-gccarmnoneeabi@~1.100301.220327
And indeed, checking readelf --program-headers
shows that the new arm-none-eabi-g++ binary uses 64kB page alignment.
I think this bug can be fixed in two ways: either by bumping up the GCC version to at least 1.100301.220327 or by rebuilding the older version in a way that fixes the alignment issue.