Clean up .ncdata/ncbss hackery in plugin linker script

rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]>
Newsgroups gmane.comp.systems.archos.rockbox.cvs
Message-ID <[email protected]>
commit 92b0bf7a273b9d2b4126b8c10b358a621bab9e2f
Author: Aidan MacDonald <[email protected]>
Date:   Thu Feb 5 12:01:21 2026 +0000

    Clean up .ncdata/ncbss hackery in plugin linker script
    
    The mess here can be reduced by paying careful attention to
    how the linker allocates LMAs/VMAs within MEMORY regions.
    
    Changing the way .ncdata and .ncbss are defined so that they
    reserve the LMA/VMA ranges they use in PLUGIN_RAM removes the
    need to explicitly set the VMAs of other sections, cutting
    down on the number of ifdefs needed and making the script a
    bit simpler.
    
    Change-Id: I316fc6e8dedd621537261d52c1ec7c20ec09438a

diff --git a/apps/plugins/plugin.lds b/apps/plugins/plugin.lds
index 6fbc834a86..fbba450b2b 100644
--- a/apps/plugins/plugin.lds
+++ b/apps/plugins/plugin.lds
@@ -281,25 +281,18 @@ SECTIONS
     } > PLUGIN_RAM
 
 #if NOCACHE_BASE != 0
-    .ncdata . + NOCACHE_BASE :
+    /*
+     * Allocate .ncdata based on the following constraints:
+     *
+     * 1. the LMA must be allocated at the next free LMA in
+     *    PLUGIN_RAM and aligned to a cacheline boundary.
+     * 2. the VMA - LMA offset must equal NOCACHE_BASE.
+     */
+    .ncdata ALIGN(. + NOCACHE_BASE, CACHEALIGN_SIZE) : ALIGN(CACHEALIGN_SIZE)
     {
-        . = ALIGN(CACHEALIGN_SIZE);
         *(.ncdata*)
         . = ALIGN(CACHEALIGN_SIZE);
-/* EABI currently needs these defined here, otherwise .iram and .bss can
-   sometimes have an incorrect load address, breaking codecs and plugins. */
-        bssaddr = . - NOCACHE_BASE;
-#if defined(IRAMSIZE) && IRAMSIZE != 0
-        iramcopy = . - NOCACHE_BASE;
-#endif
     } AT> PLUGIN_RAM
-/* This definition is used when NOCACHE_BASE is 0. The address offset bug only
-   seems to occur when the empty .ncdata is present. */
-#else
-    bssaddr = .;
-#if defined(IRAMSIZE) && IRAMSIZE != 0
-    iramcopy = .;
-#endif
 #endif
 
     /DISCARD/ :
@@ -311,7 +304,7 @@ SECTIONS
 #endif
     }
 
-    .bss bssaddr (NOLOAD) :
+    .bss (NOLOAD) :
     {
     	plugin_bss_start = .;
     	_plugin_bss_start = .;
@@ -324,29 +317,47 @@ SECTIONS
     } > PLUGIN_RAM
 
 #if NOCACHE_BASE != 0
-    .ncbss . + NOCACHE_BASE (NOLOAD) :
+    /*
+     * .ncbss has the same constraints as the .ncdata section
+     * above but there is an extra complication: because it is
+     * a NOLOAD section, unlike .ncdata it cannot consume any
+     * VMAs or LMAs in PLUGIN_RAM itself.
+     *
+     * Because free VMA/LMAs in PLUGIN_RAM are unchanged, any
+     * subsequent sections will get placed at the end of the
+     * .bss section, overlapping .ncbss, which we don't want.
+     *
+     * One solution is to manually place the next sections to
+     * account for the size of .ncbss, but a cleaner solution
+     * is to define a dummy section (.ncbss_vma) allocated at
+     * the same VMA as .ncbss and equal in size, and placed in
+     * the PLUGIN_RAM region. This allocates the correct VMA
+     * range in plugin RAM so that the next section will not
+     * overlap .ncbss.
+     */
+    .ncbss ALIGN(. + NOCACHE_BASE, CACHEALIGN_SIZE) (NOLOAD) : ALIGN(CACHEALIGN_SIZE)
     {
-    	. = ALIGN(CACHEALIGN_SIZE);
     	*(.ncbss*)
         . = ALIGN(CACHEALIGN_SIZE);
-        /* We won't trust this one any more than with .ncdata */
-        pluginendaddr = . - NOCACHE_BASE;
     } AT> PLUGIN_RAM
-#else
-    pluginendaddr = .;
+
+    .ncbss_vma (NOLOAD) : ALIGN(CACHEALIGN_SIZE)
+    {
+        . += SIZEOF(.ncbss);
+    } > PLUGIN_RAM
 #endif
 
     /* Final end of plugin after IRAM setup. The plugin or codec buffer
        is considered unused by the in-RAM image at this point once IRAM
        is copied. */
-    .pluginend pluginendaddr :
+    .pluginend (NOLOAD) :
     {
         _plugin_end_addr = .;
         plugin_end_addr = .;
-    }
+    } > PLUGIN_RAM
 
 #if defined(IRAMSIZE) && IRAMSIZE != 0
-    .iram IRAMORIG : AT (iramcopy)
+    .iram IRAMORIG : AT(LOADADDR(.bss))
     {
         iramstart = .;
         *(.icode)
@@ -354,6 +365,7 @@ SECTIONS
         *(.idata)
         iramend = .;
     } > PLUGIN_IRAM
+    iramcopy = LOADADDR(.iram);
 
     .ibss (NOLOAD) :
     {
@@ -384,3 +396,13 @@ SECTIONS
         KEEP(*(.comment))
     }
 }
+
+#if NOCACHE_BASE != 0
+/* Some asserts to make sure nocache sections appear correctly defined */
+ASSERT(LOADADDR(.ncdata) == ADDR(.ncdata) - NOCACHE_BASE, ".ncdata has incorrect LMA/VMA address");
+ASSERT(LOADADDR(.ncdata) % CACHEALIGN_SIZE == 0,          ".ncdata incorrectly aligned");
+ASSERT(LOADADDR(.ncbss) == ADDR(.ncbss) - NOCACHE_BASE,   ".ncbss has incorrect LMA/VMA address");
+ASSERT(LOADADDR(.ncbss) % CACHEALIGN_SIZE == 0,           ".ncbss incorrectly aligned");
+ASSERT(ADDR(.ncbss_vma) == LOADADDR(.ncbss),              ".ncbss_vma has wrong address");
+ASSERT(SIZEOF(.ncbss_vma) == SIZEOF(.ncbss),              ".ncbss_vma has wrong size");
+#endif
-- 
rockbox-cvs mailing list
[email protected]
https://lists.haxx.se/mailman/listinfo/rockbox-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.