[SeaBIOS] [PATCH] Don't relocate "varlow" variable references at runtime.

Kevin O'Connor kevin at koconnor.net
Wed Feb 20 03:11:55 CET 2013


Since the final location of the "varlow" variables are known at build
time, link the final locations into the binary during the build.  The
16bit code was already done at link time - update the build so the
32bit code is also done at link time.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---

v2 - When relocations are disables make sure the "init" sections are
     empty.  Thus "init32flat_end" always points to the beginning of
     the "fixed" code regardless of CONFIG_RELOCATE_INIT and there is
     no reason to introduce a final_code32flat_start reference.

---
 src/pmm.c          | 25 +++++++++++----------
 src/post.c         |  8 +------
 src/types.h        |  2 +-
 src/util.h         |  2 +-
 tools/checkrom.py  |  4 +---
 tools/layoutrom.py | 66 +++++++++++++++++++++++++++++-------------------------
 6 files changed, 53 insertions(+), 54 deletions(-)

diff --git a/src/pmm.c b/src/pmm.c
index 8944bae..02fa328 100644
--- a/src/pmm.c
+++ b/src/pmm.c
@@ -223,7 +223,7 @@ void
 malloc_preinit(void)
 {
     ASSERT32FLAT();
-    dprintf(3, "malloc setup\n");
+    dprintf(3, "malloc preinit\n");
 
     dprintf(1, "Ram Size=0x%08x (0x%016llx high)\n", RamSize, RamSizeOver4G);
 
@@ -288,25 +288,26 @@ csm_malloc_preinit(u32 low_pmm, u32 low_pmm_size, u32 hi_pmm, u32 hi_pmm_size)
 
 // Update pointers after code relocation.
 void
-malloc_fixupreloc_init(void)
+malloc_init(void)
 {
     ASSERT32FLAT();
-    if (!CONFIG_RELOCATE_INIT)
-        return;
-    dprintf(3, "malloc fixup reloc\n");
-
-    int i;
-    for (i=0; i<ARRAY_SIZE(Zones); i++) {
-        struct zone_s *zone = Zones[i];
-        if (zone->info)
-            zone->info->pprev = &zone->info;
+    dprintf(3, "malloc init\n");
+
+    if (CONFIG_RELOCATE_INIT) {
+        // Fixup malloc pointers after relocation
+        int i;
+        for (i=0; i<ARRAY_SIZE(Zones); i++) {
+            struct zone_s *zone = Zones[i];
+            if (zone->info)
+                zone->info->pprev = &zone->info;
+        }
     }
 
     // Move low-memory initial variable content to new location.
     extern u8 varlow_start[], varlow_end[], final_varlow_start[];
     memmove(final_varlow_start, varlow_start, varlow_end - varlow_start);
 
-    // Add space free'd during relocation in f-segment to ZoneFSeg
+    // Add space available in f-segment to ZoneFSeg
     extern u8 code32init_end[];
     if ((u32)code32init_end > BUILD_BIOS_ADDR) {
         memset((void*)BUILD_BIOS_ADDR, 0, (u32)code32init_end - BUILD_BIOS_ADDR);
diff --git a/src/post.c b/src/post.c
index 7f096de..44bb0b0 100644
--- a/src/post.c
+++ b/src/post.c
@@ -105,7 +105,7 @@ void
 interface_init(void)
 {
     // Running at new code address - do code relocation fixups
-    malloc_fixupreloc_init();
+    malloc_init();
 
     // Setup romfile items.
     qemu_cfg_init();
@@ -264,8 +264,6 @@ reloc_preinit(void *f, void *arg)
     extern u32 _reloc_rel_start[], _reloc_rel_end[];
     extern u32 _reloc_init_start[], _reloc_init_end[];
     extern u8 code32init_start[], code32init_end[];
-    extern u32 _reloc_varlow_start[], _reloc_varlow_end[];
-    extern u8 varlow_start[], varlow_end[], final_varlow_start[];
 
     // Allocate space for init code.
     u32 initsize = code32init_end - code32init_start;
@@ -275,10 +273,6 @@ reloc_preinit(void *f, void *arg)
         panic("No space for init relocation.\n");
 
     // Copy code and update relocs (init absolute, init relative, and runtime)
-    dprintf(1, "Relocating low data from %p to %p (size %d)\n"
-            , varlow_start, final_varlow_start, varlow_end - varlow_start);
-    updateRelocs(code32flat_start, _reloc_varlow_start, _reloc_varlow_end
-                 , final_varlow_start - varlow_start);
     dprintf(1, "Relocating init from %p to %p (size %d)\n"
             , code32init_start, codedest, initsize);
     s32 delta = codedest - (void*)code32init_start;
diff --git a/src/types.h b/src/types.h
index 4df1476..03104a2 100644
--- a/src/types.h
+++ b/src/types.h
@@ -90,7 +90,7 @@ extern void __force_link_error__only_in_16bit(void) __noreturn;
 # define VAR16 __section(".discard.var16." UNIQSEC)
 # define VAR16FIXED(addr) VAR16 __VISIBLE __weak
 # define VAR32SEG __section(".discard.var32seg." UNIQSEC)
-# define VARLOW __section(".data.varlow." UNIQSEC) __VISIBLE
+# define VARLOW __section(".data.varlow." UNIQSEC) __VISIBLE __weak
 # define VARFSEG __section(".data.varfseg." UNIQSEC) __VISIBLE
 # define ASM16(code)
 # define ASM32FLAT(code) __ASM(code)
diff --git a/src/util.h b/src/util.h
index 5729a2f..9303b5a 100644
--- a/src/util.h
+++ b/src/util.h
@@ -371,7 +371,7 @@ int rom_confirm(u32 size);
 void csm_malloc_preinit(u32 low_pmm, u32 low_pmm_size, u32 hi_pmm,
                         u32 hi_pmm_size);
 void malloc_preinit(void);
-void malloc_fixupreloc_init(void);
+void malloc_init(void);
 void malloc_prepboot(void);
 void *pmm_malloc(struct zone_s *zone, u32 handle, u32 size, u32 align);
 int pmm_free(void *data);
diff --git a/tools/checkrom.py b/tools/checkrom.py
index f141f8b..6f07ac8 100755
--- a/tools/checkrom.py
+++ b/tools/checkrom.py
@@ -73,9 +73,7 @@ def main():
         rawdata = checksum(rawdata, tableofs, tablesize, CSUM_FIELD_OFS)
 
     # Print statistics
-    runtimesize = datasize
-    if '_reloc_abs_start' in symbols:
-        runtimesize = end - symbols['code32init_end'].offset
+    runtimesize = end - symbols['code32init_end'].offset
     print "Total size: %d  Fixed: %d  Free: %d (used %.1f%% of %dKiB rom)" % (
         datasize, runtimesize, finalsize - datasize
         , (datasize / float(finalsize)) * 100.0
diff --git a/tools/layoutrom.py b/tools/layoutrom.py
index 2543c58..2d45317 100755
--- a/tools/layoutrom.py
+++ b/tools/layoutrom.py
@@ -152,6 +152,7 @@ def getSectionsPrefix(sections, prefix):
 
 # The sections (and associated information) to be placed in output rom
 class LayoutInfo:
+    genreloc = None
     sections16 = sec16_start = sec16_align = None
     sections32seg = sec32seg_start = sec32seg_align = None
     sections32flat = sec32flat_start = sec32flat_align = None
@@ -159,9 +160,10 @@ class LayoutInfo:
     sections32low = sec32low_start = sec32low_align = None
     sections32fseg = sec32fseg_start = sec32fseg_align = None
     zonelow_base = final_sec32low_start = None
+    exportsyms = varlowsyms = None
 
 # Determine final memory addresses for sections
-def doLayout(sections, genreloc):
+def doLayout(sections):
     li = LayoutInfo()
     # Determine 16bit positions
     li.sections16 = getSectionsCategory(sections, '16')
@@ -223,17 +225,13 @@ def doLayout(sections, genreloc):
 
     # Determine "low memory" data positions
     li.sections32low = getSectionsCategory(sections, '32low')
-    if genreloc:
-        sec32low_top = li.sec32init_start
-        final_sec32low_top = min(BUILD_BIOS_ADDR, li.sec32flat_start)
-    else:
-        sec32low_top = min(BUILD_BIOS_ADDR, li.sec32init_start)
-        final_sec32low_top = sec32low_top
-    relocdelta = final_sec32low_top - sec32low_top
-    zonelow_base = final_sec32low_top - 64*1024
+    sec32low_end = li.sec32init_start
+    final_sec32low_start = min(BUILD_BIOS_ADDR, li.sec32flat_start)
+    relocdelta = final_sec32low_start - sec32low_end
+    zonelow_base = final_sec32low_start - 64*1024
     li.zonelow_base = max(BUILD_ROM_START, alignpos(zonelow_base, 2*1024))
     li.sec32low_start, li.sec32low_align = setSectionsStart(
-        li.sections32low, sec32low_top, 16
+        li.sections32low, sec32low_end, 16
         , segoffset=li.zonelow_base - relocdelta)
     li.final_sec32low_start = li.sec32low_start + relocdelta
 
@@ -243,7 +241,7 @@ def doLayout(sections, genreloc):
     size32fseg = li.sec32seg_start - li.sec32fseg_start
     size32flat = li.sec32fseg_start - li.sec32flat_start
     size32init = li.sec32flat_start - li.sec32init_start
-    sizelow = sec32low_top - li.sec32low_start
+    sizelow = sec32low_end - li.sec32low_start
     print "16bit size:           %d" % size16
     print "32bit segmented size: %d" % size32seg
     print "32bit flat size:      %d" % size32flat
@@ -258,7 +256,7 @@ def doLayout(sections, genreloc):
 ######################################################################
 
 # Write LD script includes for the given cross references
-def outXRefs(sections, useseg=0, exportsyms=[]):
+def outXRefs(sections, useseg=0, exportsyms=[], forcedelta=0):
     xrefs = dict([(symbol.name, symbol) for symbol in exportsyms])
     out = ""
     for section in sections:
@@ -272,7 +270,7 @@ def outXRefs(sections, useseg=0, exportsyms=[]):
         loc = symbol.section.finalloc
         if useseg:
             loc = symbol.section.finalsegloc
-        out += "%s = 0x%x ;\n" % (symbolname, loc + symbol.offset)
+        out += "%s = 0x%x ;\n" % (symbolname, loc + forcedelta + symbol.offset)
     return out
 
 # Write LD script includes for the given sections using relative offsets
@@ -319,7 +317,7 @@ def getSectionsStart(sections, defaddr=0):
                 if section.finalloc is not None] or [defaddr])
 
 # Output the linker scripts for all required sections.
-def writeLinkerScripts(li, exportsyms, genreloc, out16, out32seg, out32flat):
+def writeLinkerScripts(li, out16, out32seg, out32flat):
     # Write 16bit linker script
     out = outXRefs(li.sections16, useseg=1) + """
     zonelow_base = 0x%x ;
@@ -350,11 +348,10 @@ def writeLinkerScripts(li, exportsyms, genreloc, out16, out32seg, out32flat):
     outfile.close()
 
     # Write 32flat linker script
-    sections32all = (li.sections32flat + li.sections32init + li.sections32low
-                     + li.sections32fseg)
+    sections32all = (li.sections32flat + li.sections32init + li.sections32fseg)
     sec32all_start = li.sec32low_start
     relocstr = ""
-    if genreloc:
+    if li.genreloc:
         # Generate relocations
         absrelocs = getRelocs(
             li.sections32init, type='R_386_32', category='32init')
@@ -363,14 +360,14 @@ def writeLinkerScripts(li, exportsyms, genreloc, out16, out32seg, out32flat):
         initrelocs = getRelocs(
             li.sections32flat + li.sections32low + li.sections16
             + li.sections32seg + li.sections32fseg, category='32init')
-        lowrelocs = getRelocs(sections32all, category='32low')
         relocstr = (strRelocs("_reloc_abs", "code32init_start", absrelocs)
                     + strRelocs("_reloc_rel", "code32init_start", relrelocs)
-                    + strRelocs("_reloc_init", "code32flat_start", initrelocs)
-                    + strRelocs("_reloc_varlow", "code32flat_start", lowrelocs))
-        numrelocs = len(absrelocs + relrelocs + initrelocs + lowrelocs)
+                    + strRelocs("_reloc_init", "code32flat_start", initrelocs))
+        numrelocs = len(absrelocs + relrelocs + initrelocs)
         sec32all_start -= numrelocs * 4
-    out = outXRefs(sections32all, exportsyms=exportsyms) + """
+    out = outXRefs(li.sections32low, exportsyms=li.varlowsyms
+                   , forcedelta=li.final_sec32low_start-li.sec32low_start)
+    out += outXRefs(sections32all, exportsyms=li.exportsyms) + """
     _reloc_min_align = 0x%x ;
     zonelow_base = 0x%x ;
     final_varlow_start = 0x%x ;
@@ -621,7 +618,12 @@ def main():
     sections = gc(info16, info32seg, info32flat)
 
     # Separate 32bit flat into runtime and init parts
-    findInit(sections)
+    genreloc = '_reloc_abs_start' in info32flat[1]
+    if genreloc:
+        findInit(sections)
+    else:
+        for section in sections:
+            section.category = section.fileid
 
     # Note "low memory" and "fseg memory" parts
     for section in getSectionsPrefix(sections, '.data.varlow.'):
@@ -630,17 +632,21 @@ def main():
         section.category = '32fseg'
 
     # Determine the final memory locations of each kept section.
-    genreloc = '_reloc_abs_start' in info32flat[1]
-    li = doLayout(sections, genreloc)
+    li = doLayout(sections)
+    li.genreloc = genreloc
 
     # Exported symbols
-    exportsyms = [symbol for symbol in info16[1].values()
-                 if (symbol.section is not None
-                     and '.export.' in symbol.section.name
-                     and symbol.name != symbol.section.name)]
+    li.exportsyms = [symbol for symbol in info16[1].values()
+                     if (symbol.section is not None
+                         and '.export.' in symbol.section.name
+                         and symbol.name != symbol.section.name)]
+    li.varlowsyms = [symbol for symbol in info32flat[1].values()
+                     if (symbol.section is not None
+                         and '.data.varlow.' in symbol.section.name
+                         and symbol.name != symbol.section.name)]
 
     # Write out linker script files.
-    writeLinkerScripts(li, exportsyms, genreloc, out16, out32seg, out32flat)
+    writeLinkerScripts(li, out16, out32seg, out32flat)
 
 if __name__ == '__main__':
     main()
-- 
1.7.11.7




More information about the SeaBIOS mailing list