函数返回值:arm64 规定了整数型返回值放在 x0 寄存器里

sp(栈空间)字节对齐:该临时变量占用 4字节空间;又因为 arm64 下对于使用 sp 作为地址基址寻址的时候,必须要 16byte-alignment(对齐),所以申请了 16字节空间作为临时变量使用。具体参见 这里

指令模式

Thumbe 或 Arm32 或 Arm64

在一段代码的开头有 .CODE16 CODE32 CODE64

IDA 中按 ALT+G 选择 T (T是虚拟寄存器,当值手动赋值为1表示是 Thumbe 指令解析模式, 0 则是 ARM指令解析模式)

svc 0 和 swi 0 指令

分析 __bionic_clone.S ,在 libc.so 中

arm32:

源码

/bionic/libc/arch-arm/bionic/__bionic_clone.S

    # Make the system call.
ldr r7, =__NR_clone
swi #

/bionic/libc/kernel/uapi/asm-arm/asm/unistd.h

#define __NR_SYSCALL_BASE
#define __NR_clone (__NR_SYSCALL_BASE + ) //=0x78

指令

/system/lib/libc.so

.text:0001712C LDR R7, =0x78    //0x78=__NR_clone
.text: SVC

svc 指令机器码(小端):00 00 00 EF

‭1110 1111 0000 0000 0000000000000000‬

根据最后的附录的表的倒数第二个

swi 指令的 0~31位 中的 4~7位为 1111,从机器码角度可以看到  SWI 指令 就是 SVC指令

源码 swi > svc

R7 向内核传递系统调用号

arm64:

源码:

/bionic/libc/arch-arm64/bionic/__bionic_clone.S

    # Make the system call.
mov x8, __NR_clone
svc #

/bionic/libc/kernel/uapi/asm-arm64/asm/unistd.h

#include <asm-generic/unistd.h>

转去看

/bionic/libc/kernel/uapi/asm-generic/unistd.h

#define __NR_clone      //=0xDC

指令

/system/lib64/libc.so

.text:000000000001B9A4 MOV X8, #0xDC          //0xDC = __NR_clone
.text:000000000001B9A8 SVC 

svc 指令机器码(小端):01 00 00 D4

网上没有找到ARM64 的 二进制机器码 格式表格所以,而ARM64的二进制机器码发生了改变。。。。

所以看起来是同一个指令

源码 svc -> svc

x8 用于向内核传递系统调用号

svc的 thumb,arm32,arm64 的格式都不太一样

svc指令官方手册:

Supervisor call to allow application code to call the OS. It generates an exception targeting exception level 1 (EL1). (生成一个异常级别1 的异常)

Supervisor Call causes an exception to be taken to EL1.

Arm®v8架构定义了四个异常级别,从EL0到EL3,其中EL3是最高的异常级别,具有最多的执行特权。在接受异常时,异常级别可以增加或保持不变,而从异常返回时,异常级别可以减少或保持不变。

EL0  Applications. 应用

EL1  OS kernels and associated functions that are typically described as privileged. 系统内核

