* [PATCH] man3/dlopen.3: Describe confusing dladdr() behavior
@ 2008-12-05 2:44 Petr Baudis
[not found] ` <20081205024452.GM10491-DDGJ70k9y3lX+M3pkMnKjw@public.gmane.org>
0 siblings, 1 reply; 5+ messages in thread
From: Petr Baudis @ 2008-12-05 2:44 UTC (permalink / raw)
To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-man-u79uwXL29TY76Z2rM5mHXA, drepper-H+wXaHxf7aLQT0dZR+AlfA
dladdr() will act unexpectedly if called from non-pic code on a
compile-time-generated function pointer:
> #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;
> }
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 <pasky-AlSwsSmVLrQ@public.gmane.org>
diff --git a/man3/dlopen.3 b/man3/dlopen.3
index d302360..649c449 100644
--- a/man3/dlopen.3
+++ b/man3/dlopen.3
@@ -30,8 +30,9 @@
.\" Modified by Matt Domsch, 2003-04-09: _init and _fini obsolete
.\" Modified by Michael Kerrisk <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2003-05-16.
.\" Modified by Walter Harms: dladdr, dlvsym
+.\" Modified by Petr Baudis <pasky-AlSwsSmVLrQ@public.gmane.org>, 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 majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 5+ messages in thread[parent not found: <20081205024452.GM10491-DDGJ70k9y3lX+M3pkMnKjw@public.gmane.org>]
* Re: [PATCH] man3/dlopen.3: Describe confusing dladdr() behavior [not found] ` <20081205024452.GM10491-DDGJ70k9y3lX+M3pkMnKjw@public.gmane.org> @ 2008-12-05 22:50 ` Michael Kerrisk [not found] ` <cfd18e0f0812051450q438f9564w2f1aa7a82a993990-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 0 siblings, 1 reply; 5+ messages in thread From: Michael Kerrisk @ 2008-12-05 22:50 UTC (permalink / raw) To: Petr Baudis Cc: linux-man-u79uwXL29TY76Z2rM5mHXA, drepper-H+wXaHxf7aLQT0dZR+AlfA Petr, Thanks for the patch! On Thu, Dec 4, 2008 at 9:44 PM, Petr Baudis <pasky-AlSwsSmVLrQ@public.gmane.org> wrote: > dladdr() will act unexpectedly if called from non-pic code on a > compile-time-generated function pointer: > >> #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. > 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 <pasky-AlSwsSmVLrQ@public.gmane.org> > > diff --git a/man3/dlopen.3 b/man3/dlopen.3 > index d302360..649c449 100644 > --- a/man3/dlopen.3 > +++ b/man3/dlopen.3 > @@ -30,8 +30,9 @@ > .\" Modified by Matt Domsch, 2003-04-09: _init and _fini obsolete > .\" Modified by Michael Kerrisk <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2003-05-16. > .\" Modified by Walter Harms: dladdr, dlvsym > +.\" Modified by Petr Baudis <pasky-AlSwsSmVLrQ@public.gmane.org>, 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. > + The convention in man-pages is not to add blank lines before .SS / .SH. Dropped. > .SS History > The dlopen interface standard comes from SunOS. > That system also has > .BR dladdr (), > but not > .BR dlvsym (). > + See above. > +.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".) > +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 > 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. > +the final symbol address from the > +.I GOT (I added "Global Offset Table") > +at runtime before passing it to > +.BR dladdr (). > + > .SH EXAMPLE > Load the math library, and print the cosine of 2.0: > .nf Cheers, Michael -- 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 majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 5+ messages in thread
[parent not found: <cfd18e0f0812051450q438f9564w2f1aa7a82a993990-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>]
* Re: [PATCH] man3/dlopen.3: Describe confusing dladdr() behavior [not found] ` <cfd18e0f0812051450q438f9564w2f1aa7a82a993990-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> @ 2008-12-05 22:55 ` Michael Kerrisk 2008-12-06 10:01 ` Petr Baudis 1 sibling, 0 replies; 5+ messages in thread From: Michael Kerrisk @ 2008-12-05 22:55 UTC (permalink / raw) To: Petr Baudis Cc: linux-man-u79uwXL29TY76Z2rM5mHXA, drepper-H+wXaHxf7aLQT0dZR+AlfA Petr, Below the changelog entry and diff that I actually applied. Cheers, Michael commit ce02f233b3e884fe1fa303d5694ead012b298410 Author: Petr Baudis <pasky-AlSwsSmVLrQ@public.gmane.org> 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 <pasky-AlSwsSmVLrQ@public.gmane.org> Signed-off-by: Michael Kerrisk <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> diff --git a/man3/dlopen.3 b/man3/dlopen.3 index d302360..43fba7c 100644 --- a/man3/dlopen.3 +++ b/man3/dlopen.3 @@ -30,8 +30,9 @@ .\" Modified by Matt Domsch, 2003-04-09: _init and _fini obsolete .\" Modified by Michael Kerrisk <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2003-05-16. .\" Modified by Walter Harms: dladdr, dlvsym +.\" Modified by Petr Baudis <pasky-AlSwsSmVLrQ@public.gmane.org>, 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 majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] man3/dlopen.3: Describe confusing dladdr() behavior [not found] ` <cfd18e0f0812051450q438f9564w2f1aa7a82a993990-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 2008-12-05 22:55 ` Michael Kerrisk @ 2008-12-06 10:01 ` Petr Baudis [not found] ` <20081206100155.GZ10491-DDGJ70k9y3lX+M3pkMnKjw@public.gmane.org> 1 sibling, 1 reply; 5+ messages in thread From: Petr Baudis @ 2008-12-06 10:01 UTC (permalink / raw) To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w Cc: linux-man-u79uwXL29TY76Z2rM5mHXA, drepper-H+wXaHxf7aLQT0dZR+AlfA Hi! On Fri, Dec 05, 2008 at 05:50:25PM -0500, Michael Kerrisk wrote: > On Thu, Dec 4, 2008 at 9:44 PM, Petr Baudis <pasky-AlSwsSmVLrQ@public.gmane.org> wrote: > > +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. > > 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. 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.) On Fri, Dec 05, 2008 at 05:55:28PM -0500, Michael Kerrisk wrote: > @@ -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) The section name is "plt" but the expanded name should be capitalized, while... > +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). > +.BR dladdr (). > .SH EXAMPLE > Load the math library, and print the cosine of 2.0: > .nf -- 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 majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 5+ messages in thread
[parent not found: <20081206100155.GZ10491-DDGJ70k9y3lX+M3pkMnKjw@public.gmane.org>]
* Re: [PATCH] man3/dlopen.3: Describe confusing dladdr() behavior [not found] ` <20081206100155.GZ10491-DDGJ70k9y3lX+M3pkMnKjw@public.gmane.org> @ 2008-12-06 17:11 ` Michael Kerrisk 0 siblings, 0 replies; 5+ messages in thread From: Michael Kerrisk @ 2008-12-06 17:11 UTC (permalink / raw) To: Petr Baudis Cc: linux-man-u79uwXL29TY76Z2rM5mHXA, drepper-H+wXaHxf7aLQT0dZR+AlfA Hi Petr, Thanks for checking the patch. On Sat, Dec 6, 2008 at 5:01 AM, Petr Baudis <pasky-AlSwsSmVLrQ@public.gmane.org> wrote: > Hi! > > On Fri, Dec 05, 2008 at 05:50:25PM -0500, Michael Kerrisk wrote: >> On Thu, Dec 4, 2008 at 9:44 PM, Petr Baudis <pasky-AlSwsSmVLrQ@public.gmane.org> wrote: >> > +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. Fair enough. I removed "gcc -fPIC". >> > 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. > > What about "code generated by today's gcc"? Yep, i made it something like that. > (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.) > > On Fri, Dec 05, 2008 at 05:55:28PM -0500, Michael Kerrisk wrote: >> @@ -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) > > The section name is "plt" but the expanded name should be capitalized, > while... Done. >> +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). Done. >> +.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 --- a/man3/dlopen.3 +++ b/man3/dlopen.3 @@ -32,7 +32,7 @@ .\" Modified by Walter Harms: dladdr, dlvsym .\" Modified by Petr Baudis <pasky-AlSwsSmVLrQ@public.gmane.org>, 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 majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-12-06 17:11 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-12-05 2:44 [PATCH] man3/dlopen.3: Describe confusing dladdr() behavior Petr Baudis
[not found] ` <20081205024452.GM10491-DDGJ70k9y3lX+M3pkMnKjw@public.gmane.org>
2008-12-05 22:50 ` Michael Kerrisk
[not found] ` <cfd18e0f0812051450q438f9564w2f1aa7a82a993990-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-12-05 22:55 ` Michael Kerrisk
2008-12-06 10:01 ` Petr Baudis
[not found] ` <20081206100155.GZ10491-DDGJ70k9y3lX+M3pkMnKjw@public.gmane.org>
2008-12-06 17:11 ` Michael Kerrisk
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox