- {
- asection *plt, *gotplt, *relplt;
-
- /* Return and discard space for dynamic relocations against it if
- it is never referenced in a non-shared object. */
- if (!h->ref_regular)
- {
- if (h->plt.refcount > 0
- || h->got.refcount > 0)
- abort ();
- h->got.offset = (bfd_vma) -1;
- eh->dyn_relocs = NULL;
- return TRUE;
- }
-
- if (h->plt.refcount <= 0)
- abort ();
-
- /* When building a static executable, use .iplt, .igot.plt and
- .rel.iplt sections for STT_GNU_IFUNC symbols. */
- if (htab->splt != 0)
- {
- plt = htab->splt;
- gotplt = htab->sgotplt;
- relplt = htab->srelplt;
-
- /* If this is the first .plt entry, make room for the special
- first entry. */
- if (plt->size == 0)
- plt->size += PLT_ENTRY_SIZE;
- }
- else
- {
- plt = htab->iplt;
- gotplt = htab->igotplt;
- relplt = htab->irelplt;
- }
-
- /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need
- the original value for R_386_IRELATIVE. */
- h->plt.offset = plt->size;
-
- /* Make room for this entry in the .plt/.iplt section. */
- plt->size += PLT_ENTRY_SIZE;
-
- /* We also need to make an entry in the .got.plt/.got.iplt
- section, which will be placed in the .got section by the
- linker script. */
- gotplt->size += 4;
-
- /* We also need to make an entry in the .rela.plt/.rela.iplt
- section. */
- relplt->size += sizeof (Elf32_External_Rel);
- relplt->reloc_count++;
-
- /* No need for dynamic relocation for local STT_GNU_IFUNC symbol.
- Discard space for relocations against it. */
- if (h->dynindx == -1 || h->forced_local)
- eh->dyn_relocs = NULL;
-
- /* STT_GNU_IFUNC symbol uses .got.plt, not .got. But for
- shared library, we must go through GOT and we can't
- use R_386_IRELATIVE unless it is forced local. */
- if (info->executable
- || info->symbolic
- || h->forced_local)
- {
- if (h->pointer_equality_needed
- && htab->sgot != NULL)
- {
- /* We can't use .got.plt, which contains the real
- function addres, since we need pointer equality.
- We will load the GOT entry with the PLT entry
- in elf_i386_finish_dynamic_symbol and don't
- need GOT relocation. */
- h->got.offset = htab->sgot->size;
- htab->sgot->size += 4;
- eh->tlsdesc_got = (bfd_vma) -1;
- goto skip_relgot;
- }
- else
- h->got.refcount = 0;
- }
- }