EL2  Hypervisor. (硬件辅助虚拟化。arm目前采用的是硬件辅助虚拟化的方式,即在处理器模式上增加了el2级别,将hypervisor运行在el2上。将hypervisor与VM kernel运行在不同的模式下,VM运行在一个受控模式,hypervisor可以配置哪些敏感指令是否触发异常。总的来说目的是为了捕获敏感指令以触发异常。  https://blog.csdn.net/zgy666/article/details/79238646

EL3  Secure monitor.

arm32指令机器码表格:

Thumb SVC 指令

 

系统调用号如何获取?用哪个寄存器?

官方文档:

问题:

为什么我们看到 arm32下,使用 svc 指令陷入内核调用 __NR_clone 的参数是用 R7 传递 而不是 R0~R3 ? arm官方推荐R0-R3 ,但Linux内核实现用的是R7 ,X8 ?对吗

从 swi 陷入内核看起,调用swi 指令后,cpu会产生一个中断信号,因为是swi指令产生的,所以会将pc赋值为 中断向量表基地址 + 0x8

此处有一条跳转指令

这张表定义在 /arch/arm/kernel/entry-armv.S

...
1131 .equ stubs_offset, __vectors_start + 0x200 - __stubs_start
1133 .globl __vectors_start
1134__vectors_start:
ARM( swi SYS_ERROR0 )
THUMB( svc # ) //一个表项32位,一条thumb指令16位,所以第一个表项 用了2个 thumb沾满了32位,第一个指令是 svc 0 ,第二个是 nop,用于cpu复位后调用
THUMB( nop )
W(b) vector_und + stubs_offset
W(ldr) pc, .LCvswi + stubs_offset //这里是我们关注的 swi 的中断向量跳转 指令 = ldr pc, .LCvswi + stubs_offset
W(b) vector_pabt + stubs_offset
W(b) vector_dabt + stubs_offset
W(b) vector_addrexcptn + stubs_offset
W(b) vector_irq + stubs_offset
W(b) vector_fiq + stubs_offset .globl __vectors_end
1147__vectors_end:
...
.LCvswi:
.word vector_swi

/arch/arm/kernel/entry-common.S

353ENTRY(vector_swi)
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0 - r12
ARM( add r8, sp, #S_PC )
ARM( stmdb r8, {sp, lr}^ ) @ Calling sp, lr
THUMB( mov r8, sp )
THUMB( store_user_sp_lr r8, r10, S_SP ) @ calling sp, lr
mrs r8, spsr @ called from non-FIQ mode, so ok.
str lr, [sp, #S_PC] @ Save calling PC
str r8, [sp, #S_PSR] @ Save CPSR
str r0, [sp, #S_OLD_R0] @ Save OLD_R0
zero_fp /*
* Get the system call number. 获取系统调用号
*/ #if defined(CONFIG_OABI_COMPAT) /*
* If we have CONFIG_OABI_COMPAT then we need to look at the swi
* value to determine if it is an EABI or an old ABI call.
*/
#ifdef CONFIG_ARM_THUMB
tst r8, #PSR_T_BIT
movne r10, # @ no thumb OABI emulation
ldreq r10, [lr, #-] @ get SWI instruction
#else
ldr r10, [lr, #-] @ get SWI instruction
A710( and ip, r10, #0x0f000000 @ check for SWI )
A710( teq ip, #0x0f000000 )
A710( bne .Larm710bug )
#endif
#ifdef CONFIG_CPU_ENDIAN_BE8
rev r10, r10 @ little endian instruction
#endif #elif defined(CONFIG_AEABI) /*
* Pure EABI user space always put syscall number into scno (r7).
*/
A710( ldr ip, [lr, #-] @ get SWI instruction )
A710( and ip, ip, #0x0f000000 @ check for SWI )
A710( teq ip, #0x0f000000 )
A710( bne .Larm710bug ) #elif defined(CONFIG_ARM_THUMB) /* Legacy ABI only, possibly thumb mode. */
tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in
ldreq scno, [lr, #-] #else /* Legacy ABI only. */
ldr scno, [lr, #-] @ get SWI instruction
A710( and ip, scno, #0x0f000000 @ check for SWI )
A710( teq ip, #0x0f000000 )
A710( bne .Larm710bug ) #endif #ifdef CONFIG_ALIGNMENT_TRAP
ldr ip, __cr_alignment
ldr ip, [ip]
mcr p15, , ip, c1, c0 @ update control register
#endif
enable_irq get_thread_info tsk
adr tbl, sys_call_table @ load syscall table pointer #if defined(CONFIG_OABI_COMPAT)
/*
* If the swi argument is zero, this is an EABI call and we do nothing.
*
* If this is an old ABI call, get the syscall number into scno and
* get the old ABI syscall table address.
*/
bics r10, r10, #0xff000000
eorne scno, r10, #__NR_OABI_SYSCALL_BASE
ldrne tbl, =sys_oabi_call_table
#elif !defined(CONFIG_AEABI)
bic scno, scno, #0xff000000 @ mask off SWI op-code
eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
#endif ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing
stmdb sp!, {r4, r5} @ push fifth and sixth args #ifdef CONFIG_SECCOMP
tst r10, #_TIF_SECCOMP
beq 1f
mov r0, scno
bl __secure_computing
add r0, sp, #S_R0 + S_OFF @ pointer to regs
ldmia r0, {r0 - r3} @ have to reload r0 - r3
:
#endif tst r10, #_TIF_SYSCALL_WORK @ are we tracing syscalls?
bne __sys_trace cmp scno, #NR_syscalls @ check upper syscall limit
adr lr, BSYM(ret_fast_syscall) @ return address
ldrcc pc, [tbl, scno, lsl #] @ call sys_* routine add r1, sp, #S_OFF
: mov why, # @ no longer a real syscall
cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back
bcs arm_syscall
b sys_ni_syscall @ not private func
468ENDPROC(vector_swi)

if def 的嵌套:

//1.
//现场保护:保存寄存器到内存

//2.
//从swi 指令的立即数处获取系统调用号
#if defined(CONFIG_OABI_COMPAT)
    #ifdef CONFIG_ARM_THUMB
    #else
    #end

    #ifdef CONFIG_CPU_ENDIAN_BE8
    #end
#elif defined(CONFIG_AEABI)
#elif defined(CONFIG_ARM_THUMB)
#else
  //遗留ABI
#end

。。。

//3.

//获取系统调用表基地址 到 tbl(r8)

adr tbl, sys_call_table @ load syscall table pointer
。。。

//4.
//如果 swi 指令的立即数是0,那么表示是EABI调用。
//如果是旧ABI调用,则从scno 获取系统调用号,并获得旧ABI系统调用表的地址
//scno 是什么? r7寄存器别称,纯EABI用户空间总是将syscall号放入scno (r7)。 SystemCallNO
#if defined(CONFIG_OABI_COMPAT)
#elif !defined(CONFIG_AEABI)
#endif

。。。

//5.

ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
。。。

.type sys_call_table, #object
ENTRY(sys_call_table)
#include "calls.S"

tbl,scno 等定义在文件

/arch/arm/kernel/entry-header.S

/*
* These are the registers used in the syscall handler, and allow us to
* have in theory up to arguments to a function - r0 to r6. 允许携带7个参数给方法 r0~r6
*
* r7 is reserved for the system call number for thumb mode. r7 是在thumb模式下的保留的系统调用号寄存器
*
。。。 */
176scno .req r7 @ syscall number
177tbl .req r8 @ syscall table pointer
178why .req r8 @ Linux syscall (!= )
179tsk .req r9 @ current thread_info
 

杂项记录 arm64 的一些特性的更多相关文章

  1. JAVA记录-Spring两大特性

    1.IOC控制反转 Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象 ...

  2. android 启动流程 相关 杂项记录

    Android原生流程 Init进程 主要流程及分支梳理 ueventd_main()watchdogd_main()主要流程a) 公共部分 增加PATH 环境变量初始化内核日志,打开/dev/kms ...

  3. JAVA记录 Spring 两大特性

    1.IOC控制反转 Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象 ...

  4. Berkeley DB的数据存储结构——哈希表(Hash Table)、B树(BTree)、队列(Queue)、记录号(Recno)

    Berkeley DB的数据存储结构 BDB支持四种数据存储结构及相应算法,官方称为访问方法(Access Method),分别是哈希表(Hash Table).B树(BTree).队列(Queue) ...

  5. Python的一些高级特性以及反序列化漏洞

    0x01 简述 文章主要记录一下python高级特性以及安全相关的问题 python作为脚本语言,其作为高级语言是由c语言开发的,关于python的编译和链接可以看向这里https://github. ...

  6. 分布式监控系统Zabbix-3.0.3-完整安装记录(0)

    一.Linux下开源监控系统简单介绍1)cacti:存储数据能力强,报警性能差2)nagios:报警性能差,存储数据仅有简单的一段可以判断是否在合理范围内的数据长度,储存在内存中.比如,连续采样数据存 ...

  7. linux 备忘记录

    杂项记录 Ubuntu 通过/etc/network/interfaces修改IP,重启网络服务貌似也不会生效.可以重启电脑使其生效,或执行: ip addr flush dev ens33 & ...

  8. Java 14 有哪些新特性?

    记录为 Java 提供了一种正确实现数据类的能力,不再需要为实现数据类而编写冗长的代码.下面就来看看 Java 14 中的记录有哪些新特性. 作者 | Nathan Esquenazi 译者 | 弯月 ...

  9. Phoenix踩坑填坑记录

    Phoenix踩坑填坑记录 Phoenix建表语句 如何添加二级索引 判断某表是否存在 判断索引是否存在 Date类型日期,条件判断 杂项 记录Phoenix开发过程中的填坑记录. 部分原文地址:ph ...

随机推荐

  1. 如何将RAC数据库的 RMAN Disk 备份 Restore 到另一个节点上的单个实例 (Doc ID 415579.1)

    HowTo Restore RMAN Disk backups of RAC Database to Single Instance On Another Node (Doc ID 415579.1) ...

  2. Red Hat 4.4.7-4上安装glances填大大大坑实录,我的内心是崩溃的!!!

    今天的任务是在公司的一台压力测试机上安装一个性能监控工具:glances 因为以前我已经多次安装和使用这个工具,我大意的以为整个过程是这样的: 分分钟搞定完事 然而 我们公司的服务器版本实在是太老了, ...

  3. WPF DataGrid 绑定数据及时更新的处理

    原文:WPF DataGrid 绑定数据及时更新的处理 默认情况下datagrid 绑定数据源后,在界面编辑某一列后,数据不会及时更新到内存对象中.如在同一行上有一个命令对来获取 当前选中行(内存对象 ...

  4. Noip2017Day2T2 宝藏

    题目链接 problem 有\(n\)个点,\(m\)条无向边,选择一个点开始开辟道路.开辟一条长度为\(L\)的链接\(u,v\)的道路会花费\(L \times K\),K表示从选择的最初点到\( ...

  5. CSP 2019 游记

    Day -32 开坑. 没什么好说的,等个 5 天等初赛(应该叫第一轮认证)挂掉之后就能弃坑了. 今天开始停课,虽然每天只停半天,但是感觉还是特别的舒服~ 然而得等初赛过了才能全天停课-- 没关系,熬 ...

  6. "One or more types required to compile a dynamic expression cannot be found. Are you missing references to Microsoft.CSharp.dll and System.Core.dll?"的解决方法

    #事故现场: 在一个.net 4.0 的项目中使用dynamic,示例代码如下: private static void Main(string[] args) { dynamic obj; obj ...

  7. Qt Designer布局预览正常,代码调用时所有控件堆在一起

    一.实验环境 1.Windows10x64 2.anaconda4.6.9 + python3.7.1(anaconda集成,不需单独安装) 3.pyinstaller3.5 二.问题描述 1.Qt ...

  8. idea插件备份

  9. 深入理解java中的byte类型

    作者 | 进击的石头--GO! 来源 | https://www.cnblogs.com/zl181015/p/9435035.html#4432849 Java也提供了一个byte数据类型,并且是基 ...

  10. 杂牌机搞机之旅最终章————刷入Xposed框架

    杂牌机搞机之旅最终章----刷入Xposed框架 recovery移植不成功,没办法,挂载分区好像挂载不上,所以,刷入magisk如果卡在开机屏,只能线刷解决..心累.. 所以,折腾完XPosed框架 ...