温馨提示:本文翻译自stackoverflow.com,查看原文请点击:c - Do I have to add the length of the mapping to a pointer returned by mmap with the MAP_GROWSDOWN and
c linux mmap

c - 我是否必须使用MAP_GROWSDOWN将映射的长度添加到mmap返回的指针,并且

发布于 2020-03-27 11:34:35

我正在为a.out加载程序创建一个简单的堆栈,并提出了以下方案:

stack = (char *)mmap(NULL,
                     65535,
                     PROT_READ | PROT_WRITE,
                     MAP_PRIVATE | MAP_STACK |
                       MAP_GROWSDOWN | MAP_UNINITIALIZED |
                       MAP_ANONYMOUS,
                     -1,
                     0);

但是,我对此不确定。

65535因为使用了MAP_STACKMAP_GROWSDOWN标志,在将其移动到堆栈指针之前,是否必须添加(映射的大小)还是我可以按原样使用它?

关于此的文档还不是很清楚,并且在搜索Internet时我什么也找不到。

具体来说,这(来自mmap(2))使我感到困惑:

返回地址比在进程的虚拟地址空间中实际创建的内存区域低一页。

查看更多

查看更多

提问者
S.S. Anne
被浏览
260
11.5k 2019-07-04 23:53
  1. 是的,您必须将65536添加到结果指针。注意,不是65535。大多数体系结构将push(x)实现为*-sp = x; 因此,将sp 置于堆栈上方是可以的。更重要的是,它必须对齐,而不是65535。

  2. 该文档似乎是错误的。我认为打算“ 比... 一页”。这样可以更好地与源代码实现以及下面的小示例程序的结果保持一致:


  #include <signal.h>
  #include <stdio.h>
  #include <unistd.h>
  #include <sys/mman.h>

  volatile int sp;

  void segv(int signo) {
          char buf[80];
          int n = snprintf(buf, 80, "(%d): sp = %#x\n", signo, sp);
          write(1, buf, n);
           _exit(1);
  }

  int main(void) {
          int N = 65535;
          signal(SIGSEGV, segv);
          signal(SIGBUS, segv);
          char *stack = (char *)mmap(NULL,
                       N,
                       PROT_READ | PROT_WRITE,
                       MAP_PRIVATE | MAP_STACK |
                         MAP_GROWSDOWN | /*MAP_UNINITIALIZED |*/
                         MAP_ANONYMOUS,
                       -1,
                       0);
          printf("stack %p\n", stack);
          for (sp = 0; sp < N; sp += 4096) {
                  if (stack[sp]) {
                          printf("stack[%d] = %x\n", sp, stack[sp]);
                  }
          }
          for (sp = 0; sp > -N; sp -= 4096) {
                  if (stack[sp]) {
                          printf("stack[%d] = %x\n", sp, stack[sp]);
                  }
          }
          return 0;
  }

输出:

$ ./a.out
stack 0x7f805c5fb000
(11): sp = -4096

在我的系统上:

$ uname -a
Linux u2 4.15.0-42-generic #45-Ubuntu SMP Thu Nov 15 19:32:57 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux