From faf3d3e9e93a71b3947bf563e4ffe13cbd053cb8 Mon Sep 17 00:00:00 2001
From: Damien George <damien.p.george@gmail.com>
Date: Tue, 4 Jun 2019 22:13:32 +1000
Subject: [PATCH] tools/mpy-tool.py: Fix linking qstrs in native code, and
 multiple files.

Fixes errors in the tool when 1) linking qstrs in native ARM-M code; 2)
freezing multiple files some of which use native code and some which don't.

Fixes issue #4829.
---
 tools/mpy-tool.py | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py
index c8216bb60..db6fe2383 100755
--- a/tools/mpy-tool.py
+++ b/tools/mpy-tool.py
@@ -4,7 +4,7 @@
 #
 # The MIT License (MIT)
 #
-# Copyright (c) 2016 Damien P. George
+# Copyright (c) 2016-2019 Damien P. George
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy
 # of this software and associated documentation files (the "Software"), to deal
@@ -479,18 +479,23 @@ class RawCodeNative(RawCode):
 
     def _link_qstr(self, pc, kind, qst):
         if kind == 0:
+            # Generic 16-bit link
             print('    %s & 0xff, %s >> 8,' % (qst, qst))
         else:
-            if kind == 2:
+            # Architecture-specific link
+            is_obj = kind == 2
+            if is_obj:
                 qst = '((uintptr_t)MP_OBJ_NEW_QSTR(%s))' % qst
             if config.native_arch in (MP_NATIVE_ARCH_X86, MP_NATIVE_ARCH_X64):
                 print('    %s & 0xff, %s >> 8, 0, 0,' % (qst, qst))
             elif MP_NATIVE_ARCH_ARMV6M <= config.native_arch <= MP_NATIVE_ARCH_ARMV7EMDP:
                 if is_obj:
-                    self._asm_thumb_rewrite_mov(i, qst)
-                    self._asm_thumb_rewrite_mov(i + 4, '(%s >> 16)' % qst)
+                    # qstr object, movw and movt
+                    self._asm_thumb_rewrite_mov(pc, qst)
+                    self._asm_thumb_rewrite_mov(pc + 4, '(%s >> 16)' % qst)
                 else:
-                    self._asm_thumb_rewrite_mov(i, qst)
+                    # qstr number, movw instruction
+                    self._asm_thumb_rewrite_mov(pc, qst)
             else:
                 assert 0
 
@@ -663,7 +668,7 @@ def read_raw_code(f, qstr_win):
             # load qstr link table
             n_qstr_link = read_uint(f)
             for _ in range(n_qstr_link):
-                off = read_uint(f, qstr_win)
+                off = read_uint(f)
                 qst = read_qstr(f, qstr_win)
                 qstr_links.append((off >> 2, off & 3, qst))
 
@@ -714,7 +719,12 @@ def read_mpy(filename):
         qw_size = read_uint(f)
         config.MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE = (feature_byte & 1) != 0
         config.MICROPY_PY_BUILTINS_STR_UNICODE = (feature_byte & 2) != 0
-        config.native_arch = feature_byte >> 2
+        mpy_native_arch = feature_byte >> 2
+        if mpy_native_arch != MP_NATIVE_ARCH_NONE:
+            if config.native_arch == MP_NATIVE_ARCH_NONE:
+                config.native_arch = mpy_native_arch
+            elif config.native_arch != mpy_native_arch:
+                raise Exception('native architecture mismatch')
         config.mp_small_int_bits = header[3]
         qstr_win = QStrWindow(qw_size)
         return read_raw_code(f, qstr_win)
@@ -838,6 +848,7 @@ def main():
         'mpz':config.MICROPY_LONGINT_IMPL_MPZ,
     }[args.mlongint_impl]
     config.MPZ_DIG_SIZE = args.mmpz_dig_size
+    config.native_arch = MP_NATIVE_ARCH_NONE
 
     # set config values for qstrs, and get the existing base set of qstrs
     if args.qstr_header:
-- 
GitLab