因为想跟踪下在新建进程时,如何处理新建进程的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

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

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

  1. #define LOAD_ARGS_0()
  2. #define ASM_ARGS_0
  3.  
  4. #define LOAD_ARGS_1(a1) \
  5. int _a1tmp = (int)(a1); \
  6. LOAD_ARGS_0 () \
  7. _a1 = _a1tmp;
  8.  
  9. #define ASM_ARGS_1 ASM_ARGS_0, "r" (_a1)
  10.  
  11. #define LOAD_ARGS_2(a1, a2) \
  12. int _a2tmp = (int)(a2); \
  13. LOAD_ARGS_1(a1) \
  14. register int _a2 asm ("a2") = _a2tmp;
  15.  
  16. #define ASM_ARGS_2 ASM_ARGS_1, "r" (_a2)
  17.  
  18. #define LOAD_ARGS_3(a1, a2, a3) \
  19. int _a3tmp = (int)(a3); \
  20. LOAD_ARGS_2 (a1, a2) \
  21. register int _a3 asm ("a3") = _a3tmp;
  22.  
  23. #define ASM_ARGS_3 ASM_ARGS_2, "r" (_a3)
  24.  
  25. #define LOAD_ARGS_4(a1, a2, a3, a4) \
  26. int _a4tmp = (int) (a4); \
  27. LOAD_ARGS_3 (a1, a2, a3) \
  28. register int _a4 asm ("a4") = _a4tmp;
  29.  
  30. #define ASM_ARGS_4 ASM_ARGS_3, "r" (_a4)
  31.  
  32. #define LOAD_ARGS_5(a1, a2, a3, a4, a5) \
  33. int _v1tmp = (int)(a5); \
  34. LOAD_ARGS_4 (a1, a2, a3, a4) \
  35. register int _v1 asm ("v1") = _v1tmp;
  36.  
  37. #define ASM_ARGS_5 ASM_ARGS_4, "r" (_v1)
  38.  
  39. #define INTERNAL_SYSCALL_RAW(name, err, nr, args...) \
  40. ({ \
  41. register int _a1 asm("r0"), _nr asm("r7"); \
  42. LOAD_ARGS_5 (args) \
  43. _nr = name; \
  44. asm volatile ("swi 0x0" \
  45. : "=r" (_a1) \
  46. : "r" (_nr) ASM_ARGS_##nr \
  47. : "memory" \
  48. ); \
  49. _a1; \
  50. })
  51.  
  52. void test(void)
  53. {
  54. INTERNAL_SYSCALL_RAW(, , , , , , , );
  55. }

预处理后即为:

  1. void test(void)
  2. {
  3. ({
  4. register int _a1 asm("r0"), _nr asm("r7");
  5. int _v1tmp = (int)();
  6. int _a4tmp = (int) ();
  7. int _a3tmp = (int)();
  8. int _a2tmp = (int)();
  9. int _a1tmp = (int)();
  10. _a1 = _a1tmp;
  11. register int _a2 asm ("a2") = _a2tmp;
  12. register int _a3 asm ("a3") = _a3tmp;
  13. register int _a4 asm ("a4") = _a4tmp;
  14. register int _v1 asm ("v1") = _v1tmp;
  15. _nr = ;
  16. asm volatile (
  17. "swi 0x0"
  18. : "=r" (_a1)
  19. : "r" (_nr) , "r" (_a1), "r" (_a2),
                           "r" (_a3), "r" (_a4), "r" (_v1)
  20. : "memory"
  21. );
  22. _a1;
  23. });
  24. }

