【问题标题】:How can I use otool to get the size of a binary file?如何使用 otool 获取二进制文件的大小?
【发布时间】:2016-08-14 05:28:45
【问题描述】:

我正在使用 otool 来获取有关我的二进制文件的信息。这是我的输出的一部分:

Load command 0
      cmd LC_SEGMENT_64
  cmdsize 72
  segname __PAGEZERO
   vmaddr 0x0000000000000000
   vmsize 0x0000000100000000
  fileoff 0
 filesize 0
  maxprot 0x00000000
 initprot 0x00000000
   nsects 0
    flags 0x0
Load command 1
      cmd LC_SEGMENT_64
  cmdsize 952
  segname __TEXT
   vmaddr 0x0000000100000000
   vmsize 0x0000000000268000
  fileoff 0
 filesize 2523136
  maxprot 0x00000005
 initprot 0x00000005
   nsects 11
    flags 0x0

我们可以在这里看到command 1segname __TEXTvmaddr 0x0000000100000000 开始

问题是二进制大小是 2.3MB 而 0x0000000100000000 是 4 GB!

我假设地址中间的“一”与64位架构有关,0x0000000100000000实际上是地址0x00。我一直在寻找有关此的一些信息,但没有发现任何有用的信息。谁能证实我的假设并解释这究竟是如何运作的?

【问题讨论】:

    标签: virtual-memory segments otool executable-format


    【解决方案1】:

    没有什么奇怪的。

    首先在地址空间的低 4 GB 中保留一个“无效段”。这就像无效的 4 KB 或任何它被保留以使 NULL 指针取消引用在 32 位进程中崩溃,只是更大(这也应该捕获,例如,任何 32 位整数错误地转换为指针)。毕竟,为什么不呢?它是虚拟内存,它是免费的。 Some more details here

    然后,您的可执行文本将在 4 GB 边界处加载。没什么不好 - 请记住,较低的 4 GB 不是由实际内存烘焙的,它们只是被标记为保留。

    一般来说,在 64 位地址空间中的“高”地址加载内容绝对不奇怪。例如,堆栈通常位于 48 位边界下方的区域中。这不像系统实际上必须在中间提供所有内存,虚拟内存使得只有包含某些内容的页面才会消耗实际内存(RAM或交换空间)。 (其实页面数据结构记账是有一定成本的,但一般可以忽略不计)

    二进制文件的大小会在 VM 大小字段和文件大小字段中报告 (0x268000 = 2523136 ≈ 2.4 MB)。

    【讨论】:

    • 所以当我的应用程序加载到 RAM 时,它会落在低位,对吗?如果我想从 RAM 中转储内存,我应该寻找位于 0x00 和 0x268000 之间的内存?
    • 不!您的二进制文件将完全按照otool 输出中写入的内容映射到虚拟内存中 - 地址为 0x0000000100000000,即刚好在 4 GB 边界之上。它下面的所有空间都是为“无效”页面保留的,每当有人尝试访问它时都会出现段错误。它在物理 RAM 中的位置是完全不相关的(并且取决于操作系统的突发奇想 - 它实际上可以透明地移动,例如,以防它被换出)。
    • 好的,我现在得到了一切。 THX 寻求帮助:)
    猜你喜欢
    • 2023-01-02
    • 2011-01-31
    • 2012-03-19
    • 1970-01-01
    • 2011-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多