/* Set if a relocation is converted from a GOTPCREL relocation. */
#define R_X86_64_converted_reloc_bit (1 << 7)
-#define IS_X86_64_PCREL_TYPE(TYPE) \
+#define X86_PCREL_TYPE_P(TYPE) \
( ((TYPE) == R_X86_64_PC8) \
|| ((TYPE) == R_X86_64_PC16) \
|| ((TYPE) == R_X86_64_PC32) \
|| ((TYPE) == R_X86_64_PC32_BND) \
|| ((TYPE) == R_X86_64_PC64))
+#define X86_SIZE_TYPE_P(TYPE) \
+ ((TYPE) == R_X86_64_SIZE32 || (TYPE) == R_X86_64_SIZE64)
+
/* Map BFD relocs to the x86_64 elf relocs. */
struct elf_reloc_map
{
DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
};
-/* Architecture-specific backend data for x86-64. */
-
-struct elf_x86_64_backend_data
-{
- /* Target system. */
- enum
- {
- is_normal,
- is_nacl
- } os;
-};
-
-#define get_elf_x86_64_arch_data(bed) \
- ((const struct elf_x86_64_backend_data *) (bed)->arch_data)
-
-#define get_elf_x86_64_backend_data(abfd) \
- get_elf_x86_64_arch_data (get_elf_backend_data (abfd))
-
/* These are the standard parameters. */
static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_plt =
{
sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
};
-static const struct elf_x86_64_backend_data elf_x86_64_arch_bed =
+static const struct elf_x86_backend_data elf_x86_64_arch_bed =
{
is_normal /* os */
};
switch (r_type)
{
case R_X86_64_TLSLD:
- htab->tls_ld_or_ldm_got.refcount += 1;
+ htab->tls_ld_or_ldm_got.refcount = 1;
goto create_got;
case R_X86_64_TPOFF32:
return elf_x86_64_need_pic (info, abfd, sec, h, symtab_hdr, isym,
&x86_64_elf_howto_table[r_type]);
if (eh != NULL)
- eh->has_got_reloc = 1;
+ eh->zero_undefweak &= 0x2;
break;
case R_X86_64_GOTTPOFF:
if (h != NULL)
{
- h->got.refcount += 1;
+ h->got.refcount = 1;
old_tls_type = eh->tls_type;
}
else
elf_x86_local_got_tls_type (abfd)
= (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
}
- local_got_refcounts[r_symndx] += 1;
+ local_got_refcounts[r_symndx] = 1;
old_tls_type
= elf_x86_local_got_tls_type (abfd) [r_symndx];
}
case R_X86_64_GOTPC64:
create_got:
if (eh != NULL)
- eh->has_got_reloc = 1;
+ eh->zero_undefweak &= 0x2;
break;
case R_X86_64_PLT32:
if (h == NULL)
continue;
- eh->has_got_reloc = 1;
+ eh->zero_undefweak &= 0x2;
h->needs_plt = 1;
h->plt.refcount += 1;
break;
case R_X86_64_64:
pointer:
if (eh != NULL && (sec->flags & SEC_CODE) != 0)
- eh->has_non_got_reloc = 1;
+ eh->zero_undefweak |= 0x2;
/* We are called after all symbols have been resolved. Only
relocation against STT_GNU_IFUNC symbol must go through
PLT. */
size_reloc = FALSE;
do_size:
- /* If we are creating a shared library, and this is a reloc
- against a global symbol, or a non PC relative reloc
- against a local symbol, then we need to copy the reloc
- into the shared library. However, if we are linking with
- -Bsymbolic, we do not need to copy a reloc against a
- global symbol which is defined in an object we are
- including in the link (i.e., DEF_REGULAR is set). At
- this point we have not seen all the input files, so it is
- possible that DEF_REGULAR is not set now but will be set
- later (it is never cleared). In case of a weak definition,
- DEF_REGULAR may be cleared later by a strong definition in
- a shared library. We account for that possibility below by
- storing information in the relocs_copied field of the hash
- table entry. A similar situation occurs when creating
- shared libraries and symbol visibility changes render the
- symbol local.
-
- If on the other hand, we are creating an executable, we
- may need to keep relocations for symbols satisfied by a
- dynamic library if we manage to avoid copy relocs for the
- symbol.
-
- Generate dynamic pointer relocation against STT_GNU_IFUNC
- symbol in the non-code section. */
- if ((bfd_link_pic (info)
- && (! IS_X86_64_PCREL_TYPE (r_type)
- || (h != NULL
- && (! (bfd_link_pie (info)
- || SYMBOLIC_BIND (info, h))
- || h->root.type == bfd_link_hash_defweak
- || !h->def_regular))))
- || (h != NULL
- && h->type == STT_GNU_IFUNC
- && r_type == htab->pointer_r_type
- && (sec->flags & SEC_CODE) == 0)
- || (ELIMINATE_COPY_RELOCS
- && !bfd_link_pic (info)
- && h != NULL
- && (h->root.type == bfd_link_hash_defweak
- || !h->def_regular)))
+ if (NEED_DYNAMIC_RELOCATION_P (info, h, sec, r_type,
+ htab->pointer_r_type))
{
struct elf_dyn_relocs *p;
struct elf_dyn_relocs **head;
p->count += 1;
/* Count size relocation as PC-relative relocation. */
- if (IS_X86_64_PCREL_TYPE (r_type) || size_reloc)
+ if (X86_PCREL_TYPE_P (r_type) || size_reloc)
p->pc_count += 1;
}
break;
bfd_boolean resolved_to_zero;
bfd_boolean relative_reloc;
bfd_boolean converted_reloc;
+ bfd_boolean need_copy_reloc_in_pie;
r_type = ELF32_R_TYPE (rel->r_info);
if (r_type == (int) R_X86_64_GNU_VTINHERIT
outrel.r_offset += (input_section->output_section->vma
+ input_section->output_offset);
- if (h->dynindx == -1
- || h->forced_local
- || bfd_link_executable (info))
+ if (POINTER_LOCAL_IFUNC_P (info, h))
{
info->callbacks->minfo (_("Local IFUNC function `%s' in %B\n"),
h->root.root.string,
relative_reloc = FALSE;
if (h != NULL)
{
- bfd_boolean dyn;
-
off = h->got.offset;
if (h->needs_plt
&& h->plt.offset != (bfd_vma)-1
base_got = htab->elf.sgotplt;
}
- dyn = htab->elf.dynamic_sections_created;
-
- if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
- || (bfd_link_pic (info)
- && SYMBOL_REFERENCES_LOCAL_P (info, h))
- || (ELF_ST_VISIBILITY (h->other)
- && h->root.type == bfd_link_hash_undefweak))
+ if (RESOLVED_LOCALLY_P (info, h, htab))
{
- /* This is actually a static link, or it is a -Bsymbolic
- link and the symbol is defined locally, or the symbol
- was forced to be local because of a version file. We
- must initialize this entry in the global offset table.
- Since the offset must always be a multiple of 8, we
- use the least significant bit to record whether we
- have initialized it already.
+ /* We must initialize this entry in the global offset
+ table. Since the offset must always be a multiple
+ of 8, we use the least significant bit to record
+ whether we have initialized it already.
When doing a dynamic link, we create a .rela.got
relocation entry to initialize the value. This is
as -1 | 1 still is -1. */
h->got.offset |= 1;
- if (h->dynindx == -1
- && !h->forced_local
- && h->root.type != bfd_link_hash_undefweak
- && bfd_link_pic (info))
+ if (GENERATE_RELATIVE_RELOC_P (info, h))
{
/* If this symbol isn't dynamic in PIC,
generate R_X86_64_RELATIVE here. */
if ((input_section->flags & SEC_ALLOC) == 0)
break;
- /* Don't copy a pc-relative relocation into the output file
- if the symbol needs copy reloc or the symbol is undefined
- when building executable. Copy dynamic function pointer
- relocations. Don't generate dynamic relocations against
- resolved undefined weak symbols in PIE. */
- if ((bfd_link_pic (info)
- && !(bfd_link_pie (info)
- && h != NULL
- && (h->needs_copy
- || eh->needs_copy
- || h->root.type == bfd_link_hash_undefined)
- && (IS_X86_64_PCREL_TYPE (r_type)
- || r_type == R_X86_64_SIZE32
- || r_type == R_X86_64_SIZE64))
- && (h == NULL
- || ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
- && !resolved_to_zero)
- || h->root.type != bfd_link_hash_undefweak))
- && ((! IS_X86_64_PCREL_TYPE (r_type)
- && r_type != R_X86_64_SIZE32
- && r_type != R_X86_64_SIZE64)
- || ! SYMBOL_CALLS_LOCAL (info, h)))
- || (ELIMINATE_COPY_RELOCS
- && !bfd_link_pic (info)
- && h != NULL
- && h->dynindx != -1
- && (!h->non_got_ref
- || eh->func_pointer_refcount > 0
- || (h->root.type == bfd_link_hash_undefweak
- && !resolved_to_zero))
- && ((h->def_dynamic && !h->def_regular)
- /* Undefined weak symbol is bound locally when
- PIC is false. */
- || h->root.type == bfd_link_hash_undefined)))
+ need_copy_reloc_in_pie = (bfd_link_pie (info)
+ && h != NULL
+ && (h->needs_copy
+ || eh->needs_copy
+ || (h->root.type
+ == bfd_link_hash_undefined))
+ && (X86_PCREL_TYPE_P (r_type)
+ || X86_SIZE_TYPE_P (r_type)));
+
+ if (GENERATE_DYNAMIC_RELOCATION_P (info, eh, r_type,
+ need_copy_reloc_in_pie,
+ resolved_to_zero, FALSE))
{
Elf_Internal_Rela outrel;
bfd_boolean skip, relocate;
if (skip)
memset (&outrel, 0, sizeof outrel);
- /* h->dynindx may be -1 if this symbol was marked to
- become local. */
- else if (h != NULL
- && h->dynindx != -1
- && (IS_X86_64_PCREL_TYPE (r_type)
- || !(bfd_link_executable (info)
- || SYMBOLIC_BIND (info, h))
- || ! h->def_regular))
+ else if (COPY_INPUT_RELOC_P (info, h, r_type))
{
outrel.r_info = htab->r_info (h->dynindx, r_type);
outrel.r_addend = rel->r_addend;
relplt = htab->elf.irelplt;
}
- /* This symbol has an entry in the procedure linkage table. Set
- it up. */
- if ((h->dynindx == -1
- && !local_undefweak
- && !((h->forced_local || bfd_link_executable (info))
- && h->def_regular
- && h->type == STT_GNU_IFUNC))
- || plt == NULL
- || gotplt == NULL
- || relplt == NULL)
- abort ();
+ VERIFY_PLT_ENTRY (info, h, plt, gotplt, relplt, local_undefweak)
/* Get the index in the procedure linkage table which
corresponds to this symbol. This is the index of this symbol
rela.r_offset = (gotplt->output_section->vma
+ gotplt->output_offset
+ got_offset);
- if (h->dynindx == -1
- || ((bfd_link_executable (info)
- || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
- && h->def_regular
- && h->type == STT_GNU_IFUNC))
+ if (PLT_LOCAL_IFUNC_P (info, h))
{
info->callbacks->minfo (_("Local IFUNC function `%s' in %B\n"),
h->root.root.string,
asection *s;
/* This symbol needs a copy reloc. Set it up. */
-
- if (h->dynindx == -1
- || (h->root.type != bfd_link_hash_defined
- && h->root.type != bfd_link_hash_defweak)
- || htab->elf.srelbss == NULL
- || htab->elf.sreldynrelro == NULL)
- abort ();
+ VERIFY_COPY_RELOC (h, htab)
rela.r_offset = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
struct bfd_link_info *info)
{
struct elf_x86_link_hash_table *htab;
- bfd *dynobj;
- asection *sdyn;
- htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
+ htab = _bfd_x86_elf_finish_dynamic_sections (output_bfd, info);
if (htab == NULL)
return FALSE;
- dynobj = htab->elf.dynobj;
- sdyn = bfd_get_linker_section (dynobj, ".dynamic");
-
- if (htab->elf.dynamic_sections_created)
- {
- bfd_byte *dyncon, *dynconend;
- const struct elf_backend_data *bed;
- bfd_size_type sizeof_dyn;
-
- if (sdyn == NULL || htab->elf.sgot == NULL)
- abort ();
-
- bed = get_elf_backend_data (dynobj);
- sizeof_dyn = bed->s->sizeof_dyn;
- dyncon = sdyn->contents;
- dynconend = sdyn->contents + sdyn->size;
- for (; dyncon < dynconend; dyncon += sizeof_dyn)
- {
- Elf_Internal_Dyn dyn;
- asection *s;
-
- (*bed->s->swap_dyn_in) (dynobj, dyncon, &dyn);
-
- switch (dyn.d_tag)
- {
- default:
- continue;
-
- case DT_PLTGOT:
- s = htab->elf.sgotplt;
- dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
- break;
-
- case DT_JMPREL:
- dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma;
- break;
-
- case DT_PLTRELSZ:
- s = htab->elf.srelplt->output_section;
- dyn.d_un.d_val = s->size;
- break;
-
- case DT_TLSDESC_PLT:
- s = htab->elf.splt;
- dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
- + htab->tlsdesc_plt;
- break;
-
- case DT_TLSDESC_GOT:
- s = htab->elf.sgot;
- dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
- + htab->tlsdesc_got;
- break;
- }
-
- (*bed->s->swap_dyn_out) (output_bfd, &dyn, dyncon);
- }
-
- if (htab->elf.splt && htab->elf.splt->size > 0)
- {
- elf_section_data (htab->elf.splt->output_section)
- ->this_hdr.sh_entsize = htab->plt.plt_entry_size;
-
- if (htab->plt.has_plt0)
- {
- /* Fill in the special first entry in the procedure linkage
- table. */
- memcpy (htab->elf.splt->contents,
- htab->lazy_plt->plt0_entry,
- htab->lazy_plt->plt0_entry_size);
- /* Add offset for pushq GOT+8(%rip), since the instruction
- uses 6 bytes subtract this value. */
- bfd_put_32 (output_bfd,
- (htab->elf.sgotplt->output_section->vma
- + htab->elf.sgotplt->output_offset
- + 8
- - htab->elf.splt->output_section->vma
- - htab->elf.splt->output_offset
- - 6),
- (htab->elf.splt->contents
- + htab->lazy_plt->plt0_got1_offset));
- /* Add offset for the PC-relative instruction accessing
- GOT+16, subtracting the offset to the end of that
- instruction. */
- bfd_put_32 (output_bfd,
- (htab->elf.sgotplt->output_section->vma
- + htab->elf.sgotplt->output_offset
- + 16
- - htab->elf.splt->output_section->vma
- - htab->elf.splt->output_offset
- - htab->lazy_plt->plt0_got2_insn_end),
- (htab->elf.splt->contents
- + htab->lazy_plt->plt0_got2_offset));
-
- if (htab->tlsdesc_plt)
- {
- bfd_put_64 (output_bfd, (bfd_vma) 0,
- htab->elf.sgot->contents + htab->tlsdesc_got);
-
- memcpy (htab->elf.splt->contents + htab->tlsdesc_plt,
- htab->lazy_plt->plt0_entry,
- htab->lazy_plt->plt0_entry_size);
-
- /* Add offset for pushq GOT+8(%rip), since the
- instruction uses 6 bytes subtract this value. */
- bfd_put_32 (output_bfd,
- (htab->elf.sgotplt->output_section->vma
- + htab->elf.sgotplt->output_offset
- + 8
- - htab->elf.splt->output_section->vma
- - htab->elf.splt->output_offset
- - htab->tlsdesc_plt
- - 6),
- (htab->elf.splt->contents
- + htab->tlsdesc_plt
- + htab->lazy_plt->plt0_got1_offset));
- /* Add offset for the PC-relative instruction accessing
- GOT+TDG, where TDG stands for htab->tlsdesc_got,
- subtracting the offset to the end of that
- instruction. */
- bfd_put_32 (output_bfd,
- (htab->elf.sgot->output_section->vma
- + htab->elf.sgot->output_offset
- + htab->tlsdesc_got
- - htab->elf.splt->output_section->vma
- - htab->elf.splt->output_offset
- - htab->tlsdesc_plt
- - htab->lazy_plt->plt0_got2_insn_end),
- (htab->elf.splt->contents
- + htab->tlsdesc_plt
- + htab->lazy_plt->plt0_got2_offset));
- }
- }
- }
-
- if (htab->plt_got != NULL && htab->plt_got->size > 0)
- elf_section_data (htab->plt_got->output_section)
- ->this_hdr.sh_entsize = htab->non_lazy_plt->plt_entry_size;
-
- if (htab->plt_second != NULL && htab->plt_second->size > 0)
- elf_section_data (htab->plt_second->output_section)
- ->this_hdr.sh_entsize = htab->non_lazy_plt->plt_entry_size;
- }
-
- /* GOT is always created in setup_gnu_properties. But it may not be
- needed. */
- if (htab->elf.sgotplt && htab->elf.sgotplt->size > 0)
- {
- if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
- {
- _bfd_error_handler
- (_("discarded output section: `%A'"), htab->elf.sgotplt);
- return FALSE;
- }
-
- /* Set the first entry in the global offset table to the address of
- the dynamic section. */
- if (sdyn == NULL)
- bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents);
- else
- bfd_put_64 (output_bfd,
- sdyn->output_section->vma + sdyn->output_offset,
- htab->elf.sgotplt->contents);
- /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
- bfd_put_64 (output_bfd, (bfd_vma) 0,
- htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
- bfd_put_64 (output_bfd, (bfd_vma) 0,
- htab->elf.sgotplt->contents + GOT_ENTRY_SIZE*2);
-
- elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize
- = GOT_ENTRY_SIZE;
- }
+ if (! htab->elf.dynamic_sections_created)
+ return TRUE;
- /* Adjust .eh_frame for .plt section. */
- if (htab->plt_eh_frame != NULL
- && htab->plt_eh_frame->contents != NULL)
+ if (htab->elf.splt && htab->elf.splt->size > 0)
{
- if (htab->elf.splt != NULL
- && htab->elf.splt->size != 0
- && (htab->elf.splt->flags & SEC_EXCLUDE) == 0
- && htab->elf.splt->output_section != NULL
- && htab->plt_eh_frame->output_section != NULL)
- {
- bfd_vma plt_start = htab->elf.splt->output_section->vma;
- bfd_vma eh_frame_start = htab->plt_eh_frame->output_section->vma
- + htab->plt_eh_frame->output_offset
- + PLT_FDE_START_OFFSET;
- bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
- htab->plt_eh_frame->contents
- + PLT_FDE_START_OFFSET);
- }
- if (htab->plt_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
- {
- if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
- htab->plt_eh_frame,
- htab->plt_eh_frame->contents))
- return FALSE;
- }
- }
+ elf_section_data (htab->elf.splt->output_section)
+ ->this_hdr.sh_entsize = htab->plt.plt_entry_size;
- /* Adjust .eh_frame for .plt.got section. */
- if (htab->plt_got_eh_frame != NULL
- && htab->plt_got_eh_frame->contents != NULL)
- {
- if (htab->plt_got != NULL
- && htab->plt_got->size != 0
- && (htab->plt_got->flags & SEC_EXCLUDE) == 0
- && htab->plt_got->output_section != NULL
- && htab->plt_got_eh_frame->output_section != NULL)
+ if (htab->plt.has_plt0)
{
- bfd_vma plt_start = htab->plt_got->output_section->vma;
- bfd_vma eh_frame_start = htab->plt_got_eh_frame->output_section->vma
- + htab->plt_got_eh_frame->output_offset
- + PLT_FDE_START_OFFSET;
- bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
- htab->plt_got_eh_frame->contents
- + PLT_FDE_START_OFFSET);
- }
- if (htab->plt_got_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
- {
- if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
- htab->plt_got_eh_frame,
- htab->plt_got_eh_frame->contents))
- return FALSE;
+ /* Fill in the special first entry in the procedure linkage
+ table. */
+ memcpy (htab->elf.splt->contents,
+ htab->lazy_plt->plt0_entry,
+ htab->lazy_plt->plt0_entry_size);
+ /* Add offset for pushq GOT+8(%rip), since the instruction
+ uses 6 bytes subtract this value. */
+ bfd_put_32 (output_bfd,
+ (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + 8
+ - htab->elf.splt->output_section->vma
+ - htab->elf.splt->output_offset
+ - 6),
+ (htab->elf.splt->contents
+ + htab->lazy_plt->plt0_got1_offset));
+ /* Add offset for the PC-relative instruction accessing
+ GOT+16, subtracting the offset to the end of that
+ instruction. */
+ bfd_put_32 (output_bfd,
+ (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + 16
+ - htab->elf.splt->output_section->vma
+ - htab->elf.splt->output_offset
+ - htab->lazy_plt->plt0_got2_insn_end),
+ (htab->elf.splt->contents
+ + htab->lazy_plt->plt0_got2_offset));
}
- }
- /* Adjust .eh_frame for the second PLT section. */
- if (htab->plt_second_eh_frame != NULL
- && htab->plt_second_eh_frame->contents != NULL)
- {
- if (htab->plt_second != NULL
- && htab->plt_second->size != 0
- && (htab->plt_second->flags & SEC_EXCLUDE) == 0
- && htab->plt_second->output_section != NULL
- && htab->plt_second_eh_frame->output_section != NULL)
- {
- bfd_vma plt_start = htab->plt_second->output_section->vma;
- bfd_vma eh_frame_start
- = (htab->plt_second_eh_frame->output_section->vma
- + htab->plt_second_eh_frame->output_offset
- + PLT_FDE_START_OFFSET);
- bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
- htab->plt_second_eh_frame->contents
- + PLT_FDE_START_OFFSET);
- }
- if (htab->plt_second_eh_frame->sec_info_type
- == SEC_INFO_TYPE_EH_FRAME)
+ if (htab->tlsdesc_plt)
{
- if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
- htab->plt_second_eh_frame,
- htab->plt_second_eh_frame->contents))
- return FALSE;
+ bfd_put_64 (output_bfd, (bfd_vma) 0,
+ htab->elf.sgot->contents + htab->tlsdesc_got);
+
+ memcpy (htab->elf.splt->contents + htab->tlsdesc_plt,
+ htab->lazy_plt->plt0_entry,
+ htab->lazy_plt->plt0_entry_size);
+
+ /* Add offset for pushq GOT+8(%rip), since the
+ instruction uses 6 bytes subtract this value. */
+ bfd_put_32 (output_bfd,
+ (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + 8
+ - htab->elf.splt->output_section->vma
+ - htab->elf.splt->output_offset
+ - htab->tlsdesc_plt
+ - 6),
+ (htab->elf.splt->contents
+ + htab->tlsdesc_plt
+ + htab->lazy_plt->plt0_got1_offset));
+ /* Add offset for the PC-relative instruction accessing
+ GOT+TDG, where TDG stands for htab->tlsdesc_got,
+ subtracting the offset to the end of that
+ instruction. */
+ bfd_put_32 (output_bfd,
+ (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset
+ + htab->tlsdesc_got
+ - htab->elf.splt->output_section->vma
+ - htab->elf.splt->output_offset
+ - htab->tlsdesc_plt
+ - htab->lazy_plt->plt0_got2_insn_end),
+ (htab->elf.splt->contents
+ + htab->tlsdesc_plt
+ + htab->lazy_plt->plt0_got2_offset));
}
}
- if (htab->elf.sgot && htab->elf.sgot->size > 0)
- elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
- = GOT_ENTRY_SIZE;
-
/* Fill PLT entries for undefined weak symbols in PIE. */
if (bfd_link_pie (info))
bfd_hash_traverse (&info->hash->table,
if (relsize <= 0)
return -1;
- if (get_elf_x86_64_backend_data (abfd)->os == is_normal)
+ if (get_elf_x86_backend_data (abfd)->target_os == is_normal)
{
lazy_plt = &elf_x86_64_lazy_plt;
non_lazy_plt = &elf_x86_64_non_lazy_plt;
!= (int) R_X86_64_GNU_VTENTRY))
abort ();
- init_table.is_vxworks = FALSE;
- if (get_elf_x86_64_backend_data (info->output_bfd)->os == is_normal)
+ /* This is unused for x86-64. */
+ init_table.plt0_pad_byte = 0x90;
+
+ if (get_elf_x86_backend_data (info->output_bfd)->target_os
+ == is_normal)
{
if (info->bndplt)
{
init_table.lazy_ibt_plt = &elf_x32_lazy_ibt_plt;
init_table.non_lazy_ibt_plt = &elf_x32_non_lazy_ibt_plt;
}
- init_table.normal_target = TRUE;
}
else
{
init_table.non_lazy_plt = NULL;
init_table.lazy_ibt_plt = NULL;
init_table.non_lazy_ibt_plt = NULL;
- init_table.normal_target = FALSE;
}
if (ABI_64_P (info->output_bfd))
#define elf_backend_additional_program_headers \
elf_x86_64_additional_program_headers
#define elf_backend_setup_gnu_properties \
- elf_x86_64_link_setup_gnu_properties
+ elf_x86_64_link_setup_gnu_properties
+#define elf_backend_hide_symbol \
+ _bfd_x86_elf_hide_symbol
#include "elf64-target.h"
|| PLT_FDE_LENGTH != 36 \
|| PLT_FDE_START_OFFSET != 4 + PLT_CIE_LENGTH + 8 \
|| PLT_FDE_LEN_OFFSET != 4 + PLT_CIE_LENGTH + 12)
-# error "Need elf_x86_64_backend_data parameters for eh_frame_plt offsets!"
+# error "Need elf_x86_backend_data parameters for eh_frame_plt offsets!"
#endif
PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
0, 0, 0, 0, /* CIE ID */
sizeof (elf_x86_64_nacl_eh_frame_plt) /* eh_frame_plt_size */
};
-static const struct elf_x86_64_backend_data elf_x86_64_nacl_arch_bed =
+static const struct elf_x86_backend_data elf_x86_64_nacl_arch_bed =
{
is_nacl /* os */
};