-
Notifications
You must be signed in to change notification settings - Fork 2.1k
cpu/avr8_common: Fix link with binutils > 2.35.2 #16790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
does this one ldscript work for all our avr8s? |
@nandojve want to take a look at this? |
Maybe @jnohlgard has an idea how to fix the original |
What is the linker script this is based on? Of course if we can't find a solution that can do with less copy & paste, we should merge this swiftly before the next release. |
The one provided by binutils-avr 2.37-r of Alpine (I think binutils is build unpatched on Alpine): $ diff /usr/avr/lib/ldscripts/avr6.xn avr8.ld
--- /usr/avr/lib/ldscripts/avr6.xn
+++ avr8.ld
@@ -173,7 +173,9 @@
{
PROVIDE (__data_start = .) ;
*(.data)
- *(.data*)
+ *(.data*)
+ KEEP (*(SORT(.roxfa.*)))
+ KEEP (*(SORT(.xfa.*)))
*(.gnu.linkonce.d*)
*(.rodata) /* We need to include .rodata here if gcc is used */
*(.rodata*) /* with -fdata-sections. */ |
That's a pleasantly small change. Better mark that in the linker script to ease future updates. |
feel free to squash |
Hi, I noted below from diff --git a/cpu/avr8_common/ldscripts/avr8.ld b/cpu/avr8_common/ldscripts/avr8.ld
index 0ac95e9505..bed30592ae 100644
--- a/cpu/avr8_common/ldscripts/avr8.ld
+++ b/cpu/avr8_common/ldscripts/avr8.ld
@@ -101,6 +101,10 @@ SECTIONS
*libc.a:*(.progmem.data)
*(.progmem.*)
. = ALIGN(2);
+ /* For future tablejump instruction arrays for 3 byte pc devices.
+ We don't relax jump/call instructions within these sections. */
+ *(.jumptables)
+ *(.jumptables*)
/* For code that needs to reside in the lower 128k progmem. */
*(.lowtext)
*(.lowtext*)
@@ -226,6 +230,10 @@ SECTIONS
{
KEEP(*(.signature*))
} > signature
+ .user_signatures :
+ {
+ KEEP(*(.user_signatures*))
+ } > user_signatures
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) } |
Did you figure out what the difference is between the working binary and the broken one? |
@jnohlgard: The .data sections are now longer merged and the .text section gets a wrong offset. Old binutils (working):
New binutils (broken):
|
Which ld variant are you using? (gold, bfd, lld?) |
the binutils linker |
Murdock does not like it. |
Seems like the new linker script is not compatible with the toolchain in the docker container. Maybe diffing the to scripts could also give a clue why xfa.ld stopped working in the first place. Anyway, I will have to resume looking into this after my vacation. Feel free to take over, if this is an itch you care to scratch. |
b2c59c9
to
ce65c34
Compare
Almost. --- avr51.xn
+++ avr6.xn
@@ -4,9 +4,9 @@
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
-OUTPUT_ARCH(avr:51)
-__TEXT_REGION_LENGTH__ = DEFINED(__TEXT_REGION_LENGTH__) ? __TEXT_REGION_LENGTH__ : 128K;
-__DATA_REGION_LENGTH__ = DEFINED(__DATA_REGION_LENGTH__) ? __DATA_REGION_LENGTH__ : 0xff00;
+OUTPUT_ARCH(avr:6)
+__TEXT_REGION_LENGTH__ = DEFINED(__TEXT_REGION_LENGTH__) ? __TEXT_REGION_LENGTH__ : 1024K;
+__DATA_REGION_LENGTH__ = DEFINED(__DATA_REGION_LENGTH__) ? __DATA_REGION_LENGTH__ : 0xfe00;
__EEPROM_REGION_LENGTH__ = DEFINED(__EEPROM_REGION_LENGTH__) ? __EEPROM_REGION_LENGTH__ : 64K;
__FUSE_REGION_LENGTH__ = DEFINED(__FUSE_REGION_LENGTH__) ? __FUSE_REGION_LENGTH__ : 1K;
__LOCK_REGION_LENGTH__ = DEFINED(__LOCK_REGION_LENGTH__) ? __LOCK_REGION_LENGTH__ : 1K;
@@ -15,7 +15,7 @@
MEMORY
{
text (rx) : ORIGIN = 0, LENGTH = __TEXT_REGION_LENGTH__
- data (rw!x) : ORIGIN = 0x800100, LENGTH = __DATA_REGION_LENGTH__
+ data (rw!x) : ORIGIN = 0x800200, LENGTH = __DATA_REGION_LENGTH__
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = __EEPROM_REGION_LENGTH__
fuse (rw!x) : ORIGIN = 0x820000, LENGTH = __FUSE_REGION_LENGTH__
lock (rw!x) : ORIGIN = 0x830000, LENGTH = __LOCK_REGION_LENGTH__ --- avr51.xn
+++ avrxmega6.xn
@@ -4,9 +4,9 @@
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
-OUTPUT_ARCH(avr:51)
-__TEXT_REGION_LENGTH__ = DEFINED(__TEXT_REGION_LENGTH__) ? __TEXT_REGION_LENGTH__ : 128K;
-__DATA_REGION_LENGTH__ = DEFINED(__DATA_REGION_LENGTH__) ? __DATA_REGION_LENGTH__ : 0xff00;
+OUTPUT_ARCH(avr:106)
+__TEXT_REGION_LENGTH__ = DEFINED(__TEXT_REGION_LENGTH__) ? __TEXT_REGION_LENGTH__ : 1024K;
+__DATA_REGION_LENGTH__ = DEFINED(__DATA_REGION_LENGTH__) ? __DATA_REGION_LENGTH__ : 0xffa0;
__EEPROM_REGION_LENGTH__ = DEFINED(__EEPROM_REGION_LENGTH__) ? __EEPROM_REGION_LENGTH__ : 64K;
__FUSE_REGION_LENGTH__ = DEFINED(__FUSE_REGION_LENGTH__) ? __FUSE_REGION_LENGTH__ : 1K;
__LOCK_REGION_LENGTH__ = DEFINED(__LOCK_REGION_LENGTH__) ? __LOCK_REGION_LENGTH__ : 1K;
@@ -15,7 +15,7 @@
MEMORY
{
text (rx) : ORIGIN = 0, LENGTH = __TEXT_REGION_LENGTH__
- data (rw!x) : ORIGIN = 0x800100, LENGTH = __DATA_REGION_LENGTH__
+ data (rw!x) : ORIGIN = 0x802000, LENGTH = __DATA_REGION_LENGTH__
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = __EEPROM_REGION_LENGTH__
fuse (rw!x) : ORIGIN = 0x820000, LENGTH = __FUSE_REGION_LENGTH__
lock (rw!x) : ORIGIN = 0x830000, LENGTH = __LOCK_REGION_LENGTH__ --- avr51.xn
+++ avrxmega7.xn
@@ -4,9 +4,9 @@
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
-OUTPUT_ARCH(avr:51)
-__TEXT_REGION_LENGTH__ = DEFINED(__TEXT_REGION_LENGTH__) ? __TEXT_REGION_LENGTH__ : 128K;
-__DATA_REGION_LENGTH__ = DEFINED(__DATA_REGION_LENGTH__) ? __DATA_REGION_LENGTH__ : 0xff00;
+OUTPUT_ARCH(avr:107)
+__TEXT_REGION_LENGTH__ = DEFINED(__TEXT_REGION_LENGTH__) ? __TEXT_REGION_LENGTH__ : 1024K;
+__DATA_REGION_LENGTH__ = DEFINED(__DATA_REGION_LENGTH__) ? __DATA_REGION_LENGTH__ : 0xffa0;
__EEPROM_REGION_LENGTH__ = DEFINED(__EEPROM_REGION_LENGTH__) ? __EEPROM_REGION_LENGTH__ : 64K;
__FUSE_REGION_LENGTH__ = DEFINED(__FUSE_REGION_LENGTH__) ? __FUSE_REGION_LENGTH__ : 1K;
__LOCK_REGION_LENGTH__ = DEFINED(__LOCK_REGION_LENGTH__) ? __LOCK_REGION_LENGTH__ : 1K;
@@ -15,7 +15,7 @@
MEMORY
{
text (rx) : ORIGIN = 0, LENGTH = __TEXT_REGION_LENGTH__
- data (rw!x) : ORIGIN = 0x800100, LENGTH = __DATA_REGION_LENGTH__
+ data (rw!x) : ORIGIN = 0x802000, LENGTH = __DATA_REGION_LENGTH__
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = __EEPROM_REGION_LENGTH__
fuse (rw!x) : ORIGIN = 0x820000, LENGTH = __FUSE_REGION_LENGTH__
lock (rw!x) : ORIGIN = 0x830000, LENGTH = __LOCK_REGION_LENGTH__ The main part of the LD scripts are completely identical, so I just added a common |
Hi @maribu , Nice work! I noted that it is missing "user_signature" entries at avr_common.ld. See, #16790 (comment) |
That section was dropped upstream. The linker scripts are identical to the ones a current AVR toolchain contains, execpt for:
(See #16790 (comment) - there is indeed no extra section in at ATXmega script comared to the ATmega script. It really only is about memory sizes/origin and output arch.) I think it will be easier to maintain of the linker scripts remain as close to upstream as possible. But if there is a feature to gain from adding it, I would certainly do so. |
Indeed there is, please check XMEGA-A manual 4.3.5 User Signature Row. In fact, it is defined at memory sizes as
but there is no entry at |
Are you sure that there is value in adding that section? The horribly outdated toolchain in SECTIONS
{
[...]
.user_signatures :
{
KEEP(*(.user_signatures*))
} > user_signatures
[...]
} But this section has been dropped in upstream, either for a reason or by accident. In any case, no code in RIOT is providing any symbols that get linked into that section and the section is empty, even when using
So adding that section will - with the current code in RIOT - not change the ELF file in any way. I also think it does make sense that upstream dropped it. The user signature seems to be something that you don't want to flash together with your firmware, but rather once during commissioning. Not having the section might prevent some mistakes from happening here. But in any case: Since the ld scripts are an exact copy of the upstream version (except for the XFA addition and the deduplication), this is IMO unrelated to the PR. That section has also not been present for quite a few release, so any code relying on this will already be broken in |
I don't have a use case for it. I'm just warning what users may not have access since you are touching LD script topic. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please squash.
I think those avr51, avr6, … could eventually be modeled as CPU_CORE
just like we do on Cortex-M.
@maribu ping 😉 |
The xfa.ld script is incompatible with binutils > 2.35.2 and results in firmwares that wont boot. Sadly, I couldn't figure out an elegant way to fix the issue. Instead, I modified the linker script provided by binutils to also include XFA.
454c8e1
to
62d6a56
Compare
I'm not really happy with this, as understanding and maintaining the original linker script was quite a lot easier than this. But I guess until we have a better fix, we should get this in. So if nobody speaks up now, I hit the green button soonish. |
Thanks for the reviews! |
Backport provided in #16990 |
Contribution description
The xfa.ld script is incompatible with binutils > 2.35.2 and results in firmwares that wont boot. Sadly, I couldn't figure out an elegant way to fix the issue. Instead, I modified the linker script provided by binutils to also include XFA.
Testing procedure
tests/xfa
should again still compile, flash, and bootIssues/PRs references
Fixes #16251