man3/dlopen.3: Describe confusing dladdr() behavior
PATCH 1/1 man3/dlopen.3: Describe confusing dladdr() behavior
dladdr() will act unexpectedly if called from non-pic code on a compile-time-generated function pointer:
Quoted 6 lines
#define
_GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>int
main(void)
Quoted 11 lines
{
void *func;
Dl_info info = {};
func = printf;
dladdr(func, &info);
printf("%s at %p resolved from %s\n", info.dli_sname,
func, info.dli_fname);
return 0;
}In the long term, it might make sense to make dladdr() recognize plt pointers and recurse, but I'm too afraid of Ulrich ;-) (and he seems to be heavy proponent of pic code anyway, so the chances for that to be accepted probably aren't high).
man3/dlopen.3 +27 -1
@@ -30,8 +30,9 @@ .\" Modified by Matt Domsch, 2003-04-09: _init and _fini obsolete .\" Modified by Michael Kerrisk <[email protected]> 2003-05-16. .\" Modified by Walter Harms: dladdr, dlvsym +.\" Modified by Petr Baudis <[email protected]>, 2008-12-04: dladdr caveat .\" -.TH DLOPEN 3 2008-10-27 "Linux" "Linux Programmer's Manual" +.TH DLOPEN 3 2008-12-04 "Linux" "Linux Programmer's Manual" .SH NAME dladdr, dlclose, dlerror, dlopen, dlsym, dlvsym \- programming interface to dynamic linking loader
@@ -408,12 +409,37 @@ Since glibc 2.2.3, .BR atexit (3) can be used to register an exit handler that is automatically called when a library is unloaded. + .SS History The dlopen interface standard comes from SunOS. That system also has .BR dladdr (), but not .BR dlvsym (). + +.SH BUGS +Sometimes, the function pointers you pass to +.BR dladdr () +may surprise you. On some architectures (notably i386 and x86_64), +.IR "dli_fname " and " dli_fbase" +may end up pointing back at the object where you called +.BR dladdr () +from, even if the function used as an argument should come from +a dynamically linked library. +.PP +The problem is that the function pointer will still be resolved +at the compile time, but point merely to the +.I plt +section of the original object (which dispatches the call after +asking the dynamic linker to resolve the symbol). +To work this around, you can try to compile the code to be +position-independent: then, the compiler cannot prepare the pointer +at the compile time anymore and today's gcc will just load +the final symbol address from the +.I GOT +at runtime before passing it to +.BR dladdr (). + .SH EXAMPLE Load the math library, and print the cosine of 2.0: .nf
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): [email protected]
Petr,
Thanks for the patch!
Quoted 20 lines · Petr Baudis
dladdr()will act unexpectedly if called from non-pic code on a compile-time-generated function pointer:Quoted 17 lines
#define
_GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>int
main(void){ void *func; Dl_info info = {}; func = printf; dladdr(func, &info); printf("%s at %p resolved from %s\n", info.dli_sname, func, info.dli_fname); return 0;
Thanks for the patch. For the change log, I added sample runs. See my follow-up mail.
I've applied the patch pretty much as you gave it for 3.15. Some notes below, including a question or two.
Quoted 23 lines
In the long term, it might make sense to make
dladdr()recognize plt pointers and recurse, but I'm too afraid of Ulrich ;-) (and he seems to be heavy proponent of pic code anyway, so the chances for that to be accepted probably aren't high).Signed-off-by Petr Baudis <[email protected]>man3/dlopen.3 +2
-1@@ -30,8 +30,9 @@ .\" Modified by Matt Domsch, 2003-04-09: _init and _fini obsolete .\" Modified by Michael Kerrisk <[email protected]> 2003-05-16. .\" Modified by Walter Harms: dladdr, dlvsym +.\" Modified by Petr Baudis <[email protected]>, 2008-12-04: dladdr caveat .\" -.TH DLOPEN 3 2008-10-27 "Linux" "Linux Programmer's Manual" +.TH DLOPEN 3 2008-12-04 "Linux" "Linux Programmer's Manual" .SH NAME dladdr, dlclose, dlerror, dlopen, dlsym, dlvsym \- programming interface to dynamic linking loader
man3/dlopen.3 Since glibc 2.2.3, · line 412
Quoted 4 lines
man3/dlopen.3 +1
-0@@ -408,12 +409,37 @@ Since glibc 2.2.3, .BR atexit (3) can be used to register an exit handler that is automatically called when a library is unloaded. +
The convention in man-pages is not to add blank lines before .SS / .SH. Dropped.
man3/dlopen.3 Since glibc 2.2.3, · line 419
Quoted 7 lines
man3/dlopen.3 +1
-0.SS History The dlopen interface standard comes from SunOS. That system also has .BR dladdr (), but not .BR dlvsym (). +
See above.
man3/dlopen.3 Since glibc 2.2.3, · line 432
Quoted 13 lines
man3/dlopen.3 +13
-0+.SH BUGS +Sometimes, the function pointers you pass to +.BR dladdr () +may surprise you. On some architectures (notably i386 and x86_64), +.IR "dli_fname " and " dli_fbase" +may end up pointing back at the object where you called +.BR dladdr () +from, even if the function used as an argument should come from +a dynamically linked library. +.PP +The problem is that the function pointer will still be resolved +at the compile time, but point merely to the +.I plt
(It would be kind here to explain what "plt" stand as for. I added "Procedure Linkage Table".)
man3/dlopen.3 Since glibc 2.2.3,
Quoted 4 lines
man3/dlopen.3 +4
-0+section of the original object (which dispatches the call after +asking the dynamic linker to resolve the symbol). +To work this around, you can try to compile the code to be +position-independent:
I added: "gcc -fPIC" here
Quoted 2 lines
then, the compiler cannot prepare the pointer
+at the compile time anymore and today's gcc will just load
I made it "gcc(1)", but this doesn't seem quite right. It's not gcc in operation at program run time. can you more precisely say what you mean here.
Quoted 2 lines
+the final symbol address from the
+.I GOT
(I added "Global Offset Table")
man3/dlopen.3 Since glibc 2.2.3, · line 445
Quoted 6 lines
man3/dlopen.3 +3
-0+at runtime before passing it to +.BR dladdr (). + .SH EXAMPLE Load the math library, and print the cosine of 2.0: .nf
Cheers,
Michael
Signature · 9 lines
Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ git://git.kernel.org/pub/scm/docs/man-pages/man-pages.git man-pages online: http://www.kernel.org/doc/man-pages/online_pages.html Found a bug? http://www.kernel.org/doc/man-pages/reporting_bugs.html -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): cfd18e0f0812051450q438f9564w2f1aa7a82a993990-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
Petr,
Below the changelog entry and diff that I actually applied.
Cheers,
Michael
commit ce02f233b3e884fe1fa303d5694ead012b298410
Author: Petr Baudis <[email protected]> Date: Fri Dec 5 17:45:53 2008 -0500
dlopen.3: Describe confusing dladdr() behavior
dladdr() will act unexpectedly if called from non-pic code on a
compile-time-generated function pointer:
/* test_dladdr.c */
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
int
main(void)
{
void *func;
Dl_info info = {};
func = printf;
dladdr(func, &info);
printf("%s at %p resolved from %s\n", info.dli_sname,
func, info.dli_fname);
return 0;
}
$ cc test_dladdr.c -ldl
$ ./a.out
printf at 0x804838c resolved from ./a.out
$ cc -fPIC test_dladdr.c -ldl
$ ./a.out
_IO_printf at 0xb7f71c30 resolved from /lib/libc.so.6
In the long term, it might make sense to make dladdr() recognize
plt pointers and recurse, but I'm too afraid of Ulrich ;-)
(and he seems to be heavy proponent of pic code anyway, so
the chances for that to be accepted probably aren't high).
Signed-off-by: Petr Baudis <[email protected]>
Signed-off-by: Michael Kerrisk <[email protected]>man3/dlopen.3 +30 -1
@@ -30,8 +30,9 @@ .\" Modified by Matt Domsch, 2003-04-09: _init and _fini obsolete .\" Modified by Michael Kerrisk <[email protected]> 2003-05-16. .\" Modified by Walter Harms: dladdr, dlvsym +.\" Modified by Petr Baudis <[email protected]>, 2008-12-04: dladdr caveat .\" -.TH DLOPEN 3 2008-10-27 "Linux" "Linux Programmer's Manual" +.TH DLOPEN 3 2008-12-05 "Linux" "Linux Programmer's Manual" .SH NAME dladdr, dlclose, dlerror, dlopen, dlsym, dlvsym \- programming interface to dynamic linking loader
@@ -414,6 +415,34 @@ That system also has .BR dladdr (), but not .BR dlvsym (). +.SH BUGS +Sometimes, the function pointers you pass to +.BR dladdr () +may surprise you. +On some architectures (notably i386 and x86_64), +.I dli_fname +and +.I dli_fbase +may end up pointing back at the object from which you called +.BR dladdr (), +even if the function used as an argument should come from +a dynamically linked library. +.PP +The problem is that the function pointer will still be resolved +at compile time, but merely point to the +.I plt +(procedure linkage table) +section of the original object (which dispatches the call after +asking the dynamic linker to resolve the symbol). +To work this around, you can try to compile the code to be +position-independent +.RI ( "cc -fPIC" ): then, the compiler cannot prepare the pointer +at compile time anymore and today's +.BR gcc (1) +will just load the final symbol address from the +.I GOT +(Global Offset Table) at run time before passing it to +.BR dladdr (). .SH EXAMPLE Load the math library, and print the cosine of 2.0: .nf
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): cfd18e0f0812051455s5b1800a2ve00dcb21cdd4baa1-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
Hi!
Quoted 7 lines · Michael Kerrisk
man3/dlopen.3 That system also has
Quoted 4 lines · Petr Baudis
man3/dlopen.3 +4
-0+section of the original object (which dispatches the call after +asking the dynamic linker to resolve the symbol). +To work this around, you can try to compile the code to be +position-independent:I added: "gcc -fPIC" here
Sometimes, -fpic might be better idea, for executables -fpie or -fPIE is better choice, which is why I chose not to mention a particular switch. It should be easy to look that up in the gcc manual page and you should understand the implications of this choice before doing it anyway.
Quoted 6 lines
Quoted 2 lines
then, the compiler cannot prepare the pointer
+at the compile time anymore and today's gcc will just loadI made it "gcc(1)", but this doesn't seem quite right. It's not gcc in operation at program run time. can you more precisely say what you mean here.
What about "code generated by today's gcc"? (I don't know if gcc always behaved like that or what do other compilers do, and I'm not willing to do the research in this case.)
Quoted 11 lines · Michael Kerrisk
man3/dlopen.3 +7
-0@@ -414,6 +415,34 @@ That system also has .BR dladdr (), but not .BR dlvsym (). +.SH BUGS +Sometimes, the function pointers you pass to +.BR dladdr () +may surprise you. +On some architectures (notably i386 and x86_64), +.I dli_fname +and
man3/dlopen.3 That system also has · line 434
Quoted 10 lines
man3/dlopen.3 +10
-0+.I dli_fbase +may end up pointing back at the object from which you called +.BR dladdr (), +even if the function used as an argument should come from +a dynamically linked library. +.PP +The problem is that the function pointer will still be resolved +at compile time, but merely point to the +.I plt +(procedure linkage table)
The section name is "plt" but the expanded name should be capitalized, while...
man3/dlopen.3 That system also has · line 444
Quoted 10 lines
man3/dlopen.3 +10
-0+section of the original object (which dispatches the call after +asking the dynamic linker to resolve the symbol). +To work this around, you can try to compile the code to be +position-independent +.RI ( "cc -fPIC" ): then, the compiler cannot prepare the pointer +at compile time anymore and today's +.BR gcc (1) +will just load the final symbol address from the +.I GOT +(Global Offset Table) at run time before passing it to
...here I guess either the acronym is not necessary or it should be "got" for consistency (the section name).
Quoted 4 lines
man3/dlopen.3 +1
-0+.BR dladdr (). .SH EXAMPLE Load the math library, and print the cosine of 2.0: .nf
Signature · 7 lines
Petr "Pasky" Baudis People who take cold baths never have rheumatism, but they have cold baths. -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): [email protected]
Hi Petr,
Thanks for checking the patch.
Quoted 11 lines · Petr Baudis
Hi!
Quoted 7 lines · Michael Kerrisk
Review
Quoted 4 lines · Petr Baudis
(quoted diff) +4
-0+section of the original object (which dispatches the call after +asking the dynamic linker to resolve the symbol). +To work this around, you can try to compile the code to be +position-independent:I added: "gcc -fPIC" here
Quoted 4 lines
Sometimes, -fpic might be better idea, for executables -fpie or -fPIE is better choice, which is why I chose not to mention a particular switch. It should be easy to look that up in the gcc manual page and you should understand the implications of this choice before doing it anyway.
Fair enough. I removed "gcc -fPIC".
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
then, the compiler cannot prepare the pointer
+at the compile time anymore and today's gcc will just loadI made it "gcc(1)", but this doesn't seem quite right. It's not gcc in operation at program run time. can you more precisely say what you mean here.
What about "code generated by today's gcc"?
Yep, i made it something like that.
Quoted 21 lines
(I don't know if gcc always
behaved like that or what do other compilers do, and I'm not willing to do the research in this case.)Quoted 16 lines · Michael Kerrisk
(quoted diff) +12
-0@@ -414,6 +415,34 @@ That system also has .BR dladdr (), but not .BR dlvsym (). +.SH BUGS +Sometimes, the function pointers you pass to +.BR dladdr () +may surprise you. +On some architectures (notably i386 and x86_64), +.I dli_fname +and +.I dli_fbase +may end up pointing back at the object from which you called +.BR dladdr (), +even if the function used as an argument should come from +a dynamically linked library.
Quoted 8 lines
Review That system also has · line 434
Quoted 5 lines
(quoted diff) +5
-0+.PP +The problem is that the function pointer will still be resolved +at compile time, but merely point to the +.I plt +(procedure linkage table)The section name is "plt" but the expanded name should be capitalized, while...
Done.
Quoted 5 lines
Quoted 5 lines
(quoted diff) +5
-0+section of the original object (which dispatches the call after +asking the dynamic linker to resolve the symbol). +To work this around, you can try to compile the code to be +position-independent +.RI ( "cc -fPIC" ): then, the compiler cannot prepare the pointer
Quoted 8 lines
Review That system also has · line 444
Quoted 5 lines
(quoted diff) +5
-0+at compile time anymore and today's +.BR gcc (1) +will just load the final symbol address from the +.I GOT +(Global Offset Table) at run time before passing it to...here I guess either the acronym is not necessary or it should be "got" for consistency (the section name).
Done.
Quoted 4 lines
Review That system also has · line 448
Quoted 4 lines
(quoted diff) +1
-0+.BR dladdr (). .SH EXAMPLE Load the math library, and print the cosine of 2.0: .nf
Below is the change for man-pages-3.16.
Cheers,
Michael
man3/dlopen.3 +6 -7
@@ -32,7 +32,7 @@ .\" Modified by Walter Harms: dladdr, dlvsym .\" Modified by Petr Baudis <[email protected]>, 2008-12-04: dladdr caveat .\" -.TH DLOPEN 3 2008-12-05 "Linux" "Linux Programmer's Manual" +.TH DLOPEN 3 2008-12-06 "Linux" "Linux Programmer's Manual" .SH NAME dladdr, dlclose, dlerror, dlopen, dlsym, dlvsym \- programming interface to dynamic linking loader
@@ -431,17 +431,16 @@ a dynamically linked library. The problem is that the function pointer will still be resolved at compile time, but merely point to the .I plt -(procedure linkage table) +(Procedure Linkage Table) section of the original object (which dispatches the call after asking the dynamic linker to resolve the symbol). -To work this around, you can try to compile the code to be -position-independent -.RI ( "cc -fPIC" ): +To work around this, +you can try to compile the code to be position-independent: then, the compiler cannot prepare the pointer at compile time anymore and today's .BR gcc (1) -will just load the final symbol address from the -.I GOT +will generate code that just loads the final symbol address from the +.I got (Global Offset Table) at run time before passing it to .BR dladdr (). .SH EXAMPLE
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html