.Net CLR主线合并的部分Risc-v,龙芯,ARM代码。当然ARM一直是主力支持的,这里主要是Risc-V和龙芯。通过UnwindCode看下。
UnwindCode这个东西,主要是通过一些二进制代码描述一些机器码含义,然后对其进行相应的操作。
我们通过lldb来看下这些操作的内容:
(lldb) b RunMainInternal(lldb) r(lldb) b allocUnwindInfo(lldb) c(lldb) source info(lldb) b jitinterface.cpp:11232(lldb) c
内容如下:
lldb) cProcess 58851 resumingProcess 58851 stopped* thread #1, name = 'clrrun', stop reason = breakpoint 6.1 frame #0: 0x00007ffff6e676c7 libcoreclr.so`CEEJitInfo::allocUnwindInfo(this=0x00007fffffffaf70, pHotCode="UH/x83/xecPH/x8dl$P/xc4A8W/xc0/xc5y/U0000007fE/xc0/xc5y/U0000007fE/xd0/xc5y/U0000007fE/xe03/xc0H/x89E/xf0H/x89}/xf8/x83=/xa9/xf3/U0000001d", pColdCode=0x0000000000000000, startOffset=0, endOffset=395, unwindSize=8, pUnwindBlock="/U00000001/U00000005/U00000002", funcKind=CORJIT_FUNC_ROOT) at jitinterface.cpp:11232:5 11229 } 11230 #endif // _DEBUG 11231 -> 11232 memcpy(pUnwindInfoRW, pUnwindBlock, unwindSize);
我们看到它是一个memcpy的赋值。看下pUnwindInfoRW里面是什么
(lldb) n(lldb) p/x *pUnwindInfoRW(UNWIND_INFO) $6 = { Version = 0x01 Flags = 0x00 SizeOfProlog = 0x05 CountOfUnwindCodes = 0x02 FrameRegister = 0x00 FrameOffset = 0x00 UnwindCode = { [0] = { = (CodeOffset = 0x05, UnwindOp = 0x02, OpInfo = 0x09) EpilogueCode = (OffsetLow = 0x05, UnwindOp = 0x02, OffsetHigh = 0x09) FrameOffset = 0x9205 } }}
CountOfUnwindCodes表示总共有两个UnwindCode。
下面是UnwindCode成员意义:
CodeOffset表示机器码的长度。UnwindOp表示对是枚举类型_UNWIND_OP_CODES,表示机器码指令,比如UWOP_ALLOC_SMALL表示分配小对象栈空间(sub指令),UWOP_PUSH_NONVOL(push指令)。OpInfo则表示机器操作数。
看下两个UnwindCode的结构
(lldb) p/x pUnwindInfoRW->UnwindCode[0](UNWIND_CODE) $12 = { = (CodeOffset = 0x05, UnwindOp = 0x02, OpInfo = 0x09) EpilogueCode = (OffsetLow = 0x05, UnwindOp = 0x02, OffsetHigh = 0x09) FrameOffset = 0x9205}(lldb) p/x pUnwindInfoRW->UnwindCode[1](UNWIND_CODE) $13 = { = (CodeOffset = 0x01, UnwindOp = 0x00, OpInfo = 0x05) EpilogueCode = (OffsetLow = 0x01, UnwindOp = 0x00, OffsetHigh = 0x05) FrameOffset = 0x5001}(lldb) p/x pUnwindInfoRW->UnwindCode[2](UNWIND_CODE) $14 = { = (CodeOffset = 0x00, UnwindOp = 0x00, OpInfo = 0x00) EpilogueCode = (OffsetLow = 0x00, UnwindOp = 0x00, OffsetHigh = 0x00) FrameOffset = 0x0000}
第三个索引它就为零,确实是是两个。它的Unwindop分别是0x02和0x00.这分别代表了:UWOP_ALLOC_SMALL和UWOP_PUSH_NONVOL.也即机器码:sub和push。它的OpInfo分别为:0x09和0x05。分别代表了操作机器码:8* 9+8以及rbp。
OpInfo
if (OpInfo == kRBP)
那么这个指令就很明显了
push rbpsub rsp_80
OK,以上是UnwindCode解析,下面来看下UnwindCode对于Risc-V和龙芯的这次hi。
在它进行赋值完成之后,也即是:
memcpy(pUnwindInfoRW, pUnwindBlock, unwindSize);
它总共有五个target,也就是指令集,分别为:amd64,arm64/arm,la64,riscv64
#elif defined(TARGET_AMD64) pUnwindInfoRW->Flags = UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER;#elif defined(TARGET_ARM64) *(LONG *)pUnwindInfoRW |= (1 << 20); // X bit#elif defined(TARGET_ARM) *(LONG *)pUnwindInfoRW |= (1 << 20); // X bit#elif defined(TARGET_LOONGARCH64) *(LONG *)pUnwindInfoRW |= (1 << 20); // X bit#elif defined(TARGET_RISCV64) *(LONG *)pUnwindInfoRW |= (1 << 20); // X bit#endif
我们看到.Net的主线当中支持的Risc-v和La64,这里和x64的区别就在于,x64是pUnwindInfoRW的flag是或上
UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER;
而其他的三个则是:
*(LONG *)pUnwindInfoRW |= (1 << 20);
本文链接:http://www.28at.com/showinfo-26-11911-0.html.Net JIT支持的Risc-V/La/Arm
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
上一篇: WPF中WCF应用实例