public inbox for linux-man@vger.kernel.org
 help / color / mirror / Atom feed
* [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

* 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

* 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

* 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