virtual-memorysegmentsotoolexecutable-format

How can I use otool to get the size of a binary file?


I'm using otool to get information about my binary. Here is part of my output:

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

We can see here that command 1 with segname __TEXT starts at vmaddr 0x0000000100000000

The problem is that binary size is 2.3MB and 0x0000000100000000 is 4 GB!

I assume that "one" in the middle of address is related to the 64 bit architecture, and 0x0000000100000000 in fact address 0x00. I was looking for some information about that but I didn't find anything useful. Can anyone confirms my assumptions and explain how exactly this is working?


Solution

  • There's nothing strange.

    First an "invalid segment" is reserved in the lower 4 GBs of the address space. This is like the invalid 4 KB or whatever it was kept to make the NULL pointer dereference crash in 32 bit processes, only bigger (this should catch also, for example, any 32 bit integer erroneously cast to pointer). After all, why not? It's virtual memory, it's free. Some more details here.

    Then, your executable text is loaded at the 4 GB boundary. Nothing bad - keep in mind that the lower 4 GBs are not baked by actual memory, they are just marked as reserved.

    In general, it's definitely not strange to have stuff loaded at "high" addresses in a 64 bit address space. The stack, for example, is typically in the zone just below the 48 bit boundaries. It's not like the system have actually to provide all the memory in the middle, virtual memory makes so that only the pages which contain something consume actual memory (RAM or swap space). (actually, there's some cost in the page data structures bookkeeping, but it's generally negligible)

    The size of the binary is instead reported both in the VM size field and in the file size field (0x268000 = 2523136 ≈ 2.4 MB).