OSX ld:为什么 pagezero_size 在 64b OSX 上默认为 4GB?

OSX ld: why does pagezero_size default to 4GB on 64b OSX?

这是一个 OSX 链接器问题。我认为 OSX(BSD 或 Mach 层)不关心零页有多大,或者它是否存在。我认为这是一个工具的事情。但这是我的意见,这就是我问的原因。

-pagezero_size 大小:默认情况下,链接器会创建一个不可读的段,该段从地址零开始,名为 __PAGEZERO。如果取消引用 NULL 指针,它的存在将导致总线错误。

这很清楚;它用于捕获 NULL 指针。在 32b OSX 系统上,段的大小为 4KB,这是系统页面大小。但是在当前的 64b 系统上,这个段的大小增加到 4GB。为什么它不保持系统页面大小 4KB 或体系结构的最大页面大小 2MB?这意味着我根本无法使用 32b 绝对寻址。

使用这个标志并覆盖默认值有什么问题吗? Apple Store 规则,...?

(此功能特定于 OSX ld64 链接器。该功能至少可追溯到 2006 年 3 月的 ld64-47.2。地址 Space 布局随机化和 64b 支持从 2007 年 10 月的 Leopard 开始。 )

-pagezero_size选项是链接器选项,不是编译器选项。因此,当您使用编译器驱动链接时,您需要将其作为 -Wl,-pagezero_size,0x1000 (或任何您想要的大小)传递。这很好用。我作为贡献者的 Wine 项目依赖于此来实现其 64 位构建的兼容性。

我对为什么 64 位的默认页面零大小为 4GB 的理解是为了捕获指针无意中存储在 32 位变量中并因此被截断的情况。当它最终被转换回一个指针时,它将处于低 4GB,因此无效。任何取消引用它的尝试都会导致访问冲突。

更新:

似乎 -pagezero_size 也被识别为一个编译器选项,并且在我的测试中工作得很好。无论哪种方式,我都得到了一个正常运行的可执行文件,并且 otool 显示了所需大小的 __PAGEZERO 段。

您使用的是什么版本的工具?我在 Sierra (10.12.6) 上使用 Xcode 8:

$ cc --version
Apple LLVM version 8.1.0 (clang-802.0.41)
...