[Bug target/88954] __attribute__((noplt)) doesn't work with function pointers

2019-01-23 Thread hjl.tools at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88954

H.J. Lu  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |FIXED
   Target Milestone|--- |9.0

--- Comment #8 from H.J. Lu  ---
(In reply to nsz from comment #7)
> note that with
> 
> void f_noplt(void) __attribute__((noplt));
> void (*p)(void) = f_noplt;
> 
> the linker may create a PLT for f_noplt and use its address to initialize p
> in
> case of non-pie linking.
> 
> alternatively the linker may emit a dynamic relocation for p so it is filled
> in
> by the dynamic linker to the actual address of f_noplt.
> 
> it seems the bfd linker on x86_64 does the latter (if there is otherwise no
> PLT),
> but e.g. the gold linker does the former. (as far as the sysv abi is
> concerned
> both behaviours are correct, the linker does not know about the noplt attr.)
> 
> this means that (depending on linker behaviour) a noplt function may get a
> PLT in
> non-pie executables (so noplt can only avoid lazy binding and jump slot
> relocs
> reliably in pic code), may be linkers should be fixed so noplt always avoids
> PLT
> (on x86_64, other targets have other issues with non-pic), but then this has
> to
> be abi to be reliable.

Gold doesn't have the same optimization as bfd linker on x86.  This is just
one of them.

[Bug target/88954] __attribute__((noplt)) doesn't work with function pointers

2019-01-23 Thread nsz at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88954

nsz at gcc dot gnu.org changed:

   What|Removed |Added

 CC||nsz at gcc dot gnu.org

--- Comment #7 from nsz at gcc dot gnu.org ---
note that with

void f_noplt(void) __attribute__((noplt));
void (*p)(void) = f_noplt;

the linker may create a PLT for f_noplt and use its address to initialize p in
case of non-pie linking.

alternatively the linker may emit a dynamic relocation for p so it is filled in
by the dynamic linker to the actual address of f_noplt.

it seems the bfd linker on x86_64 does the latter (if there is otherwise no
PLT),
but e.g. the gold linker does the former. (as far as the sysv abi is concerned
both behaviours are correct, the linker does not know about the noplt attr.)

this means that (depending on linker behaviour) a noplt function may get a PLT
in
non-pie executables (so noplt can only avoid lazy binding and jump slot relocs
reliably in pic code), may be linkers should be fixed so noplt always avoids
PLT
(on x86_64, other targets have other issues with non-pic), but then this has to
be abi to be reliable.

[Bug target/88954] __attribute__((noplt)) doesn't work with function pointers

2019-01-22 Thread hjl at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88954

--- Comment #6 from hjl at gcc dot gnu.org  ---
Author: hjl
Date: Tue Jan 22 14:53:41 2019
New Revision: 268152

URL: https://gcc.gnu.org/viewcvs?rev=268152=gcc=rev
Log:
i386: Load external function address via GOT slot

With noplt attribute, we load the external function address via the GOT
slot so that linker won't create an PLT entry for extern function address.

gcc/

PR target/88954
* config/i386/i386.c (ix86_force_load_from_GOT_p): Also check
noplt attribute.

gcc/testsuite/

PR target/88954
* gcc.target/i386/pr88954-1.c: New test.
* gcc.target/i386/pr88954-2.c: Likewise.

Added:
trunk/gcc/testsuite/gcc.target/i386/pr88954-1.c
trunk/gcc/testsuite/gcc.target/i386/pr88954-2.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/config/i386/i386.c
trunk/gcc/testsuite/ChangeLog

[Bug target/88954] __attribute__((noplt)) doesn't work with function pointers

2019-01-22 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88954

--- Comment #5 from Richard Biener  ---
For indirect calls the attributes on the function type pointed to a relevant. 
Unioning attributes from the actually called function (if the compiler can
figure that out) can be appropriate depending on the actual attribute.

[Bug target/88954] __attribute__((noplt)) doesn't work with function pointers

2019-01-21 Thread hjl.tools at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88954

--- Comment #4 from H.J. Lu  ---
(In reply to Martin Sebor from comment #3)
> My question is about the change you are proposing.  How do you expect g() to
> be called if the test case from comment #0 is modified for example as
> follows:
> 
>   void f_plt(void);
>   void f_noplt(void) __attribute__((noplt));
>   void (*p_noplt)(void) = f_noplt;
>   void g(void (*)(void));
> 
>   int main()
>   {
> if (getenv ("USE_PLT"))
>   p_noplt = f_plt;   // should this be diagnosed?

f_plt will be handled by

00404020  00060007 R_X86_64_JUMP_SLO 00401040 f_plt + 0

> g (p_noplt);
>   }
> 
> In most other cases, initializing a pointer with the address of a function
> declared with some function attribute (e.g., const, nonnull, noreturn, pure,
> or warn_unused_result) doesn't transfer the special properties to the
> pointer, so I'm trying to understand what semantics you are after and if
> there is any potential for user errors and decide whether they should be
> detected.
> 
> I happen to think it would make sense to make it possible to imbue function
> pointers with some (but not all) of the same attributes as those that apply
> to functions, but there certainly are cases where doing so could cause
> problems, just as there are cases where not doing so can.

__attribute__((noplt)) only applies to functions, which instructors
compiler to avoid PLT when accessing the marked function, via function
pointer nor direct call.  The function pointer itself has no impact
on PLT.

[Bug target/88954] __attribute__((noplt)) doesn't work with function pointers

2019-01-21 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88954

--- Comment #3 from Martin Sebor  ---
My question is about the change you are proposing.  How do you expect g() to be
called if the test case from comment #0 is modified for example as follows:

  void f_plt(void);
  void f_noplt(void) __attribute__((noplt));
  void (*p_noplt)(void) = f_noplt;
  void g(void (*)(void));

  int main()
  {
if (getenv ("USE_PLT"))
  p_noplt = f_plt;   // should this be diagnosed?

g (p_noplt);
  }

In most other cases, initializing a pointer with the address of a function
declared with some function attribute (e.g., const, nonnull, noreturn, pure, or
warn_unused_result) doesn't transfer the special properties to the pointer, so
I'm trying to understand what semantics you are after and if there is any
potential for user errors and decide whether they should be detected.

I happen to think it would make sense to make it possible to imbue function
pointers with some (but not all) of the same attributes as those that apply to
functions, but there certainly are cases where doing so could cause problems,
just as there are cases where not doing so can.

[Bug target/88954] __attribute__((noplt)) doesn't work with function pointers

2019-01-21 Thread hjl.tools at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88954

--- Comment #2 from H.J. Lu  ---
(In reply to Martin Sebor from comment #1)
> I'm wondering if noplt is meant to be a property of the function pointer or
> that of its type?
> 
> Either way, what should happen in cases when a noplt pointer is assigned the
> address of a PLT function?  E.g.,:
> 
>   void (*p_noplt)(void) = f_noplt;
> 
>   void f (int i)
>   {
> if (i < 0)
>   p_noplt = f_plt;
>   }
> 
> Do calls through p_noplt still happen without the use of the PLT after the
> assignment?  Should a warning be issued when a noplt pointer is assigned the
> address of an ordinary PLT function?

noplt attribute only applies to function, not function pointer.

[Bug target/88954] __attribute__((noplt)) doesn't work with function pointers

2019-01-21 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88954

Martin Sebor  changed:

   What|Removed |Added

 CC||msebor at gcc dot gnu.org

--- Comment #1 from Martin Sebor  ---
I'm wondering if noplt is meant to be a property of the function pointer or
that of its type?

Either way, what should happen in cases when a noplt pointer is assigned the
address of a PLT function?  E.g.,:

  void (*p_noplt)(void) = f_noplt;

  void f (int i)
  {
if (i < 0)
  p_noplt = f_plt;
  }

Do calls through p_noplt still happen without the use of the PLT after the
assignment?  Should a warning be issued when a noplt pointer is assigned the
address of an ordinary PLT function?