diff --git a/patch.py b/patch.py index 41ec2c8..df82174 100644 --- a/patch.py +++ b/patch.py @@ -90,7 +90,6 @@ ldm.+\{(?P.+)\} """, start=layout_driver_addr, n=0) layout_driver_frame_size = int(layout_driver_end_match.groups["sz1"]) + (layout_driver_end_match.groups["popregs"].count(",") + 1) * 4 -arbitrary_offset = 0x34 if platform == "aplite": # Dig out a pointer to the structure that holds the input iteration state. @@ -100,14 +99,11 @@ layour_driver_setup_end = p.match(r"b(?:ne|eq).+", start=layout_driver_addr, n=2).start layout_driver_last_call = p.match("bl.+", start=layout_driver_addr, end=layour_driver_setup_end, n=-1).start lineend_sp_off = int(p.match("add r1, sp, #(?P\d+).*", start=layout_driver_addr, end=layout_driver_last_call, n=-1).groups["off"]) - assert lineend_sp_off == (layout_driver_frame_size - arbitrary_offset) + print("Line-end stack pointer offset %x" % lineend_sp_off) + p.define_macro("LINEEND_SP_OFF", lineend_sp_off) else: - # I couldn't find a good place to pull this value from. - # But, it's stable between aplite and basalt so. - lineend_sp_off = layout_driver_frame_size - arbitrary_offset - print(lineend_sp_off) - -p.define_macro("LINEEND_SP_OFF", lineend_sp_off) + # Empirically determined - probably only works on >=4.1. + p.define_macro("LINEEND_INDIRECT_SP_OFF", 56) # This is the part that actually calls the render callback - which we intend to wrap. render_handler_call_match = p.match(r""" diff --git a/runtime/patch.c b/runtime/patch.c index 3935373..e751bc7 100644 --- a/runtime/patch.c +++ b/runtime/patch.c @@ -60,10 +60,16 @@ GTextAlignment gdt_alignment_step(char* text, GTextAlignment alignment){ void render_rtl_step(char* line_start, bool more_text, char* callsite_sp) { char *line_end, *line_end_1, *line_end_2; - bool did_rtl_transform = false; if (line_start >= (char *)SRAM_BASE && *line_start) { +#ifdef LINEEND_INDIRECT_SP_OFF + // 4.1 breaks the old LINEEND_SP_OFF stuff. + // But, after an hour or two of rifling through memory, this seems to be the same... + line_end_1 = *((*(char***)(callsite_sp + LINEEND_INDIRECT_SP_OFF) + 2)); + line_end_2 = *((*(char***)(callsite_sp + LINEEND_INDIRECT_SP_OFF) + 3)); +#else line_end_1 = *(char **)(callsite_sp + LINEEND_SP_OFF); line_end_2 = *(char **)(callsite_sp + LINEEND_SP_OFF + 4); +#endif line_end = more_text ? line_end_1 : line_end_2; while (line_end > line_start && *(line_end - 1) == ' ') { line_end--;