py/persistentcode: Remove remaining native qstr linking support.
Support for architecture-specific qstr linking was removed ind4d53e9e11, where native code was changed to access qstr values via qstr_table. The only remaining use for the special qstr link table in persistentcode.c is to support native module written in C, linked via mpy_ld.py. But native modules can also use the standard module-level qstr_table (and obj_table) which was introduced in the .mpy file reworking inf2040bfc7e. This commit removes the remaining native qstr liking support in persistentcode.c's load_raw_code function, and adds two new relocation options for constants.qstr_table and constants.obj_table. mpy_ld.py is updated to use these relocations options instead of the native qstr link table. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
@@ -36,6 +36,8 @@ import makeqstrdata as qstrutil
|
||||
|
||||
# MicroPython constants
|
||||
MPY_VERSION = 6
|
||||
MP_CODE_BYTECODE = 2
|
||||
MP_CODE_NATIVE_VIPER = 4
|
||||
MP_NATIVE_ARCH_X86 = 1
|
||||
MP_NATIVE_ARCH_X64 = 2
|
||||
MP_NATIVE_ARCH_ARMV6M = 4
|
||||
@@ -44,8 +46,7 @@ MP_NATIVE_ARCH_ARMV7EMSP = 7
|
||||
MP_NATIVE_ARCH_ARMV7EMDP = 8
|
||||
MP_NATIVE_ARCH_XTENSA = 9
|
||||
MP_NATIVE_ARCH_XTENSAWIN = 10
|
||||
MP_CODE_BYTECODE = 2
|
||||
MP_CODE_NATIVE_VIPER = 4
|
||||
MP_PERSISTENT_OBJ_STR = 5
|
||||
MP_SCOPE_FLAG_VIPERRELOC = 0x10
|
||||
MP_SCOPE_FLAG_VIPERRODATA = 0x20
|
||||
MP_SCOPE_FLAG_VIPERBSS = 0x40
|
||||
@@ -110,21 +111,20 @@ def asm_jump_xtensa(entry):
|
||||
|
||||
|
||||
class ArchData:
|
||||
def __init__(self, name, mpy_feature, qstr_entry_size, word_size, arch_got, asm_jump):
|
||||
def __init__(self, name, mpy_feature, word_size, arch_got, asm_jump, *, separate_rodata=False):
|
||||
self.name = name
|
||||
self.mpy_feature = mpy_feature
|
||||
self.qstr_entry_size = qstr_entry_size
|
||||
self.qstr_entry_size = 2
|
||||
self.word_size = word_size
|
||||
self.arch_got = arch_got
|
||||
self.asm_jump = asm_jump
|
||||
self.separate_rodata = name == "EM_XTENSA" and qstr_entry_size == 4
|
||||
self.separate_rodata = separate_rodata
|
||||
|
||||
|
||||
ARCH_DATA = {
|
||||
"x86": ArchData(
|
||||
"EM_386",
|
||||
MP_NATIVE_ARCH_X86 << 2,
|
||||
2,
|
||||
4,
|
||||
(R_386_PC32, R_386_GOT32, R_386_GOT32X),
|
||||
asm_jump_x86,
|
||||
@@ -132,7 +132,6 @@ ARCH_DATA = {
|
||||
"x64": ArchData(
|
||||
"EM_X86_64",
|
||||
MP_NATIVE_ARCH_X64 << 2,
|
||||
2,
|
||||
8,
|
||||
(R_X86_64_GOTPCREL, R_X86_64_REX_GOTPCRELX),
|
||||
asm_jump_x86,
|
||||
@@ -140,7 +139,6 @@ ARCH_DATA = {
|
||||
"armv6m": ArchData(
|
||||
"EM_ARM",
|
||||
MP_NATIVE_ARCH_ARMV6M << 2,
|
||||
2,
|
||||
4,
|
||||
(R_ARM_GOT_BREL,),
|
||||
asm_jump_thumb,
|
||||
@@ -148,7 +146,6 @@ ARCH_DATA = {
|
||||
"armv7m": ArchData(
|
||||
"EM_ARM",
|
||||
MP_NATIVE_ARCH_ARMV7M << 2,
|
||||
2,
|
||||
4,
|
||||
(R_ARM_GOT_BREL,),
|
||||
asm_jump_thumb2,
|
||||
@@ -156,7 +153,6 @@ ARCH_DATA = {
|
||||
"armv7emsp": ArchData(
|
||||
"EM_ARM",
|
||||
MP_NATIVE_ARCH_ARMV7EMSP << 2,
|
||||
2,
|
||||
4,
|
||||
(R_ARM_GOT_BREL,),
|
||||
asm_jump_thumb2,
|
||||
@@ -164,7 +160,6 @@ ARCH_DATA = {
|
||||
"armv7emdp": ArchData(
|
||||
"EM_ARM",
|
||||
MP_NATIVE_ARCH_ARMV7EMDP << 2,
|
||||
2,
|
||||
4,
|
||||
(R_ARM_GOT_BREL,),
|
||||
asm_jump_thumb2,
|
||||
@@ -172,7 +167,6 @@ ARCH_DATA = {
|
||||
"xtensa": ArchData(
|
||||
"EM_XTENSA",
|
||||
MP_NATIVE_ARCH_XTENSA << 2,
|
||||
2,
|
||||
4,
|
||||
(R_XTENSA_32, R_XTENSA_PLT),
|
||||
asm_jump_xtensa,
|
||||
@@ -181,9 +175,9 @@ ARCH_DATA = {
|
||||
"EM_XTENSA",
|
||||
MP_NATIVE_ARCH_XTENSAWIN << 2,
|
||||
4,
|
||||
4,
|
||||
(R_XTENSA_32, R_XTENSA_PLT),
|
||||
asm_jump_xtensa,
|
||||
separate_rodata=True,
|
||||
),
|
||||
}
|
||||
|
||||
@@ -435,8 +429,8 @@ def populate_got(env):
|
||||
|
||||
# Create a relocation for each GOT entry
|
||||
for got_entry in got_list:
|
||||
if got_entry.name == "mp_fun_table":
|
||||
dest = "mp_fun_table"
|
||||
if got_entry.name in ("mp_native_qstr_table", "mp_native_obj_table", "mp_fun_table"):
|
||||
dest = got_entry.name
|
||||
elif got_entry.name.startswith("mp_fun_table+0x"):
|
||||
dest = int(got_entry.name.split("+")[1], 16) // env.arch.word_size
|
||||
elif got_entry.sec_name.startswith(".text"):
|
||||
@@ -754,19 +748,19 @@ def link_objects(env, native_qstr_vals_len, native_qstr_objs_len):
|
||||
env.lit_section = Section("LIT", bytearray(lit_size), env.arch.word_size)
|
||||
env.sections.insert(1, env.lit_section)
|
||||
|
||||
# Create section to contain mp_native_qstr_val_table
|
||||
env.qstr_val_section = Section(
|
||||
".text.QSTR_VAL",
|
||||
# Create section to contain mp_native_qstr_table
|
||||
env.qstr_table_section = Section(
|
||||
".external.qstr_table",
|
||||
bytearray(native_qstr_vals_len * env.arch.qstr_entry_size),
|
||||
env.arch.qstr_entry_size,
|
||||
)
|
||||
env.sections.append(env.qstr_val_section)
|
||||
|
||||
# Create section to contain mp_native_qstr_obj_table
|
||||
env.qstr_obj_section = Section(
|
||||
".text.QSTR_OBJ", bytearray(native_qstr_objs_len * env.arch.word_size), env.arch.word_size
|
||||
# Create section to contain mp_native_obj_table
|
||||
env.obj_table_section = Section(
|
||||
".external.obj_table",
|
||||
bytearray(native_qstr_objs_len * env.arch.word_size),
|
||||
env.arch.word_size,
|
||||
)
|
||||
env.sections.append(env.qstr_obj_section)
|
||||
|
||||
# Resolve unknown symbols
|
||||
mp_fun_table_sec = Section(".external.mp_fun_table", b"", 0)
|
||||
@@ -796,10 +790,10 @@ def link_objects(env, native_qstr_vals_len, native_qstr_objs_len):
|
||||
pass
|
||||
elif sym.name == "mp_fun_table":
|
||||
sym.section = Section(".external", b"", 0)
|
||||
elif sym.name == "mp_native_qstr_val_table":
|
||||
sym.section = env.qstr_val_section
|
||||
elif sym.name == "mp_native_qstr_obj_table":
|
||||
sym.section = env.qstr_obj_section
|
||||
elif sym.name == "mp_native_qstr_table":
|
||||
sym.section = env.qstr_table_section
|
||||
elif sym.name == "mp_native_obj_table":
|
||||
sym.section = env.obj_table_section
|
||||
elif sym.name in env.known_syms:
|
||||
sym.resolved = env.known_syms[sym.name]
|
||||
else:
|
||||
@@ -923,13 +917,21 @@ def build_mpy(env, entry_offset, fmpy, native_qstr_vals, native_qstr_objs):
|
||||
out.write_bytes(bytearray([ord("M"), MPY_VERSION, env.arch.mpy_feature, MP_SMALL_INT_BITS]))
|
||||
|
||||
# MPY: n_qstr
|
||||
out.write_uint(1)
|
||||
out.write_uint(1 + len(native_qstr_vals))
|
||||
|
||||
# MPY: n_obj
|
||||
out.write_uint(0)
|
||||
out.write_uint(len(native_qstr_objs))
|
||||
|
||||
# MPY: qstr table
|
||||
out.write_qstr(fmpy) # filename
|
||||
for q in native_qstr_vals:
|
||||
out.write_qstr(q)
|
||||
|
||||
# MPY: object table
|
||||
for q in native_qstr_objs:
|
||||
out.write_bytes(bytearray([MP_PERSISTENT_OBJ_STR]))
|
||||
out.write_uint(len(q))
|
||||
out.write_bytes(bytes(q, "utf8") + b"\x00")
|
||||
|
||||
# MPY: kind/len
|
||||
out.write_uint(len(env.full_text) << 3 | (MP_CODE_NATIVE_VIPER - MP_CODE_BYTECODE))
|
||||
@@ -937,17 +939,6 @@ def build_mpy(env, entry_offset, fmpy, native_qstr_vals, native_qstr_objs):
|
||||
# MPY: machine code
|
||||
out.write_bytes(env.full_text)
|
||||
|
||||
# MPY: n_qstr_link (assumes little endian)
|
||||
out.write_uint(len(native_qstr_vals) + len(native_qstr_objs))
|
||||
for q in range(len(native_qstr_vals)):
|
||||
off = env.qstr_val_section.addr + q * env.arch.qstr_entry_size
|
||||
out.write_uint(off << 2)
|
||||
out.write_qstr(native_qstr_vals[q])
|
||||
for q in range(len(native_qstr_objs)):
|
||||
off = env.qstr_obj_section.addr + q * env.arch.word_size
|
||||
out.write_uint(off << 2 | 3)
|
||||
out.write_qstr(native_qstr_objs[q])
|
||||
|
||||
# MPY: scope_flags
|
||||
scope_flags = MP_SCOPE_FLAG_VIPERRELOC
|
||||
if len(env.full_rodata):
|
||||
@@ -978,10 +969,14 @@ def build_mpy(env, entry_offset, fmpy, native_qstr_vals, native_qstr_objs):
|
||||
kind = 0
|
||||
elif isinstance(kind, str) and kind.startswith(".bss"):
|
||||
kind = bss_const_table_idx
|
||||
elif kind == "mp_fun_table":
|
||||
elif kind == "mp_native_qstr_table":
|
||||
kind = 6
|
||||
elif kind == "mp_native_obj_table":
|
||||
kind = 7
|
||||
elif kind == "mp_fun_table":
|
||||
kind = 8
|
||||
else:
|
||||
kind = 7 + kind
|
||||
kind = 9 + kind
|
||||
assert addr % env.arch.word_size == 0, addr
|
||||
offset = addr // env.arch.word_size
|
||||
if kind == prev_kind and base == prev_base and offset == prev_offset + 1:
|
||||
@@ -1023,18 +1018,14 @@ def do_preprocess(args):
|
||||
for i, q in enumerate(static_qstrs):
|
||||
print("#define %s (%u)" % (q, i + 1), file=f)
|
||||
for i, q in enumerate(sorted(qstr_vals)):
|
||||
print("#define %s (mp_native_qstr_val_table[%d])" % (q, i), file=f)
|
||||
print("#define %s (mp_native_qstr_table[%d])" % (q, i + 1), file=f)
|
||||
for i, q in enumerate(sorted(qstr_objs)):
|
||||
print(
|
||||
"#define MP_OBJ_NEW_QSTR_%s ((mp_obj_t)mp_native_qstr_obj_table[%d])" % (q, i),
|
||||
"#define MP_OBJ_NEW_QSTR_%s ((mp_obj_t)mp_native_obj_table[%d])" % (q, i),
|
||||
file=f,
|
||||
)
|
||||
if args.arch == "xtensawin":
|
||||
qstr_type = "uint32_t" # esp32 can only read 32-bit values from IRAM
|
||||
else:
|
||||
qstr_type = "uint16_t"
|
||||
print("extern const {} mp_native_qstr_val_table[];".format(qstr_type), file=f)
|
||||
print("extern const mp_uint_t mp_native_qstr_obj_table[];", file=f)
|
||||
print("extern const uint16_t mp_native_qstr_table[];", file=f)
|
||||
print("extern const mp_uint_t mp_native_obj_table[];", file=f)
|
||||
|
||||
|
||||
def do_link(args):
|
||||
|
||||
Reference in New Issue
Block a user