diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2013-07-11 01:36:46 -0400 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2013-07-11 04:32:23 -0400 |
commit | 1329cc29dec0ad2b5516fdcc8507f474d6b79172 (patch) | |
tree | 3d1f444240606d597903ed239b05b1e930e01d1e | |
parent | 2948cb42aecfe42a2dcad40d7791f703512891aa (diff) | |
download | rockbox-1329cc29dec0ad2b5516fdcc8507f474d6b79172.tar.gz rockbox-1329cc29dec0ad2b5516fdcc8507f474d6b79172.zip |
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
-rw-r--r-- | apps/plugins/plugin.lds | 85 | ||||
-rwxr-xr-x | tools/ovl_offset.pl | 2 |
2 files changed, 54 insertions, 33 deletions
diff --git a/apps/plugins/plugin.lds b/apps/plugins/plugin.lds index 10ce98fca4..831cb59b81 100644 --- a/apps/plugins/plugin.lds +++ b/apps/plugins/plugin.lds | |||
@@ -247,36 +247,39 @@ SECTIONS | |||
247 | { | 247 | { |
248 | *(.rodata*) | 248 | *(.rodata*) |
249 | #if defined(IRAMSIZE) && IRAMSIZE == 0 | 249 | #if defined(IRAMSIZE) && IRAMSIZE == 0 |
250 | *(.irodata) | 250 | *(.irodata) |
251 | #endif | 251 | #endif |
252 | . = ALIGN(0x4); | ||
253 | } > PLUGIN_RAM | 252 | } > PLUGIN_RAM |
254 | 253 | ||
255 | .data : | 254 | .data : |
256 | { | 255 | { |
257 | *(.data*) | 256 | *(.data*) |
258 | #if defined(IRAMSIZE) && IRAMSIZE == 0 | 257 | #if defined(IRAMSIZE) && IRAMSIZE == 0 |
259 | *(.idata) | 258 | *(.idata) |
260 | #endif | 259 | #endif |
261 | } > PLUGIN_RAM | 260 | } > PLUGIN_RAM |
262 | 261 | ||
263 | #if NOCACHE_BASE != 0 | 262 | #if NOCACHE_BASE != 0 |
264 | .ncdata . + NOCACHE_BASE : | 263 | .ncdata . + NOCACHE_BASE : |
265 | { | 264 | { |
266 | . = ALIGN(CACHEALIGN_SIZE); | 265 | . = ALIGN(CACHEALIGN_SIZE); |
267 | *(.ncdata*) | 266 | *(.ncdata*) |
268 | . = ALIGN(CACHEALIGN_SIZE); | 267 | . = ALIGN(CACHEALIGN_SIZE); |
269 | /* EABI currently needs iramcopy defined here, otherwise .iram can sometimes | 268 | /* EABI currently needs these defined here, otherwise .iram and .bss can |
270 | have an incorrect load address, breaking codecs. */ | 269 | sometimes have an incorrect load address, breaking codecs and plugins. */ |
271 | #if defined(IRAMSIZE) | 270 | bssaddr = . - NOCACHE_BASE; |
271 | #if defined(IRAMSIZE) && IRAMSIZE != 0 | ||
272 | iramcopy = . - NOCACHE_BASE; | 272 | iramcopy = . - NOCACHE_BASE; |
273 | #endif | 273 | #endif |
274 | } AT> PLUGIN_RAM | 274 | } AT> PLUGIN_RAM |
275 | /* This definition is used when NOCACHE_BASE is 0. The address offset bug only | 275 | /* This definition is used when NOCACHE_BASE is 0. The address offset bug only |
276 | seems to occur when the empty .ncdata is present. */ | 276 | seems to occur when the empty .ncdata is present. */ |
277 | #elif defined(IRAMSIZE) | 277 | #else |
278 | bssaddr = .; | ||
279 | #if defined(IRAMSIZE) && IRAMSIZE != 0 | ||
278 | iramcopy = .; | 280 | iramcopy = .; |
279 | #endif | 281 | #endif |
282 | #endif | ||
280 | 283 | ||
281 | /DISCARD/ : | 284 | /DISCARD/ : |
282 | { | 285 | { |
@@ -286,33 +289,13 @@ SECTIONS | |||
286 | #endif | 289 | #endif |
287 | } | 290 | } |
288 | 291 | ||
289 | #if defined(IRAMSIZE) && IRAMSIZE != 0 | 292 | .bss bssaddr (NOLOAD) : |
290 | .iram IRAMORIG : AT ( iramcopy) | ||
291 | { | ||
292 | iramstart = .; | ||
293 | *(.icode) | ||
294 | *(.irodata) | ||
295 | *(.idata) | ||
296 | iramend = .; | ||
297 | } > PLUGIN_IRAM | ||
298 | |||
299 | |||
300 | .ibss (NOLOAD) : | ||
301 | { | ||
302 | iedata = .; | ||
303 | *(.ibss) | ||
304 | . = ALIGN(0x4); | ||
305 | iend = .; | ||
306 | } > PLUGIN_IRAM | ||
307 | #endif | ||
308 | |||
309 | .bss (NOLOAD) : | ||
310 | { | 293 | { |
311 | plugin_bss_start = .; | 294 | plugin_bss_start = .; |
312 | _plugin_bss_start = .; | 295 | _plugin_bss_start = .; |
313 | *(.bss*) | 296 | *(.bss*) |
314 | #if defined(IRAMSIZE) && IRAMSIZE == 0 | 297 | #if defined(IRAMSIZE) && IRAMSIZE == 0 |
315 | *(.ibss) | 298 | *(.ibss) |
316 | #endif | 299 | #endif |
317 | *(COMMON) | 300 | *(COMMON) |
318 | . = ALIGN(0x4); | 301 | . = ALIGN(0x4); |
@@ -324,16 +307,54 @@ SECTIONS | |||
324 | . = ALIGN(CACHEALIGN_SIZE); | 307 | . = ALIGN(CACHEALIGN_SIZE); |
325 | *(.ncbss*) | 308 | *(.ncbss*) |
326 | . = ALIGN(CACHEALIGN_SIZE); | 309 | . = ALIGN(CACHEALIGN_SIZE); |
310 | /* We won't trust this one any more than with .ncdata */ | ||
311 | pluginendaddr = . - NOCACHE_BASE; | ||
327 | } AT> PLUGIN_RAM | 312 | } AT> PLUGIN_RAM |
313 | #else | ||
314 | pluginendaddr = .; | ||
328 | #endif | 315 | #endif |
329 | 316 | ||
330 | /* Restore . */ | 317 | /* Final end of plugin after IRAM setup. The plugin or codec buffer |
331 | .pluginend . - NOCACHE_BASE : | 318 | is considered unused by the in-RAM image at this point once IRAM |
319 | is copied. */ | ||
320 | .pluginend pluginendaddr : | ||
332 | { | 321 | { |
333 | _plugin_end_addr = .; | 322 | _plugin_end_addr = .; |
334 | plugin_end_addr = .; | 323 | plugin_end_addr = .; |
335 | } | 324 | } |
336 | 325 | ||
326 | #if defined(IRAMSIZE) && IRAMSIZE != 0 | ||
327 | .iram IRAMORIG : AT (iramcopy) | ||
328 | { | ||
329 | iramstart = .; | ||
330 | *(.icode) | ||
331 | *(.irodata) | ||
332 | *(.idata) | ||
333 | iramend = .; | ||
334 | } > PLUGIN_IRAM | ||
335 | |||
336 | .ibss (NOLOAD) : | ||
337 | { | ||
338 | iedata = .; | ||
339 | *(.ibss) | ||
340 | . = ALIGN(0x4); | ||
341 | iend = .; | ||
342 | } > PLUGIN_IRAM | ||
343 | |||
344 | loadendaddr = MAX(plugin_end_addr, LOADADDR(.iram) + SIZEOF(.iram)); | ||
345 | #else | ||
346 | loadendaddr = plugin_end_addr; | ||
347 | #endif | ||
348 | |||
349 | /* This is for ovl_offset.pl and is the highest address that must | ||
350 | be loaded into the plugin buffer (past the end of last data in | ||
351 | stored image). */ | ||
352 | .pluginloadend loadendaddr : | ||
353 | { | ||
354 | _plugin_load_end_addr = .; | ||
355 | plugin_load_end_addr = .; | ||
356 | } | ||
357 | |||
337 | /* Special trick to avoid a linker error when no other sections are | 358 | /* Special trick to avoid a linker error when no other sections are |
338 | left after garbage collection (plugin not for this platform) */ | 359 | left after garbage collection (plugin not for this platform) */ |
339 | .comment 0 : | 360 | .comment 0 : |
diff --git a/tools/ovl_offset.pl b/tools/ovl_offset.pl index 10419999d6..12777582cd 100755 --- a/tools/ovl_offset.pl +++ b/tools/ovl_offset.pl | |||
@@ -19,7 +19,7 @@ sub map_scan { | |||
19 | elsif ($_ =~ / +0x([0-9a-f]+) +_?plugin_start_addr = ./) { | 19 | elsif ($_ =~ / +0x([0-9a-f]+) +_?plugin_start_addr = ./) { |
20 | $startaddr = hex($1); | 20 | $startaddr = hex($1); |
21 | } | 21 | } |
22 | elsif ($_ =~ / +0x([0-9a-f]+) +_?plugin_end_addr = ./) { | 22 | elsif ($_ =~ / +0x([0-9a-f]+) +_?plugin_load_end_addr = ./) { |
23 | $endaddr = hex($1); | 23 | $endaddr = hex($1); |
24 | } | 24 | } |
25 | } | 25 | } |