HOWTO (AARCH64_R (MOVW_SABS_G0), /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
- 16, /* bitsize */
+ 17, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
HOWTO64 (AARCH64_R (MOVW_SABS_G1), /* type */
16, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
- 16, /* bitsize */
+ 17, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
HOWTO64 (AARCH64_R (MOVW_SABS_G2), /* type */
32, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
- 16, /* bitsize */
+ 17, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
/* Enable ADRP->ADR rewrite for erratum 843419 workaround. */
int fix_erratum_843419_adr;
+ /* Don't apply link-time values for dynamic relocations. */
+ int no_apply_dynamic_relocs;
+
/* The number of bytes in the initial entry in the PLT. */
bfd_size_type plt_header_size;
/* Determine the type of stub needed, if any, for a call. */
static enum elf_aarch64_stub_type
-aarch64_type_of_stub (struct bfd_link_info *info,
- asection *input_sec,
+aarch64_type_of_stub (asection *input_sec,
const Elf_Internal_Rela *rel,
asection *sym_sec,
unsigned char st_type,
- struct elf_aarch64_link_hash_entry *hash,
bfd_vma destination)
{
bfd_vma location;
bfd_signed_vma branch_offset;
unsigned int r_type;
- struct elf_aarch64_link_hash_table *globals;
enum elf_aarch64_stub_type stub_type = aarch64_stub_none;
- bfd_boolean via_plt_p;
if (st_type != STT_FUNC
&& (sym_sec == input_sec))
return stub_type;
- globals = elf_aarch64_hash_table (info);
- via_plt_p = (globals->root.splt != NULL && hash != NULL
- && hash->root.plt.offset != (bfd_vma) - 1);
- /* Make sure call to plt stub can fit into the branch range. */
- if (via_plt_p)
- destination = (globals->root.splt->output_section->vma
- + globals->root.splt->output_offset
- + hash->root.plt.offset);
-
/* Determine where the call point is. */
location = (input_sec->output_offset
+ input_sec->output_section->vma + rel->r_offset);
}
/* Determine what (if any) linker stub is needed. */
- stub_type = aarch64_type_of_stub
- (info, section, irela, sym_sec, st_type, hash, destination);
+ stub_type = aarch64_type_of_stub (section, irela, sym_sec,
+ st_type, destination);
if (stub_type == aarch64_stub_none)
continue;
int no_enum_warn,
int no_wchar_warn, int pic_veneer,
int fix_erratum_835769,
- int fix_erratum_843419)
+ int fix_erratum_843419,
+ int no_apply_dynamic_relocs)
{
struct elf_aarch64_link_hash_table *globals;
globals->fix_erratum_835769 = fix_erratum_835769;
globals->fix_erratum_843419 = fix_erratum_843419;
globals->fix_erratum_843419_adr = TRUE;
+ globals->no_apply_dynamic_relocs = no_apply_dynamic_relocs;
BFD_ASSERT (is_aarch64_elf (output_bfd));
elf_aarch64_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
return FALSE;
}
-/* Perform a relocation as part of a final link. */
+/* Perform a relocation as part of a final link. The input relocation type
+ should be TLS relaxed. */
+
static bfd_reloc_status_type
elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
bfd *input_bfd,
unsigned int r_type = howto->type;
bfd_reloc_code_real_type bfd_r_type
= elfNN_aarch64_bfd_reloc_from_howto (howto);
- bfd_reloc_code_real_type new_bfd_r_type;
unsigned long r_symndx;
bfd_byte *hit_data = contents + rel->r_offset;
bfd_vma place, off;
r_symndx = ELFNN_R_SYM (rel->r_info);
- /* It is possible to have linker relaxations on some TLS access
- models. Update our information here. */
- new_bfd_r_type = aarch64_tls_transition (input_bfd, info, r_type, h, r_symndx);
- if (new_bfd_r_type != bfd_r_type)
- {
- bfd_r_type = new_bfd_r_type;
- howto = elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type);
- BFD_ASSERT (howto != NULL);
- r_type = howto->type;
- }
-
place = input_section->output_section->vma
+ input_section->output_offset + rel->r_offset;
relocate the text and data segments independently,
so the symbol does not matter. */
symbol = 0;
+ relocate = globals->no_apply_dynamic_relocs ? FALSE : TRUE;
outrel.r_info = ELFNN_R_INFO (symbol, AARCH64_R (RELATIVE));
outrel.r_addend += value;
}
if (h != NULL)
{
+ /* If a relocation refers to _GLOBAL_OFFSET_TABLE_, create the .got.
+ This shows up in particular in an R_AARCH64_PREL64 in large model
+ when calculating the pc-relative address to .got section which is
+ used to initialize the gp register. */
+ if (h->root.root.string
+ && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ {
+ if (htab->root.dynobj == NULL)
+ htab->root.dynobj = abfd;
+
+ if (! aarch64_elf_create_got_section (htab->root.dynobj, info))
+ return FALSE;
+
+ BFD_ASSERT (h == htab->root.hgot);
+ }
+
/* Create the ifunc sections for static executables. If we
never see an indirect function symbol nor we are building
a static executable, those sections will be empty and
&& h->def_regular)
return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
&eh->dyn_relocs,
+ NULL,
htab->plt_entry_size,
htab->plt_header_size,
GOT_ENTRY_SIZE);
break;
case DT_JMPREL:
- dyn.d_un.d_ptr = htab->root.srelplt->output_section->vma;
+ s = htab->root.srelplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
break;
case DT_PLTRELSZ: