ksco 的工作日志
245 subscribers
168 photos
10 videos
4 files
84 links
内容主要取决于我正在做的东西,目前主要是模拟器 / DBT 之类的散乱话题。
Download Telegram
今日份开心
TLS pthread 的内存布局真是各抒己见,每个架构都不太一样
很好,现在卡在 ibl 上了
DynamoRIO 某个宏展开成了 700 行代码,太可怕了
emit_fcache_enter_common

>>> append_fcache_enter_prologue

mv a1, a5 # dont care
mv a5, a0 # 将 ARG1(dc) 赋值给 a5,因为 a5 是 REG_DCXT
...

>>>>>> insert_load_dr_tls_base
sd tp, 0(a5) # 将原始 tp 放到 dc 的 X0 slot 中保存
ld tp, -8(tp) # 拿到 dtv.private 所指向的结构体(spill_state)
tp 从这里开始指向 spill_state


>>> append_setup_fcache_target


ld a0, NEXT_TAG_OFFSET(a5) # 初始化完成后跳转到的地址,加载到 a0
sd a0, A2_SLOT(tp) # 把 a0 的值放到 A2 slot

>>> body


ld a0, 96(a5) # 把 dc->a0 加载到 a0
ld a1, 104(a5) # 把 dc->a1 加载到 a1
sd a0, 0(tp) # 把 a0 保存到 spill_state A0 slot
sd a1, 8(tp) # 把 a1 保存到 spill_state A1 slot


>>> append_restore_xflags (用了 a0)

>>> append_restore_gpr


ld a0, REG_OFFSET(tp)(a5) # 把 dc->tp 加载到 a0
sd a0, stolen_slot(tp) # 把 a0 存进 spill state stolen slot
sd tp, REG_OFFSET(tp)(a5) # 把 tp 存到到 dc->tp
... 所有寄存器(除 tp)都替换为 dc 中的值


>>> append_jmp_to_fcache_target


ld a0, A2_SLOT(tp) # 把 A2 slot 的值放回 A0(跳转地址)
jr a0

| jump

insert_fragment_prefix

ld a0, 0(tp) # 从 spill_state A0 slot 加载到 a0
ld a1, 8(tp) # 从 spill_state A1 slot 加载到 a1


到这里,除了 tp,所有的寄存器的值都是 dc 中的值了

tp 指向了 spill_state (TODO:所有读写 tp 的指令都需要 mangle!!)


actual bb

| jump to exit stub

insert_exit_stub_other_flags

sd a0, 0(tp) # 把 a0 的值存回 spill_state
sd a1, 8(tp) # 把 a1 的值存回 spill_state
li a0, link_stub # 把 link_stub 地址存入 a0
auipc a1, 0
ld a1, xxx(a1) # a1 中保存 exit_stub 最后的那个地址,也就是 fcache_return 的地址
jr a1

| jump

append_fcache_return_common

>>> append_prepare_fcache_return


sd a5, A3_SLOT(tp) # a5 存到 spill_state A3 slot
ld a5, DC_SLOT(tp) # 将 spill_state dc slot 放入 a5
此时,a5 又恢复了“正常”了!


>>> append_save_gpr


... # 将除 A0, A1 外的寄存器保存到 dc
ld a1, A3_SLOT(tp)
sd a1, REG_OFFSET(a5)(a5) # 把正确的 A5 值保存到 dc
ld a1, stolen_slot(tp)
sd a1, REG_OFFSET(tp)(a5) # 把正确的 tp 保存到 dc
ld tp, 0(a5) # 把原始 tp 加载回来


>>> body


ld sp, dstack_offs(a5) # 切换到一个干净的栈上
... # 把 fcsr 写回 dc
sd a0, last_exit(a5) # dc->last_exit = (link_stub)


>>> append_call_dispatch

>>>>>> dr_insert_call_noreturn (TODO: port to RISC-V maybe?)


call d_r_dispatch with no return.
这个问题 debug 3 天了,刚刚一瞬间甚至想不起来 bug 本身是什么了
👀1
所以问题的原因是最后一个 bb 回到 d_r_dispatch 的时候, dcontext->thread_stats 不知道怎么的被改了,这他妈也太怪了
现在的想法就是一路跟下去,看看到底在哪里被改的。但是 lp4a 的性能真的好弱,gdb 慢得怀疑人生
终于跑出结果来了,果然是我写的代码导致的
终于把这个 bug 修好了,现在又有新 bug 要修了
又修好了一个 bug,现在又有一个新的
Ohhhhhhhhhhhhhhhhhhhhhhhhhhhh
成功了!
移植第一阶段彻底完成了,可以躺平了
去显摆了一下
我大概还是喜欢这个显示器的,虽然素质一般,但真的很大!