Joe.Wu Joe.Wu - 1 month ago 10
C Question

Function of shared library is loaded at different physical addresses for different processes

I get physical addresses of function "printf" in libc.so in two programs, and two physical addresses are different. And I read two different physical address, the content are almost the same. This means function "printf" has two copies in memory?

Details:


  1. My os is 32-bit linux.

  2. Physical address is calculated by read "/proc/self/pagemap".

  3. Physical address reading is implemented with fmem module, whose source code is at git@github.com:NateBrune/fmem.git


Answer

I get physical addresses of function "printf" in libc.so in two programs, and two physical addresses are different.

You are probably doing it wrong (but it's hard to guess: you didn't provide any details).

In particular, note that the following program:

#include <stdio.h>

int main()
{
  printf("&printf: %p\n", &printf);
  return 0;
}

does not print the actual address of printf in libc.so.6, as can be observed with GDB:

(gdb) start
Temporary breakpoint 1 at 0x8048426: file pagemap.c, line 5.
Starting program: /tmp/pagemap

Temporary breakpoint 1, main () at pagemap.c:5
5     printf("&printf: %p\n", &printf);
(gdb) n
&printf: 0x80482f0
6     return 0;

(gdb) info symbol 0x80482f0
printf@plt in section .plt of /tmp/pagemap

(gdb) p &printf
$1 = (<text variable, no debug info> *) 0xf7e5add0 <printf>

(gdb) info sym 0xf7e5add0
printf in section .text of /lib32/libc.so.6

Note that printf @0x80482f0 is in the main executable, and is not supposed to be shared (except between multiple instances of the same executable running at the same time), and is not where code for printf actually resides.

The printf @0xf7e5add0 is in libc.so.6, and that is where code for printf actually is. That page is supposed to be shared by all processes using libc.so.6.

P.S. To get the actual address of printf in libc.so.6, one may use this program instead:

#include <stdio.h>
#include <dlfcn.h>

int main()
{
  printf("&printf: %p\n", &printf);
  printf("&printf: %p\n", dlsym(RTLD_NEXT, "printf"));
  return 0;
}

gcc -g pagemap.c -o pagemap -m32 -ldl -D_GNU_SOURCE

(gdb) run
Starting program: /tmp/pagemap
&printf: 0x80483c0
&printf: 0xf7e55dd0

(gdb) info sym 0xf7e55dd0
printf in section .text of /lib32/libc.so.6
Comments