Linux C program: How to find the library to which a function belongs
Clash Royale CLAN TAG#URR8PPP
up vote
6
down vote
favorite
Say at runtime, I want to find out where a function "printf" is defined. How would I do this?
My first attempt was to print out the address of "printf" and compare it against the virtual address mapping of the process:
my program:
#include <stdio.h>
#include <unistd.h>
void main()
printf("address of printf is 0x%Xn", printf);
printf("pid is %dn", getpid());
while (1);
output:
-bash-4.1$ ./a &
[1] 28837
-bash-4.1$ address of printf is 0x4003F8
pid is 28837
However, this says the function is defined in my own program!
-bash-4.1$ head /proc/28837/maps
00400000-00401000 r-xp 00000000 08:06 6946857 /data2/temp/del/a <<<<<<< Address 0x4003F8 is in my own program?
00600000-00601000 rw-p 00000000 08:06 6946857 /data2/temp/del/a
397ec00000-397ec20000 r-xp 00000000 08:11 55837039 /lib64/ld-2.12.so
397ee1f000-397ee20000 r--p 0001f000 08:11 55837039 /lib64/ld-2.12.so
397ee20000-397ee21000 rw-p 00020000 08:11 55837039 /lib64/ld-2.12.so
397ee21000-397ee22000 rw-p 00000000 00:00 0
397f000000-397f18a000 r-xp 00000000 08:11 55837204 /lib64/libc-2.12.so
397f18a000-397f38a000 ---p 0018a000 08:11 55837204 /lib64/libc-2.12.so
397f38a000-397f38e000 r--p 0018a000 08:11 55837204 /lib64/libc-2.12.so
397f38e000-397f38f000 rw-p 0018e000 08:11 55837204 /lib64/libc-2.12.so
Shouldnt it be a call into libc? How do I find out where this "printf" or any other function came from?
c linux
 |Â
show 8 more comments
up vote
6
down vote
favorite
Say at runtime, I want to find out where a function "printf" is defined. How would I do this?
My first attempt was to print out the address of "printf" and compare it against the virtual address mapping of the process:
my program:
#include <stdio.h>
#include <unistd.h>
void main()
printf("address of printf is 0x%Xn", printf);
printf("pid is %dn", getpid());
while (1);
output:
-bash-4.1$ ./a &
[1] 28837
-bash-4.1$ address of printf is 0x4003F8
pid is 28837
However, this says the function is defined in my own program!
-bash-4.1$ head /proc/28837/maps
00400000-00401000 r-xp 00000000 08:06 6946857 /data2/temp/del/a <<<<<<< Address 0x4003F8 is in my own program?
00600000-00601000 rw-p 00000000 08:06 6946857 /data2/temp/del/a
397ec00000-397ec20000 r-xp 00000000 08:11 55837039 /lib64/ld-2.12.so
397ee1f000-397ee20000 r--p 0001f000 08:11 55837039 /lib64/ld-2.12.so
397ee20000-397ee21000 rw-p 00020000 08:11 55837039 /lib64/ld-2.12.so
397ee21000-397ee22000 rw-p 00000000 00:00 0
397f000000-397f18a000 r-xp 00000000 08:11 55837204 /lib64/libc-2.12.so
397f18a000-397f38a000 ---p 0018a000 08:11 55837204 /lib64/libc-2.12.so
397f38a000-397f38e000 r--p 0018a000 08:11 55837204 /lib64/libc-2.12.so
397f38e000-397f38f000 rw-p 0018e000 08:11 55837204 /lib64/libc-2.12.so
Shouldnt it be a call into libc? How do I find out where this "printf" or any other function came from?
c linux
2
haha. At runtime, how would I find it? Please note that 'printf' is only a simplistic example.
â Sush
1 hour ago
1
Such as printf. Why is there any difference at run time? if you don't know at compile time, it won't compile/link. You do know, so why establish that at run time?
â Weather Vane
1 hour ago
2
pseudocodesystem("man %s | grep .h")
(just kidding)
â ti7
1 hour ago
2
@ti7 (and others). Let's try not to confuse libraries with headers.
â rici
1 hour ago
3
@weather: where does that manpage say that printf is in libc.so?
â rici
1 hour ago
 |Â
