首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Pintos - syscalls项目2

Pintos - syscalls项目2
EN

Stack Overflow用户
提问于 2018-10-04 10:30:12
回答 1查看 943关注 0票数 0

我一边做Pintos项目,一边学习更多关于操作系统的知识。我完成了项目1,并开始了第二个项目。我已经验证了安装堆栈,并且正在工作(通过hex_dump)。现在我在获取正确的syscall参数时遇到了问题。

在user/syscall.c中,有4个程序集存根(0-4个存根)由用户syscall包装。

代码语言:javascript
复制
 #define syscall3(NUMBER, ARG0, ARG1, ARG2)                      \
    ({                                                      \
      int retval;                                           \
      asm volatile                                          \
        ("pushl %[arg2]; pushl %[arg1]; pushl %[arg0]; "    \
         "pushl %[number]; int $0x30; addl $16, %%esp"      \
           : "=a" (retval)                                  \
           : [number] "i" (NUMBER),                         \
             [arg0] "g" (ARG0),                             \
             [arg1] "g" (ARG1),                             \
             [arg2] "g" (ARG2)                              \
           : "memory");                                     \
      retval;                                               \
    }) (this code is given to us)

我的syscall_handler中有一些代码可以调用内核中的正确函数。

代码语言:javascript
复制
static void syscall_handler (struct intr_frame *f) {

  uint32_t *args = f->esp;
  if (args[0] == SYS_WRITE) {
    f->eax = write(args);
  }

在我的write函数中,我打印出了FD和大小

代码语言:javascript
复制
int sysCallNumber = (int) args[0];
  int fd = (int) args[1];
  const char *buffer = (char *) args[2];
  unsigned size = (unsigned) args[3];

  printf("FD is %d\n", fd);
  printf("Size is %d\n", size);

运行'echo hello stack overflow 1 22 333‘将产生以下结果。注意:我在括号中添加了注释。() <-有些地方搞砸了,FD被大小覆盖(包括空终止符)

代码语言:javascript
复制
FD is 6    (hello)
Size is 6
FD is 6     (stack)
Size is 6
FD is 9    (overflow)
Size is 9
FD is 2    (1)
Size is 2
FD is 3    (22)
Size is 3
FD is 4    (333)
Size is 4
FD is 1   (this is from the printf("\n") in echo.c)
Size is 1

我用GDB设置断点和转储框架来运行它,但是还不能解决这个问题。有没有人遇到过类似的情况?如果是这样,你是如何修复它的?

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2018-10-14 22:08:53

我最近在user/syscall.c中发现了一个可能会影响你的bug。尝试将此修补程序应用于user/syscall.c

代码语言:javascript
复制
diff --git a/src/lib/user/syscall.c b/src/lib/user/syscall.c
index a9c5bc8..efeb38c 100644
--- a/src/lib/user/syscall.c
+++ b/src/lib/user/syscall.c
@@ -10,7 +10,7 @@
             ("pushl %[number]; int $0x30; addl $4, %%esp"       \
                : "=a" (retval)                                  \
                : [number] "i" (NUMBER)                          \
-               : "memory");                                     \
+               : "memory", "esp");                              \
           retval;                                               \
         })

@@ -24,7 +24,7 @@
                : "=a" (retval)                                           \
                : [number] "i" (NUMBER),                                  \
                  [arg0] "g" (ARG0)                                       \
-               : "memory");                                              \
+               : "memory", "esp");                                       \
           retval;                                                        \
         })

@@ -40,7 +40,7 @@
                : [number] "i" (NUMBER),                         \
                  [arg0] "g" (ARG0),                             \
                  [arg1] "g" (ARG1)                              \
-               : "memory");                                     \
+               : "memory", "esp");                              \
           retval;                                               \
         })

@@ -57,7 +57,7 @@
                  [arg0] "g" (ARG0),                             \
                  [arg1] "g" (ARG1),                             \
                  [arg2] "g" (ARG2)                              \
-               : "memory");                                     \
+               : "memory", "esp" );                             \
           retval;                                               \
         })

说来话长..。

例如,在宏syscall3中,预期要生成的汇编代码如下所示

代码语言:javascript
复制
pushl ARG2
pushl ARG1
pushl ARG0
pushl NUMBER
int  $0x30
addl $16, %esp

只要堆栈看起来与预期完全一样,这就应该可以工作,只需推送中断指令即可。下面是测试程序(由objdump -d pintos/src/userprog/build/tests/userprog/args-many生成)中反汇编的write函数:

代码语言:javascript
复制
0804a1a5 <write>:
 804a1a5:       ff 74 24 0c             pushl  0xc(%esp)
 804a1a9:       ff 74 24 08             pushl  0x8(%esp)
 804a1ad:       ff 74 24 04             pushl  0x4(%esp)
 804a1b1:       6a 09                   push   $0x9
 804a1b3:       cd 30                   int    $0x30
 804a1b5:       83 c4 10                add    $0x10,%esp
 804a1b8:       c3                      ret

这些指令有一个很大的问题。因为参数是相对于堆栈指针%esp被压入堆栈的,所以错误的参数被压入堆栈!这是因为在每条pushl指令之后,%esp都会改变。

在深入研究了针对gcc的asm扩展语法之后,我认为我找到了正确的修复方法。对于每个syscall*,需要将%esp寄存器添加到扩展asm指令中的Clobbers列表中。这是因为每条pushl指令都会间接地修改%esp,所以我们需要将修改通知给gcc,这样它就不会在生成的指令中不正确地使用%esp

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52638134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档