Add a build check to verify certain variables are only reachable via the 32bit "init" code. This can be used as a mechanism to enforce certain data (and code that accesses that data) as only available during POST.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/types.h | 4 ++++ tools/layoutrom.py | 18 +++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/src/types.h b/src/types.h index 03104a2..84582ac 100644 --- a/src/types.h +++ b/src/types.h @@ -59,6 +59,8 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; # define VARLOW __section(".discard.varlow." UNIQSEC) __VISIBLE __weak // Designate a variable as visible and located in the f-segment. # define VARFSEG __section(".discard.varfseg." UNIQSEC) __VISIBLE __weak +// Verify a variable is only accessable via 32bit "init" functions +# define VARVERIFY32INIT __section(".discard.varinit." UNIQSEC) // Designate top-level assembler as 16bit only. # define ASM16(code) __ASM(code) // Designate top-level assembler as 32bit flat only. @@ -77,6 +79,7 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; # define VAR32SEG __section(".data32seg." UNIQSEC) # define VARLOW __section(".discard.varlow." UNIQSEC) __VISIBLE __weak # define VARFSEG __section(".discard.varfseg." UNIQSEC) __VISIBLE __weak +# define VARVERIFY32INIT __section(".discard.varinit." UNIQSEC) # define ASM16(code) # define ASM32FLAT(code) # define ASSERT16() __force_link_error__only_in_16bit() @@ -92,6 +95,7 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; # define VAR32SEG __section(".discard.var32seg." UNIQSEC) # define VARLOW __section(".data.varlow." UNIQSEC) __VISIBLE __weak # define VARFSEG __section(".data.varfseg." UNIQSEC) __VISIBLE +# define VARVERIFY32INIT __section(".data.varinit." UNIQSEC) # define ASM16(code) # define ASM32FLAT(code) __ASM(code) # define ASSERT16() __force_link_error__only_in_16bit() diff --git a/tools/layoutrom.py b/tools/layoutrom.py index e8b32a7..20b9716 100755 --- a/tools/layoutrom.py +++ b/tools/layoutrom.py @@ -432,16 +432,20 @@ PHDRS # Detection of init code ######################################################################
-def markRuntime(section, sections): +def markRuntime(section, sections, chain=[]): if (section is None or not section.keep or section.category is not None or '.init.' in section.name or section.fileid != '32flat'): return + if '.data.varinit.' in section.name: + print "ERROR: %s is VARVERIFY32INIT but used from %s" % ( + section.name, chain) + sys.exit(1) section.category = '32flat' # Recursively mark all sections this section points to for reloc in section.relocs: - markRuntime(reloc.symbol.section, sections) + markRuntime(reloc.symbol.section, sections, chain + [section.name])
-def findInit(sections): +def findInit(sections, genreloc): # Recursively find and mark all "runtime" sections. for section in sections: if ('.data.varlow.' in section.name or '.data.varfseg.' in section.name @@ -450,7 +454,7 @@ def findInit(sections): for section in sections: if section.category is not None: continue - if section.fileid == '32flat': + if section.fileid == '32flat' and genreloc: section.category = '32init' else: section.category = section.fileid @@ -635,11 +639,7 @@ def main():
# Separate 32bit flat into runtime and init parts genreloc = '_reloc_abs_start' in info32flat[1] - if genreloc: - findInit(sections) - else: - for section in sections: - section.category = section.fileid + findInit(sections, genreloc)
# Note "low memory" and "fseg memory" parts for section in getSectionsPrefix(sections, '.data.varlow.'):