show 8 more comments
up vote
6
down vote
favorite
up vote
6
down vote
favorite
Say at runtime, I want to find out where a function "printf" is defined. How would I do this?
My first attempt was to print out the address of "printf" and compare it against the virtual address mapping of the process:
my program:
#include <stdio.h>
#include <unistd.h>
void main()
printf("address of printf is 0x%Xn", printf);
printf("pid is %dn", getpid());
while (1);
output:
-bash-4.1$ ./a &
[1] 28837
-bash-4.1$ address of printf is 0x4003F8
pid is 28837
However, this says the function is defined in my own program!
-bash-4.1$ head /proc/28837/maps
00400000-00401000 r-xp 00000000 08:06 6946857 /data2/temp/del/a <<<<<<< Address 0x4003F8 is in my own program?
00600000-00601000 rw-p 00000000 08:06 6946857 /data2/temp/del/a
397ec00000-397ec20000 r-xp 00000000 08:11 55837039 /lib64/ld-2.12.so
397ee1f000-397ee20000 r--p 0001f000 08:11 55837039 /lib64/ld-2.12.so
397ee20000-397ee21000 rw-p 00020000 08:11 55837039 /lib64/ld-2.12.so
397ee21000-397ee22000 rw-p 00000000 00:00 0
397f000000-397f18a000 r-xp 00000000 08:11 55837204 /lib64/libc-2.12.so
397f18a000-397f38a000 ---p 0018a000 08:11 55837204 /lib64/libc-2.12.so
397f38a000-397f38e000 r--p 0018a000 08:11 55837204 /lib64/libc-2.12.so
397f38e000-397f38f000 rw-p 0018e000 08:11 55837204 /lib64/libc-2.12.so
Shouldnt it be a call into libc? How do I find out where this "printf" or any other function came from?
c linux
Say at runtime, I want to find out where a function "printf" is defined. How would I do this?
My first attempt was to print out the address of "printf" and compare it against the virtual address mapping of the process:
my program:
#include <stdio.h>
#include <unistd.h>
void main()
printf("address of printf is 0x%Xn", printf);
printf("pid is %dn", getpid());
while (1);
output:
-bash-4.1$ ./a &
[1] 28837
-bash-4.1$ address of printf is 0x4003F8
pid is 28837
However, this says the function is defined in my own program!
-bash-4.1$ head /proc/28837/maps
00400000-00401000 r-xp 00000000 08:06 6946857 /data2/temp/del/a <<<<<<< Address 0x4003F8 is in my own program?
00600000-00601000 rw-p 00000000 08:06 6946857 /data2/temp/del/a
397ec00000-397ec20000 r-xp 00000000 08:11 55837039 /lib64/ld-2.12.so
397ee1f000-397ee20000 r--p 0001f000 08:11 55837039 /lib64/ld-2.12.so
397ee20000-397ee21000 rw-p 00020000 08:11 55837039 /lib64/ld-2.12.so
397ee21000-397ee22000 rw-p 00000000 00:00 0
397f000000-397f18a000 r-xp 00000000 08:11 55837204 /lib64/libc-2.12.so
397f18a000-397f38a000 ---p 0018a000 08:11 55837204 /lib64/libc-2.12.so
397f38a000-397f38e000 r--p 0018a000 08:11 55837204 /lib64/libc-2.12.so
397f38e000-397f38f000 rw-p 0018e000 08:11 55837204 /lib64/libc-2.12.so
Shouldnt it be a call into libc? How do I find out where this "printf" or any other function came from?
c linux
c linux
asked 2 hours ago
Sush
382314
382314
2
haha. At runtime, how would I find it? Please note that 'printf' is only a simplistic example.
â Sush
1 hour ago
1
Such as printf. Why is there any difference at run time? if you don't know at compile time, it won't compile/link. You do know, so why establish that at run time?
â Weather Vane
1 hour ago
2
pseudocodesystem("man %s | grep .h")
(just kidding)
â ti7
1 hour ago
2
@ti7 (and others). Let's try not to confuse libraries with headers.
â rici
1 hour ago
3
@weather: where does that manpage say that printf is in libc.so?
â rici
1 hour ago
 |Â
