【问题标题】:WebAssembly stack / stack pointer initialization and memory layoutWebAssembly 堆栈/堆栈指针初始化和内存布局
【发布时间】:2017-09-24 06:04:55
【问题描述】:

我目前正在玩弄通过 LLVM 编译的 WebAssembly,但我还没有设法理解堆栈/堆栈指针以及它与整体内存布局的关系。

我了解到我必须使用s2wasm--allocate-stack N 来使我的程序运行,我认为这基本上是将(data (i32.const 4) "8\00\00\00")(N=8)添加到我生成的废品中,二进制部分显然是指向内存偏移量的指针,i32 常量是它在线性内存中的偏移量。

不过,我不太明白的是,为什么指针的值为56(N=8)以及该值与内存中堆栈的确切区域的关系,在我的情况下,当前看起来像:

0-3: zero 4-7: 56 7-35: other data sections 36-55: zeroes 56-59: zero

我知道我可能更适合“只使用 emscripten”,但我也想了解这一点。

  • 堆栈指针是否始终存储在线性内存中的偏移量 4 处?
  • 它的初始值是如何计算的? (与数据后的下一个偏移量%16==0 + N 对齐?)
  • 之前存储了什么,之后它指向的偏移量是什么?

【问题讨论】:

    标签: webassembly


    【解决方案1】:

    我在another question 中谈到了这一点。从 C++ 的堆栈中,实际上有 3 个地方的值可以结束:

    1. 在执行堆栈上(每个操作码都推送和弹出值,因此add 弹出 2 然后推送 1)。
    2. 作为本地人。
    3. Memory

    请注意,您不能使用 1. 和 2 的地址。只有在这些情况下,我才希望代码生成器与 3 一起使用。WebAssembly 并不规定如何完成此操作,这取决于您使用的任何 ABI选择。 Emscripten 和其他工具所做的是将堆栈指针存储在地址4,然后在程序的早期,他们选择堆栈应该去的位置。 必须始终为 4,但始终坚持使用该 ABI 会更简单,尤其是在涉及动态链接的情况下。

    关于初始值:该位置必须足够大以容纳整个堆栈,并且malloc 的实现必须知道它,因为它无法在其上分配堆空间。这就是为什么某些工具允许您指定最大尺寸的原因。

    任何东西都可以存储在之前/之后(尽管之后您可能会有先前的堆栈值)。 WebAssembly 目前没有保护页,因此耗尽内存堆栈将破坏堆值(除非代码生成器也发出堆栈检查)。这就是“内存安全”,因为它仍然无法逃脱WebAssembly.Memory,因此浏览器无法拥有,但开发人员自己的代码可以完全拥有。构建在 WebAssembly 之上的内存安全语言必须在 WebAssembly.Memory 内强制执行内存安全。

    请注意,我没有解释 1. 和 2。它们的存在意味着大多数 C++ 程序在 WebAssembly 中使用的内存中堆栈比原生 C++ 程序使用堆栈要少。

    【讨论】:

    • 感谢您的详细解答。我想做的是自己创建一个小运行时来运行一些我用 cmake -> s2wasm -> wast2wasm 编译的超级基本 C 代码。正如您所指出的, malloc 需要知道堆栈的位置,以便它不会分配它。但是它怎么知道呢?假设在使用 binaryen 工具链时,初始堆栈指针值指向 VM 应将堆栈值放置在的最大偏移量(排他性)是否正确 - 并且 malloc 可以使用超出该偏移量的所有内容?
    • 链接器输出__stack_pointer,如果您指定堆栈分配大小,它还会输出一个名为.stack 的重定位,带有该值。不过,这不是唯一的方法,如果您自己动手,我建议您查看tool-conventions,其中建议使用全局堆栈指针。
    • 单独使用 clang/s2wasm/wasm-as 是否可以产生这样的全局?我现在以int stacktop() { int* ptr; return (int)&ptr + sizeof(int*); } 结尾,这可能就像一个从 JS 背景来到 WebAssembly 的人所期望的一样愚蠢。但无论如何,感谢您的耐心等待!
    • 我的意思是WebAssembly binary sense 中的“全局”。这没有来自 C++ 的直接映射:我希望 C++ 全局变量是简单的堆值,除非编译器可以证明地址永远不会转义。
    猜你喜欢
    • 1970-01-01
    • 2012-09-16
    • 2021-11-28
    • 2020-03-09
    • 2019-10-23
    • 2015-08-05
    • 2015-11-16
    • 2013-01-20
    • 2021-09-01
    相关资源
    最近更新 更多