相应的汇编代码:

  1. test:
  2. stmfd sp!, {r4, r7, fp}
  3. add fp, sp, #
  4. sub sp, sp, #
  5.  
  6. mov r3, #
  7. str r3, [fp, #-]
  8.  
  9. mov r3, #
  10. str r3, [fp, #-]
  11.  
  12. mov r3, #
  13. str r3, [fp, #-]
  14.  
  15. mov r3, #
  16. str r3, [fp, #-]
  17.  
  18. mov r3, #
  19. str r3, [fp, #-]
  20.  
  21. ldr r0, [fp, #-]
  22. ldr r1, [fp, #-]
  23. ldr r2, [fp, #-]
  24. ldr r3, [fp, #-]
  25. ldr r4, [fp, #-]
  26. mov r7, #
  27. #APP
  28. @ "go.c"
  29. swi 0x0
  30. @ ""
  31. sub sp, fp, #
  32. ldmfd sp!, {r4, r7, fp}
  33. bx lr

glibc中fork系统调用传参的更多相关文章

  1. 用 set follow-fork-mode child即可。这是一个 gdb 命令,其目的是告诉 gdb 在目标应用调用fork之后接着调试子进程而不是父进程,因为在 Linux 中fork系统调用成功会返回两次,一次在父进程,一次在子进程

    GDB的那些奇淫技巧 evilpan 收录于 Security  2020-09-13  约 5433 字   预计阅读 11 分钟  709 次阅读  gdb也用了好几年了,虽然称不上骨灰级玩家,但 ...

  2. 在ListBoxItem的样式中的button传参,把当前选中项传递到命令的方法

    原文:在ListBoxItem的样式中的button传参,把当前选中项传递到命令的方法 前端页面: <Style x:Key="ThumbItemStyle" TargetT ...

  3. Angular 项目开发中父子组件传参

    在项目开发中经常会遇到 组件之间传参的问题.今天总结下在使用angular的项目中父子组件传参的问题: 1.父组件向子组件传参: 然后在父组件中 然后在父组件的html中 然后就可以在子组件中使用了 ...

  4. jq中的ajax传参

        一.   jq中的Ajax传参有两种           1.通过url地址来传参    2.通过data来传递参数 1. url来传递参数 function GetQuery(id) { | ...

  5. Python中的引用传参

    Python中函数参数是引用传递(注意不是值传递).对于不可变类型,因变量不能修改,所以运算不会影响到变量自身:而对于可变类型来说,函数体中的运算有可能会更改传入的参数变量. 引用传参一: >& ...

  6. JS中onclick事件传参

    美术馆案例中,需要将“增加一个img标签,放入大图片”这样一个函数封装,但是在调用的时候需要传参. <script type="text/javascript"> on ...

  7. springMVC中controller的传参的几种案例

    1.springmvc的controller方法不指定method时,默认get/post都支持 //@RequestMapping(value="test") //@Reques ...

  8. python中给函数传参是传值还是传引用

    首先还是应该科普下函数参数传递机制,传值和传引用是什么意思? 函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用发生时进行通信的方法问题.基本的参数传递机制有两种:值传递和引用传 ...

  9. vue中的路由传参及跨组件传参

    路由跳转   this.$router.push('/course'); this.$router.push({name: course}); this.$router.go(-1); this.$r ...

随机推荐

  1. Spring Batch中job的启动,停止,放弃操作

    1,启动一个job 运行一个批处理任务至少有两点要求:一个 JobLauncher 和一个用来运行的 job .它们都包含了相同或是不同的 context .举例来说,从命令行来启动job,会为每一个 ...

  2. linux下mysql重置密码并且远程可以访问

    .重置mysql密码: 杀死所有的yum myql进程: pkill mysql; 查看端口 netstat 端口号杀死) 修改my.cnf文件,在[mysqld]下加入skip-grant-tabl ...

  3. JAVA实用工具--javamail

    在实现javamail之前首先要搭建邮件服务器 James 在进行WEB程序开发的时候需要使用Tomcat服务器,但是Tomcat服务器并不支持邮件的处理操作,所以要想进行邮件的发送,还需要配置一个单 ...

  4. wcf消息契约

    1.最多一个参数和一个返回值,返回值和参数的类型都是消息类型. 下面的代码为定义一个消息契约的实例 [MessageContract]    public class MyMessage    {   ...

  5. composer安装与应用

    操作环境:centos 6.5+32bit 1. 建立项目目录 mkdir test cd test 2. 在当前目录下安装: $ curl -sS https://getcomposer.org/i ...

  6. Linux 下编译出现 undefined reference to `pthread_create'

    这是由于没有链接线程库的原因,只要在编译的时候加入: -lpthread 参数即可. arm-linux-gcc serial.c -o serial -lpthread 查看 ubuntu 版本的命 ...

  7. c++------------提取文件中的信息

    对于文件比较复杂的时候,为了获取文件中的信息,需要一些比较特殊的函数,比如,getline().replace().atoi,atof等 例子一,读取以下文件中的数据,并保存进一个类里面. 首先,类的 ...

  8. c# 连等算式都在做什么

    在研究两个整数互换的方法时(详细看这里),发现了一个有趣的现象. a ^= b ^= a ^= b; ≠ a ^= b;b ^= a;a ^= b; 有兴趣的童鞋可以看看下面代码的结果是什么: int ...

  9. Hive Tuning(五) 标准调优清单

    Hive的标准调优清单,我们可以对照着来做我们的查询优化!

  10. 汉字转拼音首字母的java实现

    工作中经常会遇到的一些排序问题,比如 按汉字的拼音首字母排序,比如人名排序等,就要用到下面的方法了,思路: 1. 获得汉字 2. 将汉字转换成首字母,并记录下(必要时保存到数据库) 3. 按首字母进行 ...