show 8 more comments
2
haha. At runtime, how would I find it? Please note that 'printf' is only a simplistic example.
â Sush
1 hour ago
1
Such as printf. Why is there any difference at run time? if you don't know at compile time, it won't compile/link. You do know, so why establish that at run time?
â Weather Vane
1 hour ago
2
pseudocodesystem("man %s | grep .h")
(just kidding)
â ti7
1 hour ago
2
@ti7 (and others). Let's try not to confuse libraries with headers.
â rici
1 hour ago
3
@weather: where does that manpage say that printf is in libc.so?
â rici
1 hour ago
2
2
haha. At runtime, how would I find it? Please note that 'printf' is only a simplistic example.
â Sush
1 hour ago
haha. At runtime, how would I find it? Please note that 'printf' is only a simplistic example.
â Sush
1 hour ago
1
1
Such as printf. Why is there any difference at run time? if you don't know at compile time, it won't compile/link. You do know, so why establish that at run time?
â Weather Vane
1 hour ago
Such as printf. Why is there any difference at run time? if you don't know at compile time, it won't compile/link. You do know, so why establish that at run time?
â Weather Vane
1 hour ago
2
2
pseudocode
system("man %s | grep .h")
(just kidding)â ti7
1 hour ago
pseudocode
system("man %s | grep .h")
(just kidding)â ti7
1 hour ago
2
2
@ti7 (and others). Let's try not to confuse libraries with headers.
â rici
1 hour ago
@ti7 (and others). Let's try not to confuse libraries with headers.
â rici
1 hour ago
3
3
@weather: where does that manpage say that printf is in libc.so?
â rici
1 hour ago
@weather: where does that manpage say that printf is in libc.so?
â rici
1 hour ago
 |Â
