arm: Add app data section alignment constraints
This patch adds application data section alignment constraints
to match the region definition requirements for ARM MPUs. Most MPUs
require a minimum of 32 bytes of alignment for any regions, but some
require power of two alignment to the size of a region.
This requires that the linker align the application data section to
the size of the section. This requires a linker pass to determine the
size. Once this is accomplished the correct value is added to a linker
include file that is utilized in subsequent linker operations.
Signed-off-by: Andy Gross <andy.gross@linaro.org>
diff --git a/scripts/gen_alignment_script.py b/scripts/gen_alignment_script.py
new file mode 100755
index 0000000..aaaa1f4
--- /dev/null
+++ b/scripts/gen_alignment_script.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python3
+#
+# Copyright (c) 2017 Linaro Limited
+#
+# SPDX-License-Identifier: Apache-2.0
+
+import sys
+import argparse
+import pprint
+import os
+import struct
+from distutils.version import LooseVersion
+
+import elftools
+from elftools.elf.elffile import ELFFile
+from elftools.dwarf import descriptions
+from elftools.elf.sections import SymbolTableSection
+
+if LooseVersion(elftools.__version__) < LooseVersion('0.24'):
+ sys.stderr.write("pyelftools is out of date, need version 0.24 or later\n")
+ sys.exit(1)
+
+
+def get_symbols(obj):
+ for section in obj.iter_sections():
+ if isinstance(section, SymbolTableSection):
+ return {sym.name: sym.entry.st_value
+ for sym in section.iter_symbols()}
+
+ raise LookupError("Could not find symbol table")
+
+
+def parse_args():
+ global args
+
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter)
+
+ parser.add_argument(
+ "-k", "--kernel", required=True,
+ help="Input zephyr ELF binary")
+ parser.add_argument(
+ "-o", "--output", required=True,
+ help="Output linker file")
+ parser.add_argument(
+ "-v", "--verbose", action="store_true",
+ help="Print extra debugging information")
+ args = parser.parse_args()
+
+
+def main():
+ parse_args()
+
+ bit_len = None
+
+ with open(args.kernel, "rb") as fp:
+ elf = ELFFile(fp)
+ args.little_endian = elf.little_endian
+ syms = get_symbols(elf)
+
+ app_ram_size = syms['__app_last_address_used'] - \
+ syms['__app_ram_start']
+ bit_len = app_ram_size.bit_length()
+
+ if bit_len:
+ align_size = 1 << bit_len
+ else:
+ align_size = 32
+
+ with open(args.output, "w") as fp:
+ fp.write("/***********************************************\n")
+ fp.write(" * Generated file, do not modify\n")
+ fp.write(" **********************************************/\n")
+ fp.write("_app_data_align = " + str(align_size) + ";\n")
+ fp.write(". = ALIGN(_app_data_align);\n")
+
+if __name__ == "__main__":
+ main()