+ if (htab->sgot && htab->sgot->size > 0)
+ elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize
+ = GOT_ENTRY_SIZE;
+
+ return TRUE;
+}
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+elf64_x86_64_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
+}
+
+/* Handle an x86-64 specific section when reading an object file. This
+ is called when elfcode.h finds a section with an unknown type. */
+
+static bfd_boolean
+elf64_x86_64_section_from_shdr (bfd *abfd,
+ Elf_Internal_Shdr *hdr,
+ const char *name,
+ int shindex)
+{
+ if (hdr->sh_type != SHT_X86_64_UNWIND)
+ return FALSE;
+
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. We use it to put SHN_X86_64_LCOMMON items in .lbss, instead
+ of .bss. */
+
+static bfd_boolean
+elf64_x86_64_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp, bfd_vma *valp)
+{
+ asection *lcomm;
+
+ switch (sym->st_shndx)
+ {
+ case SHN_X86_64_LCOMMON:
+ lcomm = bfd_get_section_by_name (abfd, "LARGE_COMMON");
+ if (lcomm == NULL)
+ {
+ lcomm = bfd_make_section_with_flags (abfd,
+ "LARGE_COMMON",
+ (SEC_ALLOC
+ | SEC_IS_COMMON
+ | SEC_LINKER_CREATED));
+ if (lcomm == NULL)
+ return FALSE;
+ elf_section_flags (lcomm) |= SHF_X86_64_LARGE;
+ }
+ *secp = lcomm;
+ *valp = sym->st_size;
+ break;
+ }
+ return TRUE;
+}
+
+
+/* Given a BFD section, try to locate the corresponding ELF section
+ index. */
+
+static bfd_boolean
+elf64_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec, int *index)
+{
+ if (sec == &_bfd_elf_large_com_section)
+ {
+ *index = SHN_X86_64_LCOMMON;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Process a symbol. */
+
+static void
+elf64_x86_64_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
+ asymbol *asym)
+{
+ elf_symbol_type *elfsym = (elf_symbol_type *) asym;
+
+ switch (elfsym->internal_elf_sym.st_shndx)
+ {
+ case SHN_X86_64_LCOMMON:
+ asym->section = &_bfd_elf_large_com_section;
+ asym->value = elfsym->internal_elf_sym.st_size;
+ /* Common symbol doesn't set BSF_GLOBAL. */
+ asym->flags &= ~BSF_GLOBAL;
+ break;
+ }
+}
+
+static bfd_boolean
+elf64_x86_64_common_definition (Elf_Internal_Sym *sym)
+{
+ return (sym->st_shndx == SHN_COMMON
+ || sym->st_shndx == SHN_X86_64_LCOMMON);
+}
+
+static unsigned int
+elf64_x86_64_common_section_index (asection *sec)
+{
+ if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
+ return SHN_COMMON;
+ else
+ return SHN_X86_64_LCOMMON;
+}
+
+static asection *
+elf64_x86_64_common_section (asection *sec)
+{
+ if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
+ return bfd_com_section_ptr;
+ else
+ return &_bfd_elf_large_com_section;
+}
+
+static bfd_boolean
+elf64_x86_64_merge_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry **sym_hash ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym,
+ asection **psec,
+ bfd_vma *pvalue ATTRIBUTE_UNUSED,
+ unsigned int *pold_alignment ATTRIBUTE_UNUSED,
+ bfd_boolean *skip ATTRIBUTE_UNUSED,
+ bfd_boolean *override ATTRIBUTE_UNUSED,
+ bfd_boolean *type_change_ok ATTRIBUTE_UNUSED,
+ bfd_boolean *size_change_ok ATTRIBUTE_UNUSED,
+ bfd_boolean *newdef ATTRIBUTE_UNUSED,
+ bfd_boolean *newdyn,
+ bfd_boolean *newdyncommon ATTRIBUTE_UNUSED,
+ bfd_boolean *newweak ATTRIBUTE_UNUSED,
+ bfd *abfd ATTRIBUTE_UNUSED,
+ asection **sec,
+ bfd_boolean *olddef ATTRIBUTE_UNUSED,
+ bfd_boolean *olddyn,
+ bfd_boolean *olddyncommon ATTRIBUTE_UNUSED,
+ bfd_boolean *oldweak ATTRIBUTE_UNUSED,
+ bfd *oldbfd,
+ asection **oldsec)
+{
+ /* A normal common symbol and a large common symbol result in a
+ normal common symbol. We turn the large common symbol into a
+ normal one. */
+ if (!*olddyn
+ && h->root.type == bfd_link_hash_common
+ && !*newdyn
+ && bfd_is_com_section (*sec)
+ && *oldsec != *sec)
+ {
+ if (sym->st_shndx == SHN_COMMON
+ && (elf_section_flags (*oldsec) & SHF_X86_64_LARGE) != 0)
+ {
+ h->root.u.c.p->section
+ = bfd_make_section_old_way (oldbfd, "COMMON");
+ h->root.u.c.p->section->flags = SEC_ALLOC;
+ }
+ else if (sym->st_shndx == SHN_X86_64_LCOMMON
+ && (elf_section_flags (*oldsec) & SHF_X86_64_LARGE) == 0)
+ *psec = *sec = bfd_com_section_ptr;
+ }
+