Fix .ncbss from possibly overlapping .ncdata in plugins/codecs.

(Take #2)

If .bss wasn't large enough, and .ncdata was empty, .ncbss would be
at an address overlapping the alignment-padded end of .ncdata and
and linking would fail with an overlap error.

Adds plugin load end address that accounts for IRAM going past
the final .bss sections, making IRAM overlay compatible. load_code
could also use this instead of the file size.

The .lds becomes a bit more straightforward and explicit when
assigning addresses.

Change-Id: Id0c33f257710e97ece2c831e0feaaa32c1a14e05
This commit is contained in:
Michael Sevakis 2013-07-11 01:36:46 -04:00
parent 2948cb42ae
commit 1329cc29de
2 changed files with 54 additions and 33 deletions

View file

@ -247,35 +247,38 @@ SECTIONS
{
*(.rodata*)
#if defined(IRAMSIZE) && IRAMSIZE == 0
*(.irodata)
*(.irodata)
#endif
. = ALIGN(0x4);
} > PLUGIN_RAM
.data :
{
*(.data*)
#if defined(IRAMSIZE) && IRAMSIZE == 0
*(.idata)
*(.idata)
#endif
} > PLUGIN_RAM
#if NOCACHE_BASE != 0
.ncdata . + NOCACHE_BASE :
{
. = ALIGN(CACHEALIGN_SIZE);
*(.ncdata*)
. = ALIGN(CACHEALIGN_SIZE);
/* EABI currently needs iramcopy defined here, otherwise .iram can sometimes
have an incorrect load address, breaking codecs. */
#if defined(IRAMSIZE)
/* 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. */
#elif defined(IRAMSIZE)
#else
bssaddr = .;
#if defined(IRAMSIZE) && IRAMSIZE != 0
iramcopy = .;
#endif
#endif
/DISCARD/ :
@ -286,33 +289,13 @@ SECTIONS
#endif
}
#if defined(IRAMSIZE) && IRAMSIZE != 0
.iram IRAMORIG : AT ( iramcopy)
{
iramstart = .;
*(.icode)
*(.irodata)
*(.idata)
iramend = .;
} > PLUGIN_IRAM
.ibss (NOLOAD) :
{
iedata = .;
*(.ibss)
. = ALIGN(0x4);
iend = .;
} > PLUGIN_IRAM
#endif
.bss (NOLOAD) :
.bss bssaddr (NOLOAD) :
{
plugin_bss_start = .;
_plugin_bss_start = .;
*(.bss*)
#if defined(IRAMSIZE) && IRAMSIZE == 0
*(.ibss)
*(.ibss)
#endif
*(COMMON)
. = ALIGN(0x4);
@ -324,16 +307,54 @@ SECTIONS
. = 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 = .;
#endif
/* Restore . */
.pluginend . - NOCACHE_BASE :
/* 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 :
{
_plugin_end_addr = .;
plugin_end_addr = .;
}
#if defined(IRAMSIZE) && IRAMSIZE != 0
.iram IRAMORIG : AT (iramcopy)
{
iramstart = .;
*(.icode)
*(.irodata)
*(.idata)
iramend = .;
} > PLUGIN_IRAM
.ibss (NOLOAD) :
{
iedata = .;
*(.ibss)
. = ALIGN(0x4);
iend = .;
} > PLUGIN_IRAM
loadendaddr = MAX(plugin_end_addr, LOADADDR(.iram) + SIZEOF(.iram));
#else
loadendaddr = plugin_end_addr;
#endif
/* This is for ovl_offset.pl and is the highest address that must
be loaded into the plugin buffer (past the end of last data in
stored image). */
.pluginloadend loadendaddr :
{
_plugin_load_end_addr = .;
plugin_load_end_addr = .;
}
/* Special trick to avoid a linker error when no other sections are
left after garbage collection (plugin not for this platform) */
.comment 0 :

View file

@ -19,7 +19,7 @@ sub map_scan {
elsif ($_ =~ / +0x([0-9a-f]+) +_?plugin_start_addr = ./) {
$startaddr = hex($1);
}
elsif ($_ =~ / +0x([0-9a-f]+) +_?plugin_end_addr = ./) {
elsif ($_ =~ / +0x([0-9a-f]+) +_?plugin_load_end_addr = ./) {
$endaddr = hex($1);
}
}