summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2013-03-01 17:00:39 -0600
committerStefan Reinauer <stefan.reinauer@coreboot.org>2013-03-21 23:38:44 +0100
commit55ed3106556a9bcbe36d3389dc5230d4a4ee2a40 (patch)
treec99b4c4394acbd1894f2ac9cef74665720a08965 /src
parentdf3a109b72907419d503c81257ea241becdbb915 (diff)
downloadcoreboot-55ed3106556a9bcbe36d3389dc5230d4a4ee2a40.tar.xz
rmodule: correct ordering of bss clearing
This patch fixes an issue for rmodules which are copied into memory at the final load/link location. If the bss section is cleared for that rmodule the relocation could not take place properly since the relocation information was wiped by act of clearing the bss. The reason is that the relocation information resides at the same address as the bss section. Correct this issue by performing the relocation before clearing the bss. Change-Id: I01a124a8201321a9eaf6144c743fa818c0f004b4 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/2822 Reviewed-by: Ronald G. Minnich <rminnich@gmail.com> Tested-by: build bot (Jenkins)
Diffstat (limited to 'src')
-rw-r--r--src/lib/rmodule.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/src/lib/rmodule.c b/src/lib/rmodule.c
index 81e9ef10ed..4276ed33e8 100644
--- a/src/lib/rmodule.c
+++ b/src/lib/rmodule.c
@@ -241,13 +241,17 @@ int rmodule_load(void *base, struct rmodule *module)
* In order to load the module at a given address, the following steps
* take place:
* 1. Copy payload to base address.
- * 2. Clear the bss segment.
- * 3. Adjust relocations within the module to new base address.
+ * 2. Adjust relocations within the module to new base address.
+ * 3. Clear the bss segment last since the relocations live where
+ * the bss is. If an rmodule is being loaded from its load
+ * address the relocations need to be processed before the bss.
*/
module->location = base;
rmodule_copy_payload(module);
+ if (rmodule_relocate(module))
+ return -1;
rmodule_clear_bss(module);
- return rmodule_relocate(module);
+ return 0;
}
void *rmodule_find_region_below(void *addr, size_t rmodule_size,