Skip to content

Commit

Permalink
Fix bad line_end pointers on pre-ultimate lines during RTL transforma…
Browse files Browse the repository at this point in the history
…tion on OS4.1.
  • Loading branch information
cpfair committed Sep 29, 2016
1 parent 84a294b commit 77d9481
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 9 deletions.
12 changes: 4 additions & 8 deletions patch.py
Expand Up @@ -90,7 +90,6 @@
ldm.+\{(?P<popregs>.+)\}
""", 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.
Expand All @@ -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<off>\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"""
Expand Down
8 changes: 7 additions & 1 deletion runtime/patch.c
Expand Up @@ -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--;
Expand Down

0 comments on commit 77d9481

Please sign in to comment.