• glibc中fork系统调用传参


    因为想跟踪下在新建进程时,如何处理新建进程的vruntime,所以跟踪了下fork。

    以glic-2.17中ARM为例(unicore架构的没找到),实际上通过寄存器向系统调用传递的参数为:

    r7: __NR_clone 120

    r0: CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD

    r1: NULL

    r2: NULL

    r3: NULL

    r4: &THREAD_SELF->tid

    fork()---->__fork()---->__libc_fork()
    
    __libc_fork()---->INLINE_SYSCALL (clone, 5, 
                                      CLONE_CHILD_SETTID | 
                                      CLONE_CHILD_CLEARTID | 
                                      SIGCHLD, 
                                      NULL, NULL, NULL, &THREAD_SELF->tid)
    #define INLINE_SYSCALL(name, nr, args...)  
          ({ unsigned int _sys_result = 
                      INTERNAL_SYSCALL (name, , nr, args);
    if (__builtin_expect
                    (INTERNAL_SYSCALL_ERROR_P (_sys_result, ), 0)) { __set_errno (INTERNAL_SYSCALL_ERRNO
                                (_sys_result, )); _sys_result
    = (unsigned int) -1; } (int) _sys_result; })
    #define INTERNAL_SYSCALL(name, err, nr, args...)          
                INTERNAL_SYSCALL_RAW(SYS_ify(name), err, nr, args)
    
    //#define __NR_clone 120
    #define SYS_ify(syscall_name)   (__NR_##syscall_name)
    //err没用使用,也没有传递宏参,第一次见到
    # define INTERNAL_SYSCALL_RAW(name, err, nr, args...) ({ register
    int _a1 asm ("r0"), _nr asm ("r7"); LOAD_ARGS_##nr (args) _nr = name; asm volatile ("swi 0x0 @ syscall " #name : "=r" (_a1) : "r" (_nr) ASM_ARGS_##nr : "memory"); _a1; })

    关于宏INTERAL_SYSCALL_RAW还是满有意思的,写了个函数测试下,真实的看下库如何向系统调用传参:

    #define LOAD_ARGS_0()
    #define ASM_ARGS_0
    
    
    #define LOAD_ARGS_1(a1) 
        int _a1tmp = (int)(a1); 
        LOAD_ARGS_0 () 
        _a1 = _a1tmp;
    
    #define ASM_ARGS_1 ASM_ARGS_0, "r" (_a1)
    
    
    
    #define LOAD_ARGS_2(a1, a2) 
        int _a2tmp = (int)(a2); 
        LOAD_ARGS_1(a1) 
        register int _a2 asm ("a2") = _a2tmp;
    
    #define ASM_ARGS_2 ASM_ARGS_1, "r" (_a2)
    
    
    
    #define LOAD_ARGS_3(a1, a2, a3) 
        int _a3tmp = (int)(a3); 
        LOAD_ARGS_2 (a1, a2) 
        register int _a3 asm ("a3") = _a3tmp;
    
    #define ASM_ARGS_3 ASM_ARGS_2, "r" (_a3)
    
    
    
    #define LOAD_ARGS_4(a1, a2, a3, a4) 
        int _a4tmp = (int) (a4); 
        LOAD_ARGS_3 (a1, a2, a3) 
        register int _a4 asm ("a4") = _a4tmp;
    
    #define ASM_ARGS_4 ASM_ARGS_3, "r" (_a4)
    
    
    
    #define LOAD_ARGS_5(a1, a2, a3, a4, a5) 
        int _v1tmp = (int)(a5); 
        LOAD_ARGS_4 (a1, a2, a3, a4) 
        register int _v1 asm ("v1") = _v1tmp; 
    
    #define ASM_ARGS_5 ASM_ARGS_4, "r" (_v1)
    
    #define INTERNAL_SYSCALL_RAW(name, err, nr, args...) 
        ({ 
            register int _a1 asm("r0"), _nr asm("r7"); 
            LOAD_ARGS_5 (args) 
            _nr = name; 
            asm volatile ("swi 0x0" 
                          : "=r" (_a1) 
                          : "r" (_nr) ASM_ARGS_##nr 
                          : "memory" 
                         ); 
            _a1; 
         })
    
    void test(void)
    {
        INTERNAL_SYSCALL_RAW(120, , 5,  6, 7, 8, 9, 0);
    }                                                                                                                  

    预处理后即为:

    void test(void)                                                                                                    
    {
     ({ 
          register int _a1 asm("r0"), _nr asm("r7"); 
          int _v1tmp = (int)(0); 
          int _a4tmp = (int) (9); 
          int _a3tmp = (int)(8); 
          int _a2tmp = (int)(7); 
          int _a1tmp = (int)(6); 
          _a1 = _a1tmp; 
          register int _a2 asm ("a2") = _a2tmp; 
          register int _a3 asm ("a3") = _a3tmp; 
          register int _a4 asm ("a4") = _a4tmp; 
          register int _v1 asm ("v1") = _v1tmp; 
          _nr = 120;  
          asm volatile (
                          "swi 0x0" 
                          : "=r" (_a1) 
                          : "r" (_nr) , "r" (_a1), "r" (_a2),
                           "r" (_a3), "r" (_a4), "r" (_v1) : "memory" ); _a1; }); }

    相应的汇编代码:

    test:                                                                                                              
        stmfd   sp!, {r4, r7, fp}
        add fp, sp, #8
        sub sp, sp, #28
    
        mov r3, #0
        str r3, [fp, #-32]
    
        mov r3, #9
        str r3, [fp, #-28]
    
        mov r3, #8
        str r3, [fp, #-24]
    
        mov r3, #7
        str r3, [fp, #-20]
    
        mov r3, #6
        str r3, [fp, #-16]
    
        ldr r0, [fp, #-16]
        ldr r1, [fp, #-20]
        ldr r2, [fp, #-24]
        ldr r3, [fp, #-28]
        ldr r4, [fp, #-32]
        mov r7, #120
    #APP
    @ 16 "go.c" 1
        swi 0x0
    @ 0 "" 2
        sub sp, fp, #8
        ldmfd   sp!, {r4, r7, fp}
        bx  lr
  • 相关阅读:
    Visual Stdio VS 错误 error : 0xC00000FD: Stack overflow. 更改堆栈空间解决栈溢出问题
    OpenCV Mat 只能用静态数组定义时初始化,动态数组赋值给Mat需要逐元素进行. MATLAB,OpenCV,VS混合编程
    【转】Ubuntu 10.10升级显卡驱动后开机动画低分辨率问题
    linux 文件[名]编码
    L337 Speak及国外论坛、IRC常用缩写
    UCS2 手机SMS的PDU编码
    setuid
    【转】CentOS5.5硬盘安装
    SWT CTabFolder 简记
    [转] 程序员的十层楼
  • 原文地址:https://www.cnblogs.com/openix/p/3274260.html
Copyright © 2020-2023  润新知