20

Ker · 2021年06月18日

arm系统调用实现原理及相关bpf工具介绍

1. 简介

这篇文章主要介绍系统调用在arm64下的实现及使用原理,考虑到目前bpf在系统调试和调优工作中被大量使用,在文章的最后也简单介绍一下系统调用相关的bpf工具。

系统调用在每个平台的实现方式各不相同,x86通过int 0x80实现;arm通过指令SVC实现(SVC属于arm64下的同步异常)。
syscall.png

在arm64架构下,异常分为同步异常和异步异常。
同步异常包括如下:

  • SVC,HVC,SMC
  • MMU中止(比如权限错误,对齐错误等)
  • 栈指针或指令地址没有对齐
  • 未定义指令

异步异常包括如下:

  • IRQ
  • FIQ
  • SError

2. 系统调用的定义

以openat为例讲一下系统调用的定义。
openat系统调用主要通过如下几个地方定义,
include/linux/syscalls.h
Screen Shot 2021-06-18 at 11.33.27 AM.png
Screen Shot 2021-06-18 at 11.34.16 AM.png

fs/open.c
Screen Shot 2021-06-18 at 11.34.56 AM.png
编译器会将SYSCALL_DEFINE4宏展开,具体细节就不详述了,最终通过do_sys_open函数实现openat系统调用功能。

有了系统调用处理函数的定义后,还需要在系统调用表中维护一套系统调用号和处理函数的映射关系,arm64的系统调用表sys_call_table定义如下:
arch/arm64/kernel/sys.c
Screen Shot 2021-06-18 at 11.22.46 AM.png

具体的映射定义在:
include/uapi/asm-generic/unistd.h
Screen Shot 2021-06-18 at 11.29.16 AM.png
openat系统调用号为56。

3. 系统调用的使用

当应用程序调用libc库的open函数,libc库调用SVC指令进入异常模式,在arm64架构下,通过异常向量表找到相应的入口函数,然后通过系统调用号找到处理函数并执行它,最后返回。
举个例子:
open_test.c
Screen Shot 2021-06-18 at 11.52.01 AM.png

//静态编译
gcc open_test.c -o open_test --static
//反汇编
objdump -D open_test > open_arm_asm

open_arm_asm
Screen Shot 2021-06-18 at 11.54.18 AM.png
可以看到将寄存器x8设置为系统调用号0x38 (openat),
然后调用了svc进入异常处理。

进入异常模式后,内核根据异常类型(同步异常)及当前所处的ELx, 调用相应的异常处理函数,这里是el0_sync。
arch/arm64/kernel/entry.S
Screen Shot 2021-06-18 at 1.43.32 PM.png

Screen Shot 2021-06-18 at 1.46.03 PM.png
667,668行:通过读取esr_el1得到产生异常的原因,保存到寄存器x24
669行:判断x24中保存的异常原因是否为svc
670行:上一行如果判断相等,调用el0_svc
Screen Shot 2021-06-18 at 1.47.26 PM.png
914行:读入syscall table的指针
915行:将系统调用号(w8)保存到wscno中,上面的讲解中libc库将系统调用号写入了x8寄存器
928行:以系统调用号为索引,得到syscall table表中相应的函数地址,这里就是sys_openat
929行:调用sys_openat

到这里,系统调用实现原理大体就讲完了,接下来我们介绍一下系统调用相关的bpf工具。

4. 系统调用相关bpf工具

可以使用BPF对Linux内核进行跟踪,收集我们想要的内核数据,从而对Linux中的程序进行分析和调试。
BPF的主要优点是几乎可以访问Linux内核和应用程序的任何信息,因为BPF可以在内核直接处理数据,和传统工具相比,不需要将数据从内核态搬运到用户态,所以BPF执行效率非常高,对系统性能影响很小。
Screen Shot 2021-06-18 at 5.04.56 PM.png

下面这张图来自Brendan Gregg的新书BPF Performance Tools,其中黑体字标明的是BCC/bpftrace先前存在的工具,红色是为『BPF Performance Tools』这本新书所创建的新工具,我用红框所框起来的几个工具是本文所讲的系统调用相关工具。
bpf_syscall1.png

下面简要列一下这几个工具用到的tracepoint:
execsnoop:

-> tracepoint:syscalls:sys_enter_execve

syscount:

-> tracepoint:raw_syscalls:sys_enter

killsnoop:

-> tracepoint:syscalls:sys_enter_kill
-> tracepoint:syscalls:sys_exit_kill

opensnoop:

-> tracepoint:syscalls:sys_enter_openat
-> tracepoint:syscalls:sys_exit_openat

statsnoop:

-> tracepoint:syscalls:sys_enter_statfs
-> tracepoint:syscalls:sys_enter_statx
-> tracepoint:syscalls:sys_exit_statfs
-> tracepoint:syscalls:sys_exit_statx

syncsnoop:

-> tracepoint:syscalls:sys_enter_sync
-> tracepoint:syscalls:sys_enter_syncfs
-> tracepoint:syscalls:sys_enter_fsync
-> tracepoint:syscalls:sys_enter_fdatasync
-> tracepoint:syscalls:sys_enter_sync_file_range
-> tracepoint:syscalls:sys_enter_msync

简要介绍一下opensnoop工具。
该工具跟踪文件打开事件,对发现系统中使用的数据文件、日志文件以及配置文件来说十分有用。该工具还可以检测由于快速打开大量文件导致的性能问题,也可以帮助调试找不到文件导致的问题。

opensnoop.bt

#!/usr/bin/bpftrace
/*
 * opensnoop    Trace open() syscalls.
 *        For Linux, uses bpftrace and eBPF.
 *
 * Also a basic example of bpftrace.
 *
 * USAGE: opensnoop.bt
 *
 * This is a bpftrace version of the bcc tool of the same name.
 *
 * Copyright 2018 Netflix, Inc.
 * Licensed under the Apache License, Version 2.0 (the "License")
 *
 * 08-Sep-2018    Brendan Gregg    Created this.
 */

BEGIN
{
    printf("Tracing open syscalls... Hit Ctrl-C to end.\n");
    printf("%-6s %-16s %4s %3s %s\n", "PID", "COMM", "FD", "ERR", "PATH");
}

tracepoint:syscalls:sys_enter_openat
{
    @filename[tid] = args->filename;
}

tracepoint:syscalls:sys_exit_openat
/@filename[tid]/
{
    $ret = args->ret;
    $fd = $ret > 0 ? $ret : -1;
    $errno = $ret > 0 ? 0 : - $ret;

    printf("%-6d %-16s %4d %3d %s\n", pid, comm, $fd, $errno,
        str(@filename[tid]));
    delete(@filename[tid]);
}

END
{
    clear(@filename);
}

这个程序跟踪了openat系统调用,同时从返回值中获取了文件描述符信息或者错误代码。

参考文档

http://www.brendangregg.com/e...

推荐阅读
关注数
17332
内容数
74
分享arm服务器软件应用经验、测试方法、优化思路、工具使用等。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息