五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網 會員登陸 & 注冊

arm64 實現(xiàn)閉包轉C函數

2023-03-08 11:26 作者:你敢敢我就我敢  | 我要投稿

調用約定

arm64的C調用約定如下:

首八個不超過8bytes的非浮點數使用r0-r7寄存器

首八個浮點數使用d0-d7寄存器

大于八個參數則使用棧傳遞

結構體分為三種情況

  1. 不超過8bytes,那么此結構體直接使用上述規(guī)則傳遞

  2. 超過8bytes但不超過16bytes,那么此結構體使用兩個64bits寄存器傳輸

  3. 超過16bytes,傳遞結構體指針


返回值若不超過8bytes,則使用r0或d0傳遞,否則調用者使用x8傳遞接受對象的指針,被調用者將值寫入指針

實現(xiàn)

下面將使用Rust語言實現(xiàn)少于七個參數無浮點的閉包轉換

閉包是一個含有狀態(tài)的“函數”,使用起來十分方便,但是要使用一些C函數回調的時候就很不友好了

下面我們來“改造”閉包

一個閉包可以當作一個結構體,他當然也是有地址的

于是對于一個閉包

Fn(T) -> R

我們可以改造為

extern "C" fn(*const?(), T) -> R

要實現(xiàn)這點也不難,只需要將寄存器一一往后排,再將x0寄存器賦值對應指針

難點是如何生成這樣的機器碼

生成機器碼

通過上面的分析和查閱資料,找到我們需要使用的指令

BR

我們先來反匯編分析C函數的跳轉

C
ASM

可見其跳轉使用了BLR指令,那么為什么我們使用BR指令進行跳轉呢?

因為我們不需要“返回”

BLR指令的含義為:存儲返回地址到LR(x30)寄存器

RET指令的含義為:使用LR寄存器進行返回 (return)

那么使用BR指令直接跳轉即可,不需要動LR寄存器

MOVK

MOVK指令可以將一個16位立即數偏移存入指定寄存器,并且保留寄存器其他位的數值(即MOV'Keep')

那么我們可以硬編碼一個指針進入寄存器,以實現(xiàn)尋址,即:

MOVK x0, part0, LSL 0

MOVK x0, part1, LSL 16

MOVK x0, part2, LSL 32

MOVK x0, part3, LSL 48

使用四條指令即可存儲一個指針進入寄存器

MOV (register)

我們需要移動寄存器,那么是肯定需要使用MOV指令的了

機器碼生成

接下來就是生成機器碼,機器碼的詳細定義請參閱Arm手冊(見文末)

通過閱讀arm手冊我們得到這幾個指令的機器碼生成函數

然后就是期待已久的機器碼生成環(huán)節(jié)~

首先我們定義參數

根據參數列表生成對應的機器碼

規(guī)則如下:

如果小于32bits,則使用Wn傳遞

否則使用Xn傳遞

第一個參數為x0, 將其轉移至x1

第二個參數為x1, 將其轉移至x2

...?以此類推

然后將參數指針傳入x0, 函數指針傳入Xn (注意不可占用x8)

那么對于參數列表,我們可以做如下工作

遍歷參數列表,對寄存器數字遞增

然后將生成的機器碼反轉

第二個參數為x1, 將其轉移至x2

第一個參數為x0, 將其轉移至x1

(防止破壞參數)

最后存入參數指針和函數指針

小端序

那么到這里,機器碼的生成就完畢了,接下來就是將其寫入可執(zhí)行內存并嘗試執(zhí)行,此內容詳見文末(VirtualAlloc / mmap)

接下來就是執(zhí)行測試!

完美通過!

本文源碼:https://github.com/LaoLittle/binary-learn

Armv8 手冊:https://developer.arm.com/documentation/ddi0487/fc/

VirtualAlloc / VirtualProtect?/?VirtualFree?:??https://learn.microsoft.com/en-us/windows/win32/api/memoryapi

mmap / munmap / mprotect :?https://linux.die.net/man/2

arm64 實現(xiàn)閉包轉C函數的評論 (共 條)

分享到微博請遵守國家法律
舟山市| 通化市| 漾濞| 河池市| 德兴市| 双牌县| 司法| 玛纳斯县| 安达市| 阿合奇县| 宁武县| 龙门县| 舞钢市| 鹿邑县| 白城市| 金乡县| 松原市| 丹东市| 抚顺县| 冀州市| 江安县| 宣化县| 东方市| 乌审旗| 竹北市| 海阳市| SHOW| 东台市| 仙居县| 翼城县| 合山市| 饶河县| 兴安盟| 凌海市| 门头沟区| 板桥市| 克拉玛依市| 夏津县| 临江市| 瓦房店市| 维西|