【问题标题】:OSX ld: why does pagezero_size default to 4GB on 64b OSX?OSX ld:为什么 pagezero_size 在 64b OSX 上默认为 4GB?
【发布时间】:2018-04-05 13:56:19
【问题描述】:

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

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

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

使用此标志并覆盖默认值是否有任何问题? Apple Store 规则,...?

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

【问题讨论】:

  • 我猜想,看过 x86_64 寻址模式后,这不会“花费”任何东西,因为寻址模式并不真正支持短地址。同时,如果您禁止较低的 4GB 寻址,那么您将强制程序为 64b 干净。但是,这是 OSX 的事情,GNU ld 不这样做,也不提供此开关。
  • ld64/Options.cpp 中的代码说: case CPU_TYPE_ARM64: case CPU_TYPE_X86_64: // 所有操作系统上 x86_64 的前 4GB fZeroPageSize = 0x100000000ULL;休息;所以 x86_64 和 ARMv8 是 4GB,但没有说明原因。
  • 一个用“cc -pagezero_size=0x1000 test.c”编译+链接的简单的hello world程序立即以“Killed: 9”终止。用“otool -l a.out|more”查看 a.out,它缺少 __PAGEZERO 部分。与“cc -pagezero_size=0x0000000100000000 test.c”的结果相同。所以你不能随便将 PAGEZERO 大小设置为 4096。
  • “这意味着我根本不能使用 32b 绝对寻址”——这是一件好事,因为 macho64 文件格式根本不支持它。即使您更改了标志,汇编器也不会让您生成包含 32 位绝对寻址的 macho64 目标文件。请参阅 herehere。目的似乎是使所有 32 位指针无效,这有好处。
  • 谢谢,但我打算将一个页面 mmap() 到低 4GB,然后使用正常的 64b 寄存器寻址。我有一个很好的理由。是的,我确实认为 Apple 出于 64b 清洁度和 ASLR 的原因试图使所有 32b 点无效。是的,我认为没有办法解决这个问题。

标签: macos x86-64 ld


【解决方案1】:

-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)
...

【讨论】:

  • 命令行叮当声。 Apple LLVM 版本 9.0.0 (clang-900.0.38) 应该是最新的+最好的。谢谢。这对我有用。 Wine 使用它是有道理的,很高兴知道我处于良好的领域,因为我认为我不是。
猜你喜欢
  • 2015-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-05
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
相关资源
最近更新 更多