From 0bd7d1f7f03d086a0789caa8e007cf15068c689c Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 16 Dec 2019 21:53:43 +1100 Subject: [PATCH] py/persistentcode: Move loading of rodata/bss to before obj/raw-code. This makes the loading of viper-code-with-relocations a bit neater and easier to understand, by treating the rodata/bss like a special object to be loaded into the constant table (which is how it behaves). --- py/persistentcode.c | 39 +++++++++++++++++++++++++++------------ tools/mpy_ld.py | 16 +--------------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/py/persistentcode.c b/py/persistentcode.c index 8bf46202b..7a8a94b5a 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -438,9 +438,18 @@ STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader, qstr_window_t *qw) { // Allocate constant table size_t n_alloc = prelude.n_pos_args + prelude.n_kwonly_args + n_obj + n_raw_code; + #if MICROPY_EMIT_MACHINE_CODE if (kind != MP_CODE_BYTECODE) { ++n_alloc; // additional entry for mp_fun_table + if (prelude.scope_flags & MP_SCOPE_FLAG_VIPERRODATA) { + ++n_alloc; // additional entry for rodata + } + if (prelude.scope_flags & MP_SCOPE_FLAG_VIPERBSS) { + ++n_alloc; // additional entry for BSS + } } + #endif + const_table = m_new(mp_uint_t, n_alloc); mp_uint_t *ct = const_table; @@ -454,6 +463,21 @@ STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader, qstr_window_t *qw) { if (kind != MP_CODE_BYTECODE) { // Populate mp_fun_table entry *ct++ = (mp_uint_t)(uintptr_t)&mp_fun_table; + + // Allocate and load rodata if needed + if (prelude.scope_flags & MP_SCOPE_FLAG_VIPERRODATA) { + size_t size = read_uint(reader, NULL); + uint8_t *rodata = m_new(uint8_t, size); + read_bytes(reader, rodata, size); + *ct++ = (uintptr_t)rodata; + } + + // Allocate BSS if needed + if (prelude.scope_flags & MP_SCOPE_FLAG_VIPERBSS) { + size_t size = read_uint(reader, NULL); + uint8_t *bss = m_new0(uint8_t, size); + *ct++ = (uintptr_t)bss; + } } #endif @@ -469,6 +493,7 @@ STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader, qstr_window_t *qw) { // Create raw_code and return it mp_raw_code_t *rc = mp_emit_glue_new_raw_code(); if (kind == MP_CODE_BYTECODE) { + // Assign bytecode to raw code object mp_emit_glue_assign_bytecode(rc, fun_data, #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS fun_data_len, @@ -481,18 +506,7 @@ STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader, qstr_window_t *qw) { #if MICROPY_EMIT_MACHINE_CODE } else { - mp_uint_t *ct = &const_table[1]; - if (prelude.scope_flags & MP_SCOPE_FLAG_VIPERRODATA) { - size_t size = read_uint(reader, NULL); - uint8_t *rodata = m_new(uint8_t, size); - read_bytes(reader, rodata, size); - *ct++ = (uintptr_t)rodata; - } - if (prelude.scope_flags & MP_SCOPE_FLAG_VIPERBSS) { - size_t size = read_uint(reader, NULL); - uint8_t *bss = m_new0(uint8_t, size); - *ct++ = (uintptr_t)bss; - } + // Relocate and commit code to executable address space reloc_info_t ri = {reader, const_table}; #if defined(MP_PLAT_COMMIT_EXEC) void *opt_ri = (prelude.scope_flags & MP_SCOPE_FLAG_VIPERRELOC) ? &ri : NULL; @@ -503,6 +517,7 @@ STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader, qstr_window_t *qw) { } #endif + // Assign native code to raw code object mp_emit_glue_assign_native(rc, kind, fun_data, fun_data_len, const_table, #if MICROPY_PERSISTENT_CODE_SAVE diff --git a/tools/mpy_ld.py b/tools/mpy_ld.py index ec600f967..31c391299 100755 --- a/tools/mpy_ld.py +++ b/tools/mpy_ld.py @@ -765,14 +765,6 @@ class MPYOutput: self.write_uint(len(s) << 1) self.write_bytes(s) - def write_obj(self, o): - if o is Ellipsis: - self.write_bytes(b'e') - return - else: - # Other Python types not implemented - assert 0 - def write_reloc(self, base, offset, dest, n): need_offset = not (base == self.prev_base and offset == self.prev_offset + 1) self.prev_offset = offset + n - 1 @@ -845,17 +837,11 @@ def build_mpy(env, entry_offset, fmpy, native_qstr_vals, native_qstr_objs): out.write_uint(scope_flags) # MPY: n_obj - out.write_uint(bool(len(env.full_rodata)) + bool(len(env.full_bss))) + out.write_uint(0) # MPY: n_raw_code out.write_uint(0) - # MPY: optional bytes object with rodata - if len(env.full_rodata): - out.write_obj(Ellipsis) - if len(env.full_bss): - out.write_obj(Ellipsis) - # MPY: rodata and/or bss if len(env.full_rodata): rodata_const_table_idx = 1