]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
AVR: ld/32968 - Assert that .progmem data resides in the lower 64 KiB.
authorGeorg-Johann Lay <avr@gjlay.de>
Thu, 15 May 2025 08:29:25 +0000 (10:29 +0200)
committerGeorg-Johann Lay <avr@gjlay.de>
Sat, 7 Jun 2025 10:23:15 +0000 (12:23 +0200)
This patch locates the linker stubs / trampolines *after* all the .progmem
sections.  This is the natural placement since progmem data has to reside
in the lower 64 KiB (it is accessed using LPM), whereas the linker stubs
are only required to be located in the lower 128 KiB of program memory.
(They must be in the range of EICALL / EIJMP with EIND = 0.)

The current location of the linker stubs was motivated by an invalid test
case from PR13812 that allocates more than 64 KiB of progmem data.

The patch adds an assertion that makes sure that no progmem data is
allocated past 0xffff.

Data that is accessed using ELPM should be located to .progmemx so that
no .progmem addresses are wasted.  .progmemx was introduced in 2017 and
is used by __memx, __flashx and by the current AVR-LibC.
(The compiler uses .jumptables.gcc for its jump dispatch tables since
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63223 / GCC v4.9.2).

PR ld/32968
ld/
* scripttempl/avr.sc: Move the trampolines section after the
.progmem sections.  Assert that .progmem is in the lower 64 KiB.

ld/NEWS
ld/scripttempl/avr.sc

diff --git a/ld/NEWS b/ld/NEWS
index 7b5e2e47c07bd842fbdd50a0113a9199e5a76d68..209f764dddb128ce14a5ccf98f2b15b8c4c853db 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
 * Remove the linker -taso option for Alpha target, as Linux/Alpha kernel
   support for 32-bit pointers has been removed.
 
+* On avr, the default linker scripts now assert that the .progmem sections
+  don't extend past 0xffff since they are accessed by means of LPM.
+  For data in program memory that may be located past 0xffff, a .progmemx
+  section should be used.
+
 * On s390, generate ".eh_frame" unwind information for the linker generated
   .plt section.  Enabled by default.  Can be disabled using linker option
   --no-ld-generated-unwind-info.
index 8479ec31c27e9c56fc75eb00df465005911dcfc8..4d9af7fcf2ca17776047d292417b6a672f8fab73 100644 (file)
@@ -189,11 +189,16 @@ SECTIONS
     ${RELOCATING+*(.vectors)
     KEEP(*(.vectors))
 
-    /* For data that needs to reside in the lower 64k of progmem.  */
-    *(.progmem.gcc*)
+    /* For data that needs to reside in the lower 64k of progmem.
+       For data accessed with ELPM use .progmemx.* instead
+       so that no lower 64k .progmem addresses are wasted.  */
+    __progmem_start = . ;
+    *(.progmem)
+    *(.progmem.*)
+    __progmem_end = . ;
+    ASSERT (__progmem_start == __progmem_end || __progmem_end <= 0x10000,
+            \".progmem section exceeds 0x10000\");
 
-    /* PR 13812: Placing the trampolines here gives a better chance
-       that they will be in range of the code that uses them.  */
     . = ALIGN(2);
     __trampolines_start = . ;
     /* The jump trampolines for the 16-bit limited relocs will reside here.  */
@@ -201,12 +206,6 @@ SECTIONS
     *(.trampolines*)
     __trampolines_end = . ;
 
-    /* avr-libc expects these data to reside in lower 64K. */
-    *libprintf_flt.a:*(.progmem.data)
-    *libc.a:*(.progmem.data)
-
-    *(.progmem.*)
-
     . = ALIGN(2);
 
     /* For code that needs to reside in the lower 128k progmem.  */
@@ -273,6 +272,7 @@ SECTIONS
     *(.hightext)
     *(.hightext*)
 
+    *(.progmemx)
     *(.progmemx.*)
 
     . = ALIGN(2);