title: Do dynamic libraries have the same virtual memory address in all programs?
body: <p>When a library is dynamically linked to a program does it have the same address in that program as in any other program?</p>
  
  <p>I my head I imagined each process gets the whole of the address space and then everything in that process (inc. dynamic libraries that are already in memory) gets mapped to semi-random parts of it because of ASLR.</p>
  
  <p>But I did a short experiment that seems to imply that the address of libraries that are in memory are fixed across different processes and thus reusable across programs? Is that correct?</p>
  
  <p>I wrote two short c programs which used the "sleep" function. In one I printed out the address of the sleep function and in the second I assigned a function pointer to that address. I ran them both and the sleep function worked in both.</p>
  
  <pre class="lang-c prettyprint-override"><code>#include &lt;stdio.h&gt;
  #include &lt;unistd.h&gt;
  
  int main()
  {
      while(1)
      {
          printf("%s\n", &amp;"hi");
          sleep(2);
          printf("pointer to sleep: %p\n", sleep);
      }
  }
  </code></pre>
  
  <pre class="lang-c prettyprint-override"><code>#include &lt;stdio.h&gt;
  #include &lt;unistd.h&gt;
  
  #define sleepagain ((void (*)(int))0x7fff7652e669) //addr of sleep from first program
  
  int main()
  {
      while(1)
      {
          printf("%s\n", &amp;"test");
          sleepagain(2);
      }
  }
  </code></pre>
  
  <p>I wasn't sure what this would show but what it actually showed was a) the address was the same every time I ran the first program and b) that sleep still functioned when I ran the second.</p>
  
  <p>I think I understand how this works but I am curious if it <em>has</em> to work the way it does and what are the reasons behind it?</p>
  
  <p>Just to reference the answer I got already when I took a look with <code>otool -IvV</code> I got:</p>
  
  <pre><code>a.out:
  Indirect symbols for (__TEXT,__stubs) 2 entries
  address            index name
  0x0000000100000f62     2 _printf
  0x0000000100000f68     3 _sleep
  Indirect symbols for (__DATA,__nl_symbol_ptr) 2 entries
  address            index name
  0x0000000100001000     4 dyld_stub_binder
  0x0000000100001008 ABSOLUTE
  Indirect symbols for (__DATA,__got) 1 entries
  address            index name
  0x0000000100001010     3 _sleep
  Indirect symbols for (__DATA,__la_symbol_ptr) 2 entries
  address            index name
  0x0000000100001018     2 _printf
  0x0000000100001020     3 _sleep
  </code></pre>
  
  <p>Which is also what the indirect address was in lldb. The address was the address of sleep itself:</p>
  
  <pre><code>Process 11209 launched: 'stuff/a.out' (x86_64)
  hi
  Process 11209 stopped
  * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
      frame #0: 0x00007fff7652e669 libsystem_c.dylib`sleep
  libsystem_c.dylib`sleep:
  -&gt;  0x7fff7652e669 &lt;+0&gt;: push   rbp
      0x7fff7652e66a &lt;+1&gt;: mov    rbp, rsp
      0x7fff7652e66d &lt;+4&gt;: push   rbx
      0x7fff7652e66e &lt;+5&gt;: sub    rsp, 0x28
  Target 0: (a.out) stopped.
  </code></pre>
  
  <p>For some additional info:</p>
  
  <pre><code>$ otool -hv a.out
  Mach header
        magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
  MH_MAGIC_64  X86_64        ALL LIB64     EXECUTE    15       1296   NOUNDEFS DYLDLINK TWOLEVEL PIE
  </code></pre>