new file mode 100755
@@ -0,0 +1,109 @@
+#!/usr/bin/python
+#
+# binfmt check script
+#
+# Copyright 2014 Linaro
+#
+# Authors:
+# Alex Bennee <alex.bennee@linaro.org>
+#
+# This work is licensed under the terms of the GNU GPL, version 2. See
+# the COPYING file in the top-level directory.
+
+import os
+import re
+import binascii
+
+re_int = re.compile(r"interpreter (.+)$")
+re_off = re.compile(r"offset (\d+)$")
+re_magic = re.compile(r"magic ([\dabcdef]+)")
+re_mask = re.compile(r"mask ([\dabcdef]+)")
+
+# argparse is only available in Python >= 2.7
+from optparse import OptionParser
+parser = OptionParser()
+
+# list of binfmts
+binfmts = []
+
+
+def read_binfmt_spec(f):
+ bfmt = {}
+ with open(f) as fd:
+ content = fd.readlines()
+ for l in content:
+ m = re_int.match(l)
+ if m:
+ bfmt["interpreter"] = m.group(1)
+ m = re_off.match(l)
+ if m:
+ bfmt["offset"] = int(m.group(1))
+ m = re_magic.match(l)
+ if m:
+ bfmt["magic"] = binascii.unhexlify(m.group(1))
+ m = re_mask.match(l)
+ if m:
+ bfmt["mask"] = binascii.unhexlify(m.group(1))
+ print "loaded: %s" % bfmt
+ binfmts.append(bfmt)
+
+
+def load_binfmt_masks():
+ binfmt_dir = "/proc/sys/fs/binfmt_misc"
+ files = os.listdir(binfmt_dir)
+ for f in files:
+ if not f.startswith("status"):
+ fp = "%s/%s" % (binfmt_dir, f)
+ if os.access(fp, os.R_OK):
+ read_binfmt_spec(fp)
+
+
+def check_file_against_binfmt(fmt, f):
+ """
+ Check if a file will match a given binfmt mask
+ """
+ print "checking %s" % (f)
+ nbytes = len(fmt["magic"])
+
+ fd = open(f, "rb")
+ fd.seek(fmt["offset"])
+ header = fd.read(nbytes)
+ magic = fmt["magic"]
+ try:
+ mask = fmt["mask"]
+ except:
+ # TODO, make full mask
+ return
+
+ values = zip(mask, magic, header)
+ failed = False
+ pos = 0
+ for m, g, h in values:
+ mask = ord(m)
+ bits_to_check = ord(h) & mask
+ magic = ord(g)
+ if not bits_to_check == magic:
+ print "failed at %d (%x, %x, %x)" % (pos, mask, magic, bits_to_check)
+ failed = True
+ break
+ pos += 1
+ return not failed
+
+
+def check_file_against_all_binfmts(f):
+ """
+ Check a file against the binfmt masks
+ """
+ path = os.path.abspath(f)
+ print "file is %s" % (path)
+ for b in binfmts:
+ if check_file_against_binfmt(b, path):
+ print "%s will use %s" % (path, b["interpreter"])
+ break
+
+
+if __name__ == "__main__":
+ (opts, args) = parser.parse_args()
+ load_binfmt_masks()
+ for f in args:
+ check_file_against_all_binfmts(f)
From: Alex Bennée <alex.bennee@linaro.org> This script allows you to check if a given binary will match against any of the currently registered binfmts on the system. --- v2 (ajb): - cleaned up whitespace and checkpatch fixes --- scripts/qemu-binfmt-check.py | 109 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100755 scripts/qemu-binfmt-check.py