zoukankan      html  css  js  c++  java
  • fork 至 “sys_clone" SyS_clone

    注:glibc-2.17中fork的相应系统调用是sys_clone及SyS_clone。有人说调用的是sys_fork,但是我持否定意见,如果我们向真的来发起系统调用可以使用syscall。

    fork系统调用等价于直接调用的就是

    do_fork(CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHILD,

                 NULL, NULL, NULL, &THREAD_SELF->tid)。&THREAD_SELF->tid放在svc状态下的栈上,前四个参数在r0~r3中。

    比较简单,sys_clone实际上是SyS_clone

    __vectors_start:
    #....
            W(ldr)  pc, .LCvswi + stubs_offset  //将vector_swi的标号值给pc
    #....
    
    .LCvswi:
        .word   vector_swi                                                                                             

    swi流程

    sys_call_table:

    CALL(sys_clone)                                                                                

    sys_clone与SyS_clone的关系

    SYSCALL_ALIAS(sys##name, SyS##name); 
    
    #define SYSCALL_ALIAS(alias, name)  
        asm ( #alias " = " #name " .globl " #alias)

    SyS_clone何时触发了do_fork()

    #define __SYSCALL_DEFINEx(x, name, ...)                 
        asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));  
        static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__));  
        asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__))   
        {                               
            long ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__));  
            __MAP(x,__SC_TEST,__VA_ARGS__);             
            __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__));   
            return ret;                     
        }                               
    ..........
    
    static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__))                                                  
    {
        return do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr);
    }

    先参考http://www.cnblogs.com/openix/archive/2012/02/25/2367557.html

    下面抽取了细节,有点繁琐,主要是一些宏的使用(可变“参数”的宏,宏的字符串转化,宏粘贴),方法倒是蛮好的:

    SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
             int __user *, parent_tidptr,
             int __user *, child_tidptr,
             int, tls_val)
    {
        return do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr);
    }
    #define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) 

    #define SYSCALL_DEFINEx(x, sname, ...)             
        __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)


    #define __SYSCALL_DEFINEx(x, name, ...)      
    asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); 
        static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)); 
        asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__))  
        {                              
            long ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__)); 
            __MAP(x,__SC_TEST,__VA_ARGS__);            
            __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__));  
            return ret;                    
        }                              
        SYSCALL_ALIAS(sys##name, SyS##name);
    static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)

    如何__MAP的实现

    #define __SC_STR_TDECL(t, a)  #t 
    #define __SC_STR_TDECL(t, a) #a #define __SC_DECL(t, a) t a #define __SC_CAST(t, a) (t)a #define __SC_LONG(t, a)
    __typeof(__builtin_choose_expr( __TYPE_IS_LL(t), 0LL, 0L)) a #define __same_type(a, b)
    __builtin_types_compatible_p(typeof(a), typeof(b)) #define __TYPE_IS_LL(t)
    (__same_type((t)0, 0LL) || __same_type((t)0, 0ULL)) #define __MAP0(m, ...) #define __MAP1(m, t, a) m(t, a) #define __MAP2(m, t, a, ...) m(t, a), __MAP1(m, __VA_ARGS__) #define __MAP3(m, t, a, ...) m(t, a), __MAP2(m, __VA_ARGS__) #define __MAP4(m, t, a, ...) m(t, a), __MAP3(m, __VA_ARGS__) #define __MAP5(m, t, a, ...) m(t, a), __MAP4(m, __VA_ARGS__) #define __MAP6(m, t, a, ...) m(t, a), __MAP5(m, __VA_ARGS__) #define __MAP(n, ...) __MAP##n(__VA_ARGS__)

    关于汇编中的宏,可以有默认参数,参考arm的kernel中  ct_user_exit    使用。                                                                            

  • 相关阅读:
    运动员排成绩————————对多个数组进行排序
    关于指针 用字符数组,字符指针变量输入字符串 动态为字符型指针变量分配内存
    axel 原来求中点我想复杂了 两个结果一样
    Bezier曲线绘制 B样条绘制
    最大的回文子串
    字符数组
    按位与、或、异或等运算方法
    uniapp mixin 使用
    vue mixin执行覆盖
    windows10 安装NASM
  • 原文地址:https://www.cnblogs.com/openix/p/3274671.html
Copyright © 2011-2022 走看看