aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2010-01-01 12:46:54 -0500
committerKevin O'Connor <kevin@koconnor.net>2010-01-01 13:05:23 -0500
commitfdca41825dd5ed2f2d1ced2f6ecbd9077c4f6b86 (patch)
tree5db7205e68e436bb0541c8a0b6cc94f815e4be1f
parentdad41d9f217cef9dc6c404d409f6c27b0454b73f (diff)
downloadseabios-hppa-fdca41825dd5ed2f2d1ced2f6ecbd9077c4f6b86.zip
seabios-hppa-fdca41825dd5ed2f2d1ced2f6ecbd9077c4f6b86.tar.gz
seabios-hppa-fdca41825dd5ed2f2d1ced2f6ecbd9077c4f6b86.tar.bz2
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.
-rw-r--r--src/types.h28
-rwxr-xr-xtools/layoutrom.py27
2 files changed, 31 insertions, 24 deletions
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.