From: Kevin O'Connor Date: Fri, 1 Jan 2010 17:46:54 +0000 (-0500) Subject: Force a link error if a function is used from the wrong code chunk. X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=seabios.git;a=commitdiff_plain;h=fdca41825dd5ed2f2d1ced2f6ecbd9077c4f6b86 Force a link error if a function is used from the wrong code chunk. Force functions intended for other code segments to be discarded during link - this will cause a link error if it used. Clean up rom layout code to ensure discarded sections are not used. --- diff --git a/src/types.h b/src/types.h index b2100c1..59999c5 100644 --- a/src/types.h +++ b/src/types.h @@ -35,6 +35,7 @@ union u64_u32_u { #define __noreturn __attribute__((noreturn)) extern void __force_link_error__only_in_32bit_flat() __noreturn; +extern void __force_link_error__only_in_32bit_segmented() __noreturn; extern void __force_link_error__only_in_16bit() __noreturn; #define __ASM(code) asm(".section .text.asm." UNIQSEC "\n\t" code) @@ -43,9 +44,9 @@ extern void __force_link_error__only_in_16bit() __noreturn; // Notes a function as externally visible in the 16bit code chunk. # define VISIBLE16 __VISIBLE // Notes a function as externally visible in the 32bit flat code chunk. -# define VISIBLE32FLAT +# define VISIBLE32FLAT __section(".discard.func32flat." UNIQSEC) noinline // Notes a function as externally visible in the 32bit segmented code chunk. -# define VISIBLE32SEG +# define VISIBLE32SEG __section(".discard.func32seg." UNIQSEC) noinline // Designate a variable as (only) visible to 16bit code. # define VAR16 __section(".data16." UNIQSEC) // Designate a variable as visible to 16bit, 32bit, and assembler code. @@ -63,11 +64,12 @@ extern void __force_link_error__only_in_16bit() __noreturn; // Designate top-level assembler as 32bit flat only. # define ASM32FLAT(code) // Compile time check for a given mode. -#define ASSERT16() do { } while (0) -#define ASSERT32FLAT() __force_link_error__only_in_32bit_flat() +# define ASSERT16() do { } while (0) +# define ASSERT32SEG() __force_link_error__only_in_32bit_segmented() +# define ASSERT32FLAT() __force_link_error__only_in_32bit_flat() #elif MODESEGMENT == 1 -# define VISIBLE16 -# define VISIBLE32FLAT +# define VISIBLE16 __section(".discard.func16." UNIQSEC) noinline +# define VISIBLE32FLAT __section(".discard.func32flat." UNIQSEC) noinline # define VISIBLE32SEG __VISIBLE # define VAR16 __section(".discard.var16." UNIQSEC) # define VAR16VISIBLE VAR16 __VISIBLE __weak @@ -77,12 +79,13 @@ extern void __force_link_error__only_in_16bit() __noreturn; # define VAR32FLATVISIBLE __section(".discard.var32flat." UNIQSEC) __VISIBLE __weak # define ASM16(code) # define ASM32FLAT(code) -#define ASSERT16() __force_link_error__only_in_16bit() -#define ASSERT32FLAT() __force_link_error__only_in_32bit_flat() +# define ASSERT16() __force_link_error__only_in_16bit() +# define ASSERT32SEG() do { } while (0) +# define ASSERT32FLAT() __force_link_error__only_in_32bit_flat() #else -# define VISIBLE16 +# define VISIBLE16 __section(".discard.func16." UNIQSEC) noinline # define VISIBLE32FLAT __VISIBLE -# define VISIBLE32SEG +# define VISIBLE32SEG __section(".discard.func32seg." UNIQSEC) noinline # define VAR16 __section(".discard.var16." UNIQSEC) # define VAR16VISIBLE VAR16 __VISIBLE __weak # define VAR16EXPORT VAR16VISIBLE @@ -91,8 +94,9 @@ extern void __force_link_error__only_in_16bit() __noreturn; # define VAR32FLATVISIBLE __VISIBLE # define ASM16(code) # define ASM32FLAT(code) __ASM(code) -#define ASSERT16() __force_link_error__only_in_16bit() -#define ASSERT32FLAT() do { } while (0) +# define ASSERT16() __force_link_error__only_in_16bit() +# define ASSERT32SEG() __force_link_error__only_in_32bit_segmented() +# define ASSERT32FLAT() do { } while (0) #endif #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) diff --git a/tools/layoutrom.py b/tools/layoutrom.py index 3113407..d0ca9a6 100755 --- a/tools/layoutrom.py +++ b/tools/layoutrom.py @@ -274,6 +274,14 @@ def getSectionsList(info, names): out.append(i) return out +# Find and keep the section associated with a symbol (if available). +def keepsymbol(symbol, infos, pos): + addr, section = infos[pos][1].get(symbol, (None, None)) + if section is None or '*' in section or section[:9] == '.discard.': + return -1 + keepsection(section, infos, pos) + return 0 + # Note required section, and recursively set all referenced sections # as required. def keepsection(name, infos, pos=0): @@ -286,21 +294,16 @@ def keepsection(name, infos, pos=0): return # Keep all sections that this section points to for symbol in relocs: - addr, section = infos[pos][1].get(symbol, (None, None)) - if (section is not None and '*' not in section - and section[:9] != '.discard.'): - keepsection(section, infos, pos) + ret = keepsymbol(symbol, infos, pos) + if not ret: continue # Not in primary sections - it may be a cross 16/32 reference - newpos = (pos+1)%3 - addr, section = infos[newpos][1].get(symbol, (None, None)) - if section is not None and '*' not in section: - keepsection(section, infos, newpos) + ret = keepsymbol(symbol, infos, (pos+1)%3) + if not ret: + continue + ret = keepsymbol(symbol, infos, (pos+2)%3) + if not ret: continue - newpos = (pos+2)%3 - addr, section = infos[(pos+2)%3][1].get(symbol, (None, None)) - if section is not None and '*' not in section: - keepsection(section, infos, newpos) # Determine which sections are actually referenced and need to be # placed into the output file.