Add optional build flag to check effective image size
Some targets will have a static-size memory carveout dedicated
to the hypervisor. In those cases, we should assert that the Hafnium
image does fit into the allocated memory. Add this as a toolchain arg
'plat_max_image_size' and add a new assertion into check_elf.py. This
way the build will fail if the image is too big.
Change-Id: Ib7311c49b185685aef167988c9aa2416822a6f28
diff --git a/build/image/check_elf.py b/build/image/check_elf.py
index 1dc0cec..a949e72 100644
--- a/build/image/check_elf.py
+++ b/build/image/check_elf.py
@@ -30,12 +30,19 @@
HF_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
CLANG_ROOT = os.path.join(HF_ROOT, "prebuilts", "linux-x64", "clang")
OBJDUMP = os.path.join(CLANG_ROOT, "bin", "llvm-objdump")
+NM = os.path.join(CLANG_ROOT, "bin", "llvm-nm")
-def check_eret_speculation_barrier(objdump_stdout):
+def check_eret_speculation_barrier(args):
"""
Some ARM64 CPUs speculatively execute instructions after ERET.
Check that every ERET is followed by DSB NSH and ISB.
"""
+
+ objdump_stdout = subprocess\
+ .check_output([ OBJDUMP, "-d", args.input_elf ])\
+ .decode("utf-8")\
+ .splitlines()
+
found_eret = False
STATE_DEFAULT = 1
@@ -68,19 +75,59 @@
if not found_eret:
raise Exception("Could not find any ERET instructions")
+def check_max_image_size(args):
+ """
+ Check that the ELF's effective image size does not exceed maximum
+ allowed image size, if specified in command-line arguments.
+ """
+
+ if args.max_image_size <= 0:
+ return
+
+ nm_stdout = subprocess\
+ .check_output([ NM, args.input_elf ])\
+ .decode("utf-8")\
+ .splitlines()
+
+ COLUMN_COUNT = 3
+ COLUMN_IDX_VALUE = 0
+ COLUMN_IDX_TYPE = 1
+ COLUMN_IDX_NAME = 2
+
+ image_size = None
+ for line in nm_stdout:
+ line = line.split()
+ if len(line) != COLUMN_COUNT:
+ raise Exception(
+ "Unexpected number of columns in NM output")
+
+ if line[COLUMN_IDX_NAME] == "image_size":
+ if line[COLUMN_IDX_TYPE] != "A":
+ raise Exception(
+ "Unexpected type of image_size symbol")
+ image_size = int(line[COLUMN_IDX_VALUE], 16)
+ break
+
+ if image_size is None:
+ raise Exception("Could not find value of image_size symbol")
+ elif image_size > args.max_image_size:
+ raise Exception(
+ "Image size exceeds maximum allowed image size " +
+ "({}B > {}B)".format(image_size, args.max_image_size))
+
def Main():
parser = argparse.ArgumentParser()
parser.add_argument("input_elf",
help="ELF file to analyze")
parser.add_argument("stamp_file",
help="file to be touched if successful")
+ parser.add_argument("--max-image-size",
+ required=False, type=int, default=0,
+ help="maximum allowed image size in bytes")
args = parser.parse_args()
- objdump_stdout = subprocess.check_output([
- OBJDUMP, "-d", args.input_elf ])
- objdump_stdout = objdump_stdout.decode("utf-8").splitlines()
-
- check_eret_speculation_barrier(objdump_stdout)
+ check_eret_speculation_barrier(args)
+ check_max_image_size(args)
# Touch `stamp_file`.
with open(args.stamp_file, "w"):