show 8 more comments
4 Answers
4
active
oldest
votes
up vote
5
down vote
The address you observe is located in the Procedure Linkage Table (PLT). This mechanism is used, when the location of an external (dynamically linked) symbol is not known at the time, when your binary is compiled and linked.
The purpose is, that the external linkage happens only at one place, the PLT, and not on all places throughout your code where a call to the symbol happens. So, if printf is called, the way is:
main -> printf@PLT -> printf@libc
At runtime, you cannot find out easily in which external library the function you call is located; you would have to parse the opcodes at the destination (the PLT), which usually fetches the address from the .dynamic section and jumps there, then look, where the symbol is really located and finally, parse /proc/pid/maps to get the external library.
add a comment |Â
up vote
2
down vote
1) pointers are "printf"ed using %p, not %X:
printf("address of printf is 0x%pn", printf);
2) If you compile against static libc printf will be linked into your binary
3) when compiled with
gcc -fPIC a.c (older gccs)
...
gcc -fno-plt a.c (gcc 6 and above)
outputs:
address of printf is 0x0x7f40acb522a0
which is inside of
7f40acaff000-7f40accc2000 r-xp 00000000 fd:00 100687388 /usr/lib64/libc-2.17.so
see here: What does @plt mean here? to find more about this
add a comment |Â
up vote
1
down vote
Parse the elf file for the dynamically linked libraries needed. Then you can parse them searching for the required symbol
add a comment |Â
up vote
0
down vote
At runtime, you can use gdb
for this:
(terminal 1)$ ./a
pid is 16614
address of printf is 0x400450
(terminal 2)$ gdb -p 16614
(...)
Attaching to process 16614
(...)
0x00000000004005a4 in main ()
(gdb)
(gdb) info sym printf
printf in section .text of /lib/x86_64-linux-gnu/libc.so.6
If you don't want to interrupt your program or are reluctant to use gdb
, you may also ask ld.so
to output some debugging info:
(terminal 1)$ LD_DEBUG=bindings LD_DEBUG_OUTPUT=syms ./a
pid is 17180
address of printf is 0x400450
(terminal 2)$ fgrep printf syms.17180
17180: binding file ./a [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `printf' [GLIBC_2.2.5]
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
The address you observe is located in the Procedure Linkage Table (PLT). This mechanism is used, when the location of an external (dynamically linked) symbol is not known at the time, when your binary is compiled and linked.
The purpose is, that the external linkage happens only at one place, the PLT, and not on all places throughout your code where a call to the symbol happens. So, if printf is called, the way is:
main -> printf@PLT -> printf@libc
At runtime, you cannot find out easily in which external library the function you call is located; you would have to parse the opcodes at the destination (the PLT), which usually fetches the address from the .dynamic section and jumps there, then look, where the symbol is really located and finally, parse /proc/pid/maps to get the external library.
add a comment |Â
up vote
5
down vote
The address you observe is located in the Procedure Linkage Table (PLT). This mechanism is used, when the location of an external (dynamically linked) symbol is not known at the time, when your binary is compiled and linked.
The purpose is, that the external linkage happens only at one place, the PLT, and not on all places throughout your code where a call to the symbol happens. So, if printf is called, the way is:
main -> printf@PLT -> printf@libc
At runtime, you cannot find out easily in which external library the function you call is located; you would have to parse the opcodes at the destination (the PLT), which usually fetches the address from the .dynamic section and jumps there, then look, where the symbol is really located and finally, parse /proc/pid/maps to get the external library.
add a comment |Â
up vote
5
down vote
up vote
5
down vote
The address you observe is located in the Procedure Linkage Table (PLT). This mechanism is used, when the location of an external (dynamically linked) symbol is not known at the time, when your binary is compiled and linked.
The purpose is, that the external linkage happens only at one place, the PLT, and not on all places throughout your code where a call to the symbol happens. So, if printf is called, the way is:
main -> printf@PLT -> printf@libc
At runtime, you cannot find out easily in which external library the function you call is located; you would have to parse the opcodes at the destination (the PLT), which usually fetches the address from the .dynamic section and jumps there, then look, where the symbol is really located and finally, parse /proc/pid/maps to get the external library.
The address you observe is located in the Procedure Linkage Table (PLT). This mechanism is used, when the location of an external (dynamically linked) symbol is not known at the time, when your binary is compiled and linked.
The purpose is, that the external linkage happens only at one place, the PLT, and not on all places throughout your code where a call to the symbol happens. So, if printf is called, the way is:
main -> printf@PLT -> printf@libc
At runtime, you cannot find out easily in which external library the function you call is located; you would have to parse the opcodes at the destination (the PLT), which usually fetches the address from the .dynamic section and jumps there, then look, where the symbol is really located and finally, parse /proc/pid/maps to get the external library.
answered 1 hour ago
Ctx
8,66481936
8,66481936
add a comment |Â
add a comment |Â
up vote
2
down vote
1) pointers are "printf"ed using %p, not %X:
printf("address of printf is 0x%pn", printf);
2) If you compile against static libc printf will be linked into your binary
3) when compiled with
gcc -fPIC a.c (older gccs)
...
gcc -fno-plt a.c (gcc 6 and above)
outputs:
address of printf is 0x0x7f40acb522a0
which is inside of
7f40acaff000-7f40accc2000 r-xp 00000000 fd:00 100687388 /usr/lib64/libc-2.17.so
see here: What does @plt mean here? to find more about this
add a comment |Â
up vote
2
down vote
1) pointers are "printf"ed using %p, not %X:
printf("address of printf is 0x%pn", printf);
2) If you compile against static libc printf will be linked into your binary
3) when compiled with
gcc -fPIC a.c (older gccs)
...
gcc -fno-plt a.c (gcc 6 and above)
outputs:
address of printf is 0x0x7f40acb522a0
which is inside of
7f40acaff000-7f40accc2000 r-xp 00000000 fd:00 100687388 /usr/lib64/libc-2.17.so
see here: What does @plt mean here? to find more about this
add a comment |Â
up vote
2
down vote
up vote
2
down vote
1) pointers are "printf"ed using %p, not %X:
printf("address of printf is 0x%pn", printf);
2) If you compile against static libc printf will be linked into your binary
3) when compiled with
gcc -fPIC a.c (older gccs)
...
gcc -fno-plt a.c (gcc 6 and above)
outputs:
address of printf is 0x0x7f40acb522a0
which is inside of
7f40acaff000-7f40accc2000 r-xp 00000000 fd:00 100687388 /usr/lib64/libc-2.17.so
see here: What does @plt mean here? to find more about this
1) pointers are "printf"ed using %p, not %X:
printf("address of printf is 0x%pn", printf);
2) If you compile against static libc printf will be linked into your binary
3) when compiled with
gcc -fPIC a.c (older gccs)
...
gcc -fno-plt a.c (gcc 6 and above)
outputs:
address of printf is 0x0x7f40acb522a0
which is inside of
7f40acaff000-7f40accc2000 r-xp 00000000 fd:00 100687388 /usr/lib64/libc-2.17.so
see here: What does @plt mean here? to find more about this
answered 1 hour ago
fukanchik
2,2031520
2,2031520
add a comment |Â
add a comment |Â
up vote
1
down vote
Parse the elf file for the dynamically linked libraries needed. Then you can parse them searching for the required symbol
add a comment |Â
up vote
1
down vote
Parse the elf file for the dynamically linked libraries needed. Then you can parse them searching for the required symbol
add a comment |Â
up vote
1
down vote
up vote
1
down vote
Parse the elf file for the dynamically linked libraries needed. Then you can parse them searching for the required symbol
Parse the elf file for the dynamically linked libraries needed. Then you can parse them searching for the required symbol
answered 1 hour ago
P__J__
7,5912623
7,5912623
add a comment |Â
add a comment |Â
up vote
0
down vote
At runtime, you can use gdb
for this:
(terminal 1)$ ./a
pid is 16614
address of printf is 0x400450
(terminal 2)$ gdb -p 16614
(...)
Attaching to process 16614
(...)
0x00000000004005a4 in main ()
(gdb)
(gdb) info sym printf
printf in section .text of /lib/x86_64-linux-gnu/libc.so.6
If you don't want to interrupt your program or are reluctant to use gdb
, you may also ask ld.so
to output some debugging info:
(terminal 1)$ LD_DEBUG=bindings LD_DEBUG_OUTPUT=syms ./a
pid is 17180
address of printf is 0x400450
(terminal 2)$ fgrep printf syms.17180
17180: binding file ./a [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `printf' [GLIBC_2.2.5]
add a comment |Â
up vote
0
down vote
At runtime, you can use gdb
for this:
(terminal 1)$ ./a
pid is 16614
address of printf is 0x400450
(terminal 2)$ gdb -p 16614
(...)
Attaching to process 16614
(...)
0x00000000004005a4 in main ()
(gdb)
(gdb) info sym printf
printf in section .text of /lib/x86_64-linux-gnu/libc.so.6
If you don't want to interrupt your program or are reluctant to use gdb
, you may also ask ld.so
to output some debugging info:
(terminal 1)$ LD_DEBUG=bindings LD_DEBUG_OUTPUT=syms ./a
pid is 17180
address of printf is 0x400450
(terminal 2)$ fgrep printf syms.17180
17180: binding file ./a [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `printf' [GLIBC_2.2.5]
add a comment |Â
up vote
0
down vote
up vote
0
down vote
At runtime, you can use gdb
for this:
(terminal 1)$ ./a
pid is 16614
address of printf is 0x400450
(terminal 2)$ gdb -p 16614
(...)
Attaching to process 16614
(...)
0x00000000004005a4 in main ()
(gdb)
(gdb) info sym printf
printf in section .text of /lib/x86_64-linux-gnu/libc.so.6
If you don't want to interrupt your program or are reluctant to use gdb
, you may also ask ld.so
to output some debugging info:
(terminal 1)$ LD_DEBUG=bindings LD_DEBUG_OUTPUT=syms ./a
pid is 17180
address of printf is 0x400450
(terminal 2)$ fgrep printf syms.17180
17180: binding file ./a [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `printf' [GLIBC_2.2.5]
At runtime, you can use gdb
for this:
(terminal 1)$ ./a
pid is 16614
address of printf is 0x400450
(terminal 2)$ gdb -p 16614
(...)
Attaching to process 16614
(...)
0x00000000004005a4 in main ()
(gdb)
(gdb) info sym printf
printf in section .text of /lib/x86_64-linux-gnu/libc.so.6
If you don't want to interrupt your program or are reluctant to use gdb
, you may also ask ld.so
to output some debugging info:
(terminal 1)$ LD_DEBUG=bindings LD_DEBUG_OUTPUT=syms ./a
pid is 17180
address of printf is 0x400450
(terminal 2)$ fgrep printf syms.17180
17180: binding file ./a [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `printf' [GLIBC_2.2.5]
answered 6 mins ago
xhienne
1,403415
1,403415
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52599211%2flinux-c-program-how-to-find-the-library-to-which-a-function-belongs%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
2
haha. At runtime, how would I find it? Please note that 'printf' is only a simplistic example.
â Sush
1 hour ago
1
Such as printf. Why is there any difference at run time? if you don't know at compile time, it won't compile/link. You do know, so why establish that at run time?
â Weather Vane
1 hour ago
2
pseudocode
system("man %s | grep .h")
(just kidding)â ti7
1 hour ago
2
@ti7 (and others). Let's try not to confuse libraries with headers.
â rici
1 hour ago
3
@weather: where does that manpage say that printf is in libc.so?
â rici
1 hour ago