0

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?

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
Sayaki
  • 769
  • 14
  • 36

1 Answers1

1

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

Community
  • 1
  • 1
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • So when my application will be load to RAM it will lands in lower bits right? If I would like to dump memmory from RAM I should look for memory which reside between 0x00 and 0x268000? – Sayaki Aug 14 '16 at 20:32
  • 1
    No! Your binary will be mapped in virtual memory exactly as it's written in the `otool` output - at address 0x0000000100000000, i.e. just above the 4 GB boundary. All the space below it is reserved for an "invalid" page, which segfaults whenever someone tries to access it. Where does it land in physical RAM is completely irrelevant (and depends from the whims of the operating system - it can actually be moved around transparently, e.g. in case it's swapped out). – Matteo Italia Aug 14 '16 at 21:30
  • Ok, I get everything now. THX for help :) – Sayaki Aug 14 '16 at 22:10