-
- /* When a shared library references a STT_GNU_IFUNC symbol defined
- in executable, the address of the resolved function may be used.
- But in non-shared executable, the address of its .plt slot may
- be used. Pointer equality may not work correctly. PIE should
- be used if pointer equality is required here. */
- if (!info->shared
+ bfd_boolean readonly_dynrelocs_against_ifunc;
+ /* If AVOID_PLT is TRUE, don't use PLT if possible. */
+ bfd_boolean use_plt = !avoid_plt || h->plt.refcount > 0;
+ bfd_boolean need_dynreloc = !use_plt || bfd_link_pic (info);
+
+ /* When a PIC object references a STT_GNU_IFUNC symbol defined
+ in executable or it isn't referenced via PLT, the address of
+ the resolved function may be used. But in non-PIC executable,
+ the address of its .plt slot may be used. Pointer equality may
+ not work correctly. PIE or non-PLT reference should be used if
+ pointer equality is required here.
+
+ If STT_GNU_IFUNC symbol is defined in position-dependent executable,
+ backend should change it to the normal function and set its address
+ to its PLT entry which should be resolved by R_*_IRELATIVE at
+ run-time. All external references should be resolved to its PLT in
+ executable. */
+ if (!need_dynreloc
+ && !(bfd_link_pde (info) && h->def_regular)