if (!thumb_only)
{
if (input_sec->flags & SEC_ELF_PURECODE)
- (*_bfd_error_handler) (_("%B(%s): warning: long branch "
- " veneers used in section with "
- "SHF_ARM_PURECODE section "
- "attribute is only supported"
- " for M-profile targets that "
- "implement the movw "
- "instruction."));
+ _bfd_error_handler (_("%B(%s): warning: long branch "
+ " veneers used in section with "
+ "SHF_ARM_PURECODE section "
+ "attribute is only supported"
+ " for M-profile targets that "
+ "implement the movw "
+ "instruction."));
stub_type = (bfd_link_pic (info) | globals->pic_veneer)
/* PIC stubs. */
else
{
if (input_sec->flags & SEC_ELF_PURECODE)
- (*_bfd_error_handler) (_("%B(%s): warning: long branch "
- " veneers used in section with "
- "SHF_ARM_PURECODE section "
- "attribute is only supported"
- " for M-profile targets that "
- "implement the movw "
- "instruction."));
+ _bfd_error_handler (_("%B(%s): warning: long branch "
+ " veneers used in section with "
+ "SHF_ARM_PURECODE section "
+ "attribute is only supported"
+ " for M-profile targets that "
+ "implement the movw "
+ "instruction."));
stub_type = (bfd_link_pic (info) | globals->pic_veneer)
/* PIC stub. */
else
{
if (input_sec->flags & SEC_ELF_PURECODE)
- (*_bfd_error_handler) (_("%B(%s): warning: long branch "
- " veneers used in section with "
- "SHF_ARM_PURECODE section "
- "attribute is only supported"
- " for M-profile targets that "
- "implement the movw "
- "instruction."));
+ _bfd_error_handler (_("%B(%s): warning: long branch "
+ " veneers used in section with "
+ "SHF_ARM_PURECODE section "
+ "attribute is only supported"
+ " for M-profile targets that "
+ "implement the movw "
+ "instruction."));
/* Thumb to arm. */
if (sym_sec != NULL
&& sym_sec->owner != NULL
&& !INTERWORK_FLAG (sym_sec->owner))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%s): warning: interworking not enabled.\n"
" first occurrence: %B: Thumb call to ARM"),
sym_sec->owner, input_bfd, name);
|| r_type == R_ARM_TLS_CALL)
{
if (input_sec->flags & SEC_ELF_PURECODE)
- (*_bfd_error_handler) (_("%B(%s): warning: long branch "
- " veneers used in section with "
- "SHF_ARM_PURECODE section "
- "attribute is only supported"
- " for M-profile targets that "
- "implement the movw "
- "instruction."));
+ _bfd_error_handler (_("%B(%s): warning: long branch "
+ " veneers used in section with "
+ "SHF_ARM_PURECODE section "
+ "attribute is only supported"
+ " for M-profile targets that "
+ "implement the movw "
+ "instruction."));
if (branch_type == ST_BRANCH_TO_THUMB)
{
/* Arm to thumb. */
&& sym_sec->owner != NULL
&& !INTERWORK_FLAG (sym_sec->owner))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%s): warning: interworking not enabled.\n"
" first occurrence: %B: ARM call to Thumb"),
sym_sec->owner, input_bfd, name);
out_sec = bfd_get_section_by_name (output_bfd, out_sec_name);
if (out_sec == NULL)
{
- (*_bfd_error_handler) (_("No address assigned to the veneers output "
- "section %s"), out_sec_name);
+ _bfd_error_handler (_("No address assigned to the veneers output "
+ "section %s"), out_sec_name);
return NULL;
}
}
{
if (section == NULL)
section = stub_sec;
- (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
- section->owner,
- stub_name);
+ _bfd_error_handler (_("%s: cannot create stub entry %s"),
+ section->owner, stub_name);
return NULL;
}
if (!is_v8m)
{
- (*_bfd_error_handler) (_("%B: Special symbol `%s' only allowed for "
- "ARMv8-M architecture or later."),
- input_bfd, sym_name);
+ _bfd_error_handler (_("%B: Special symbol `%s' only allowed for "
+ "ARMv8-M architecture or later."),
+ input_bfd, sym_name);
is_v8m = TRUE; /* Avoid multiple warning. */
ret = FALSE;
}
if (cmse_invalid)
{
- (*_bfd_error_handler) (_("%B: invalid special symbol `%s'."),
- input_bfd, sym_name);
- (*_bfd_error_handler) (_("It must be a global or weak function "
- "symbol."));
+ _bfd_error_handler (_("%B: invalid special symbol `%s'."),
+ input_bfd, sym_name);
+ _bfd_error_handler (_("It must be a global or weak function "
+ "symbol."));
ret = FALSE;
if (i < ext_start)
continue;
if (hash || j < ext_start)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: invalid standard symbol `%s'."), input_bfd, sym_name);
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("It must be a global or weak function symbol."));
}
else
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: absent standard symbol `%s'."), input_bfd, sym_name);
ret = FALSE;
if (!hash)
if (cmse_hash->root.root.u.def.section != section)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: `%s' and its special symbol are in different sections."),
input_bfd, sym_name);
ret = FALSE;
don't create any stubs. */
if (section->output_section == NULL)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: entry function `%s' not output."), input_bfd, sym_name);
continue;
}
if (hash->root.size == 0)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: entry function `%s' is empty."), input_bfd, sym_name);
ret = FALSE;
}
return TRUE;
if (stub_entry->stub_offset == (bfd_vma) -1)
- (*_bfd_error_handler) (" %s", stub_entry->output_name);
+ _bfd_error_handler (" %s", stub_entry->output_name);
return TRUE;
}
in_implib_bfd = htab->in_implib_bfd;
if (!htab->cmse_implib)
{
- (*_bfd_error_handler) (_("%B: --in-implib only supported for Secure "
- "Gateway import libraries."), in_implib_bfd);
+ _bfd_error_handler (_("%B: --in-implib only supported for Secure "
+ "Gateway import libraries."), in_implib_bfd);
return FALSE;
}
|| (ARM_GET_SYM_BRANCH_TYPE (intsym->st_target_internal)
!= ST_BRANCH_TO_THUMB))
{
- (*_bfd_error_handler) (_("%B: invalid import library entry: `%s'."),
- in_implib_bfd, sym_name);
- (*_bfd_error_handler) (_("Symbol should be absolute, global and "
- "refer to Thumb functions."));
+ _bfd_error_handler (_("%B: invalid import library entry: `%s'."),
+ in_implib_bfd, sym_name);
+ _bfd_error_handler (_("Symbol should be absolute, global and "
+ "refer to Thumb functions."));
ret = FALSE;
continue;
}
{
bfd_boolean new_stub;
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("Entry function `%s' disappeared from secure code."), sym_name);
hash = (struct elf32_arm_link_hash_entry *)
elf_link_hash_lookup (&(htab)->root, sym_name, TRUE, TRUE, TRUE);
{
if (!cmse_entry_fct_p (hash))
{
- (*_bfd_error_handler) (_("`%s' refers to a non entry function."),
- sym_name);
+ _bfd_error_handler (_("`%s' refers to a non entry function."),
+ sym_name);
ret = FALSE;
}
continue;
/* Check visibility hasn't changed. */
if (!!(flags & BSF_GLOBAL)
!= (hash->root.root.type == bfd_link_hash_defined))
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: visibility of symbol `%s' has changed."), in_implib_bfd,
sym_name);
/* Size should match that of a SG veneer. */
if (intsym->st_size != cmse_stub_size)
{
- (*_bfd_error_handler) (_("%B: incorrect size for symbol `%s'."),
- in_implib_bfd, sym_name);
+ _bfd_error_handler (_("%B: incorrect size for symbol `%s'."),
+ in_implib_bfd, sym_name);
ret = FALSE;
}
/* Complain if stub offset not a multiple of stub size. */
if (stub_offset % cmse_stub_size)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("Offset of veneer for entry function `%s' not a multiple of "
"its size."), sym_name);
ret = FALSE;
if (!info->out_implib_bfd && new_cmse_stubs_created != 0)
{
BFD_ASSERT (new_cmse_stubs_created > 0);
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("new entry function(s) introduced but no output import library "
"specified:"));
bfd_hash_traverse (&htab->stub_hash_table, arm_list_new_cmse_stub, info);
if (cmse_stub_array_start != cmse_stub_sec_vma)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("Start address of `%s' is different from previous link."),
out_sec_name);
ret = FALSE;
TRUE, FALSE);
if (stub_entry == NULL)
{
- (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
- section->owner,
- stub_name);
+ _bfd_error_handler (_("%s: cannot create stub entry %s"),
+ section->owner, stub_name);
return FALSE;
}
default:
/* Give a warning, but do as the user requests anyway. */
- (*_bfd_error_handler) (_("%B: warning: selected VFP11 erratum "
+ _bfd_error_handler (_("%B: warning: selected VFP11 erratum "
"workaround is not necessary for target architecture"), obfd);
}
}
{
if (globals->stm32l4xx_fix != BFD_ARM_STM32L4XX_FIX_NONE)
/* Give a warning, but do as the user requests anyway. */
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: warning: selected STM32L4XX erratum "
"workaround is not necessary for target architecture"), obfd);
}
(&(globals)->root, tmp_name, FALSE, FALSE, TRUE);
if (myh == NULL)
- (*_bfd_error_handler) (_("%B: unable to find VFP11 veneer "
- "`%s'"), abfd, tmp_name);
+ _bfd_error_handler (_("%B: unable to find VFP11 veneer "
+ "`%s'"), abfd, tmp_name);
vma = myh->root.u.def.section->output_section->vma
+ myh->root.u.def.section->output_offset
(&(globals)->root, tmp_name, FALSE, FALSE, TRUE);
if (myh == NULL)
- (*_bfd_error_handler) (_("%B: unable to find VFP11 veneer "
- "`%s'"), abfd, tmp_name);
+ _bfd_error_handler (_("%B: unable to find VFP11 veneer "
+ "`%s'"), abfd, tmp_name);
vma = myh->root.u.def.section->output_section->vma
+ myh->root.u.def.section->output_offset
(&(globals)->root, tmp_name, FALSE, FALSE, TRUE);
if (myh == NULL)
- (*_bfd_error_handler) (_("%B: unable to find STM32L4XX veneer "
- "`%s'"), abfd, tmp_name);
+ _bfd_error_handler (_("%B: unable to find STM32L4XX veneer "
+ "`%s'"), abfd, tmp_name);
vma = myh->root.u.def.section->output_section->vma
+ myh->root.u.def.section->output_offset
(&(globals)->root, tmp_name, FALSE, FALSE, TRUE);
if (myh == NULL)
- (*_bfd_error_handler) (_("%B: unable to find STM32L4XX veneer "
- "`%s'"), abfd, tmp_name);
+ _bfd_error_handler (_("%B: unable to find STM32L4XX veneer "
+ "`%s'"), abfd, tmp_name);
vma = myh->root.u.def.section->output_section->vma
+ myh->root.u.def.section->output_offset
{
if (is_not_last_in_it_block)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
/* Note - overlong line used here to allow for translation. */
(_("\
%B(%A+0x%lx): error: multiple load detected in non-last IT block instruction : STM32L4XX veneer cannot be generated.\n"
&& sym_sec->owner != NULL
&& !INTERWORK_FLAG (sym_sec->owner))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%s): warning: interworking not enabled.\n"
" first occurrence: %B: Thumb call to ARM"),
sym_sec->owner, input_bfd, name);
&& sym_sec->owner != NULL
&& !INTERWORK_FLAG (sym_sec->owner))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%s): warning: interworking not enabled.\n"
" first occurrence: %B: arm call to thumb"),
sym_sec->owner, input_bfd, name);
error generation. */
insn = (insn << 16)
| bfd_get_16 (input_bfd, contents + rel->r_offset + 2);
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%A+0x%lx):unexpected Thumb instruction '0x%x' in TLS trampoline"),
input_bfd, input_sec, (unsigned long)rel->r_offset, insn);
return bfd_reloc_notsupported;
}
else
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%A+0x%lx):unexpected ARM instruction '0x%x' in TLS trampoline"),
input_bfd, input_sec, (unsigned long)rel->r_offset, insn);
return bfd_reloc_notsupported;
case R_ARM_ABS12:
if (!globals->vxworks_p)
return elf32_arm_abs12_reloc (input_bfd, hit_data, value + addend);
+ /* Fall through. */
case R_ARM_PC24:
case R_ARM_ABS32:
if (bfd_link_executable (info))
v = _("PIE executable");
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: relocation %s against external or undefined symbol `%s'"
" can not be used when making a %s; recompile with -fPIC"), input_bfd,
elf32_arm_howto_table_1[r_type].name, h->root.root.string, v);
/* FIXME: Should we translate the instruction into a BL
instruction instead ? */
if (branch_type != ST_BRANCH_TO_THUMB)
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("\%B: Warning: Arm BLX instruction targets Arm function '%s'."),
input_bfd,
h ? h->root.root.string : "(local)");
/* FIXME: Should we translate the instruction into a BL
instruction instead ? */
if (branch_type == ST_BRANCH_TO_THUMB)
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: Warning: Thumb BLX instruction targets thumb function '%s'."),
input_bfd,
h ? h->root.root.string : "(local)");
value = -5;
else
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%A+0x%lx):unexpected Thumb instruction '0x%x' referenced by TLS_GOTDESC"),
input_bfd, input_section,
(unsigned long)rel->r_offset, insn);
break;
default:
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%A+0x%lx):unexpected ARM instruction '0x%x' referenced by TLS_GOTDESC"),
input_bfd, input_section,
(unsigned long)rel->r_offset, insn);
case R_ARM_TLS_LE32:
if (bfd_link_dll (info))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"),
input_bfd, input_section,
(long) rel->r_offset, howto->name);
negative = identify_add_or_sub (insn);
if (negative == 0)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%A+0x%lx): Only ADD or SUB instructions are allowed for ALU group relocations"),
input_bfd, input_section,
(long) rel->r_offset, howto->name);
|| r_type == R_ARM_ALU_SB_G1
|| r_type == R_ARM_ALU_SB_G2) && residual != 0)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
input_bfd, input_section,
(long) rel->r_offset, signed_value < 0 ? - signed_value : signed_value,
/* Check for overflow. */
if (residual >= 0x1000)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
input_bfd, input_section,
(long) rel->r_offset, labs (signed_value), howto->name);
/* Check for overflow. */
if (residual >= 0x100)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
input_bfd, input_section,
(long) rel->r_offset, labs (signed_value), howto->name);
fit in eight bits.) */
if ((residual & 0x3) != 0 || residual >= 0x400)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
input_bfd, input_section,
(long) rel->r_offset, labs (signed_value), howto->name);
if (howto->rightshift
|| (howto->src_mask & (howto->src_mask + 1)))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"),
input_bfd, input_section,
(long) rel->r_offset, howto->name);
|| h->root.type == bfd_link_hash_defweak)
&& IS_ARM_TLS_RELOC (r_type) != (sym_type == STT_TLS))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
((sym_type == STT_TLS
? _("%B(%A+0x%lx): %s used with TLS symbol %s")
: _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
&& _bfd_elf_section_offset (output_bfd, info, input_section,
rel->r_offset) != (bfd_vma) -1)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
input_bfd,
input_section,
if (EF_ARM_EABI_VERSION (flags) == EF_ARM_EABI_UNKNOWN)
{
if (flags & EF_ARM_INTERWORK)
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"),
abfd);
else
are conflicting attributes. */
static bfd_boolean
-elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
+elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
{
+ bfd *obfd = info->output_bfd;
obj_attribute *in_attr;
obj_attribute *out_attr;
/* Some tags have 0 = don't care, 1 = strong requirement,
}
/* Merge Tag_compatibility attributes and any common GNU ones. */
- if (!_bfd_elf_merge_object_attributes (ibfd, obfd))
+ if (!_bfd_elf_merge_object_attributes (ibfd, info))
return FALSE;
/* Check for any attributes not known on ARM. */
object file when linking. */
static bfd_boolean
-elf32_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd);
+elf32_arm_merge_private_bfd_data (bfd *, struct bfd_link_info *);
/* Display the flags field. */
object file containing relocations but no symbol table. */
&& (r_symndx > STN_UNDEF || nsyms > 0))
{
- (*_bfd_error_handler) (_("%B: bad symbol index: %d"), abfd,
- r_symndx);
+ _bfd_error_handler (_("%B: bad symbol index: %d"), abfd,
+ r_symndx);
return FALSE;
}
break;
}
else goto jump_over;
-
+
/* Fall through. */
case R_ARM_MOVW_ABS_NC:
case R_ARM_THM_MOVT_ABS:
if (bfd_link_pic (info))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
abfd, elf32_arm_howto_table_1[r_type].name,
(h) ? h->root.root.string : "a local symbol");
return TRUE;
}
+static void
+elf32_arm_update_relocs (asection *o,
+ struct bfd_elf_section_reloc_data *reldata)
+{
+ void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
+ void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
+ const struct elf_backend_data *bed;
+ _arm_elf_section_data *eado;
+ struct bfd_link_order *p;
+ bfd_byte *erela_head, *erela;
+ Elf_Internal_Rela *irela_head, *irela;
+ Elf_Internal_Shdr *rel_hdr;
+ bfd *abfd;
+ unsigned int count;
+
+ eado = get_arm_elf_section_data (o);
+
+ if (!eado || eado->elf.this_hdr.sh_type != SHT_ARM_EXIDX)
+ return;
+
+ abfd = o->owner;
+ bed = get_elf_backend_data (abfd);
+ rel_hdr = reldata->hdr;
+
+ if (rel_hdr->sh_entsize == bed->s->sizeof_rel)
+ {
+ swap_in = bed->s->swap_reloc_in;
+ swap_out = bed->s->swap_reloc_out;
+ }
+ else if (rel_hdr->sh_entsize == bed->s->sizeof_rela)
+ {
+ swap_in = bed->s->swap_reloca_in;
+ swap_out = bed->s->swap_reloca_out;
+ }
+ else
+ abort ();
+
+ erela_head = rel_hdr->contents;
+ irela_head = (Elf_Internal_Rela *) bfd_zmalloc
+ ((NUM_SHDR_ENTRIES (rel_hdr) + 1) * sizeof (*irela_head));
+
+ erela = erela_head;
+ irela = irela_head;
+ count = 0;
+
+ for (p = o->map_head.link_order; p; p = p->next)
+ {
+ if (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order)
+ {
+ (*swap_in) (abfd, erela, irela);
+ erela += rel_hdr->sh_entsize;
+ irela++;
+ count++;
+ }
+ else if (p->type == bfd_indirect_link_order)
+ {
+ struct bfd_elf_section_reloc_data *input_reldata;
+ arm_unwind_table_edit *edit_list, *edit_tail;
+ _arm_elf_section_data *eadi;
+ bfd_size_type j;
+ bfd_vma offset;
+ asection *i;
+
+ i = p->u.indirect.section;
+
+ eadi = get_arm_elf_section_data (i);
+ edit_list = eadi->u.exidx.unwind_edit_list;
+ edit_tail = eadi->u.exidx.unwind_edit_tail;
+ offset = o->vma + i->output_offset;
+
+ if (eadi->elf.rel.hdr &&
+ eadi->elf.rel.hdr->sh_entsize == rel_hdr->sh_entsize)
+ input_reldata = &eadi->elf.rel;
+ else if (eadi->elf.rela.hdr &&
+ eadi->elf.rela.hdr->sh_entsize == rel_hdr->sh_entsize)
+ input_reldata = &eadi->elf.rela;
+ else
+ abort ();
+
+ if (edit_list)
+ {
+ for (j = 0; j < NUM_SHDR_ENTRIES (input_reldata->hdr); j++)
+ {
+ arm_unwind_table_edit *edit_node, *edit_next;
+ bfd_vma bias;
+ bfd_vma index;
+
+ (*swap_in) (abfd, erela, irela);
+ index = (irela->r_offset - offset) / 8;
+
+ bias = 0;
+ edit_node = edit_list;
+ for (edit_next = edit_list;
+ edit_next && edit_next->index <= index;
+ edit_next = edit_node->next)
+ {
+ bias++;
+ edit_node = edit_next;
+ }
+
+ if (edit_node->type != DELETE_EXIDX_ENTRY
+ || edit_node->index != index)
+ {
+ irela->r_offset -= bias * 8;
+ irela++;
+ count++;
+ }
+
+ erela += rel_hdr->sh_entsize;
+ }
+
+ if (edit_tail->type == INSERT_EXIDX_CANTUNWIND_AT_END)
+ {
+ /* New relocation entity. */
+ asection *text_sec = edit_tail->linked_section;
+ asection *text_out = text_sec->output_section;
+ bfd_vma exidx_offset = offset + i->size - 8;
+
+ irela->r_addend = 0;
+ irela->r_offset = exidx_offset;
+ irela->r_info = ELF32_R_INFO
+ (text_out->target_index, R_ARM_PREL31);
+ irela++;
+ count++;
+ }
+ }
+ else
+ {
+ for (j = 0; j < NUM_SHDR_ENTRIES (input_reldata->hdr); j++)
+ {
+ (*swap_in) (abfd, erela, irela);
+ erela += rel_hdr->sh_entsize;
+ irela++;
+ }
+
+ count += NUM_SHDR_ENTRIES (input_reldata->hdr);
+ }
+ }
+ }
+
+ reldata->count = count;
+ rel_hdr->sh_size = count * rel_hdr->sh_entsize;
+
+ erela = erela_head;
+ irela = irela_head;
+ while (count > 0)
+ {
+ (*swap_out) (abfd, irela, erela);
+ erela += rel_hdr->sh_entsize;
+ irela++;
+ count--;
+ }
+
+ free (irela_head);
+
+ /* Hashes are no longer valid. */
+ free (reldata->hashes);
+ reldata->hashes = NULL;
+}
+
/* Unwinding tables are not referenced directly. This pass marks them as
required if the corresponding code section is marked. Similarly, ARMv8-M
secure entry functions can only be referenced by SG veneers which are
s = bfd_get_linker_section (dynobj, name);
if (s == NULL)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("could not find section %s"), name);
bfd_set_error (bfd_error_invalid_operation);
return FALSE;
This check is just to be on the safe side... */
if ((veneered_insn_loc & ~0xfff) == (veneer_entry_loc & ~0xfff))
{
- (*_bfd_error_handler) (_("%B: error: Cortex-A8 erratum stub is "
- "allocated in unsafe location"), abfd);
+ _bfd_error_handler (_("%B: error: Cortex-A8 erratum stub is "
+ "allocated in unsafe location"), abfd);
return FALSE;
}
{
/* There's not much we can do apart from complain if this
happens. */
- (*_bfd_error_handler) (_("%B: error: Cortex-A8 erratum stub out "
- "of range (input file too large)"), abfd);
+ _bfd_error_handler (_("%B: error: Cortex-A8 erratum stub out "
+ "of range (input file too large)"), abfd);
return FALSE;
}
push_thumb2_insn32 (htab, output_bfd, current_stub_contents,
create_instruction_branch_absolute
(initial_insn_addr - current_stub_contents));
-
/* Fill the remaining of the stub with deterministic contents. */
current_stub_contents =
}
else
{
- bfd_boolean is_dp = /* DP encoding. */
+ bfd_boolean is_dp = /* DP encoding. */
(initial_insn & 0xfe100f00) == 0xec100b00;
bfd_boolean is_ia_nobang = /* (IA without !). */
(((initial_insn << 7) >> 28) & 0xd) == 0x4;
if ((signed) branch_to_veneer < -(1 << 25)
|| (signed) branch_to_veneer >= (1 << 25))
- (*_bfd_error_handler) (_("%B: error: VFP11 veneer out of "
- "range"), output_bfd);
+ _bfd_error_handler (_("%B: error: VFP11 veneer out of "
+ "range"), output_bfd);
insn |= (branch_to_veneer >> 2) & 0xffffff;
contents[endianflip ^ target] = insn & 0xff;
if ((signed) branch_from_veneer < -(1 << 25)
|| (signed) branch_from_veneer >= (1 << 25))
- (*_bfd_error_handler) (_("%B: error: VFP11 veneer out of "
- "range"), output_bfd);
+ _bfd_error_handler (_("%B: error: VFP11 veneer out of "
+ "range"), output_bfd);
/* Original instruction. */
insn = errnode->u.v.branch->u.b.vfp_insn;
((signed) branch_to_veneer >= (1 << 24)) ?
branch_to_veneer - (1 << 24) : 0;
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B(%#x): error: Cannot create STM32L4XX veneer. "
"Jump out of range by %ld bytes. "
"Cannot encode branch instruction. "),
STM32L4XX_ERRATUM_LDM_VENEER_SIZE) < -(1 << 24)
|| (signed) (veneer_r - veneer) >= (1 << 24))
{
- (*_bfd_error_handler) (_("%B: error: Cannot create STM32L4XX "
- "veneer."), output_bfd);
+ _bfd_error_handler (_("%B: error: Cannot create STM32L4XX "
+ "veneer."), output_bfd);
continue;
}
return arm_data == NULL ? 0 : arm_data->additional_reloc_count;
}
-static unsigned int
-elf32_arm_count_output_relocs (struct bfd_link_info * info,
- asection * o,
- bfd_boolean rela)
-{
- struct bfd_elf_section_data *esdo;
- struct bfd_link_order *p;
- bfd_size_type count;
-
- esdo = elf_section_data (o->output_section);
- if (esdo->this_hdr.sh_type != SHT_ARM_EXIDX)
- return _bfd_elf_default_count_output_relocs (info, o, rela);
-
- /* PR 20595: Skip relocations for deleted exidx entries. */
- count = 0;
- for (p = o->map_head.link_order; p != NULL; p = p->next)
- {
- struct _arm_elf_section_data *arm_data;
- struct bfd_elf_section_data *esd;
- arm_unwind_table_edit *edit_list;
- Elf_Internal_Rela *relocs;
- asection *sec;
- bfd_size_type num_rel;
- bfd_size_type num_rela;
- unsigned int i;
-
- if (p->type == bfd_section_reloc_link_order
- || p->type == bfd_symbol_reloc_link_order)
- {
- count++;
- continue;
- }
-
- sec = p->u.indirect.section;
- arm_data = get_arm_elf_section_data (sec);
- esd = &arm_data->elf;
-
- if (arm_data->additional_reloc_count)
- count += arm_data->additional_reloc_count;
-
- edit_list = arm_data->u.exidx.unwind_edit_list;
- if (!edit_list)
- {
- count += sec->reloc_count;
- continue;
- }
-
- relocs = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL,
- info->keep_memory);
- num_rel = esd->rel.hdr ? NUM_SHDR_ENTRIES (esd->rel.hdr) : 0;
- num_rela = esd->rela.hdr ? NUM_SHDR_ENTRIES (esd->rela.hdr) : 0;
- if (rela)
- relocs += num_rel;
-
- for (i = 0; i < (rela ? num_rela : num_rel); i++)
- {
- arm_unwind_table_edit *edit_node;
- unsigned int index;
-
- index = (relocs[i].r_offset - sec->vma) / 8;
-
- for (edit_node = edit_list;
- edit_node->next && edit_node->next->index > index;
- edit_node++);
-
- if (edit_node->type != DELETE_EXIDX_ENTRY
- || edit_node->index != index)
- count++;
- }
- }
-
- return count;
-}
-
/* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which
- has a type >= SHT_LOOS. Returns TRUE if these fields were initialised
+ has a type >= SHT_LOOS. Returns TRUE if these fields were initialised
FALSE otherwise. ISECTION is the best guess matching section from the
input bfd IBFD, but it might be NULL. */
== iheaders[isection->sh_link]->bfd_section->output_section)
break;
}
-
+
if (i == 0)
{
/* Failing that we have to find a matching section ourselves. If
sym->flags |= BSF_KEEP;
}
-static bfd_boolean
-emit_relocs (bfd * output_bfd,
- asection * input_section,
- Elf_Internal_Shdr * input_rel_hdr,
- Elf_Internal_Rela * internal_relocs,
- struct elf_link_hash_entry ** rel_hash,
- bfd_boolean (* fallback) (bfd *, asection *,
- Elf_Internal_Shdr *,
- Elf_Internal_Rela *,
- struct elf_link_hash_entry **))
-{
- _arm_elf_section_data *arm_data;
- struct bfd_elf_section_reloc_data *output_reldata;
- Elf_Internal_Shdr *output_rel_hdr;
- Elf_Internal_Rela *irela;
- Elf_Internal_Rela *irelaend;
- asection *output_section;
- const struct elf_backend_data *bed;
- void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
- struct bfd_elf_section_data *esdo;
- arm_unwind_table_edit *edit_list, *edit_tail;
- bfd_byte *erel;
- bfd_vma offset;
-
- arm_data = get_arm_elf_section_data (input_section);
-
- if (!arm_data || arm_data->elf.this_hdr.sh_type != SHT_ARM_EXIDX)
- goto fallback_label;
-
- edit_list = arm_data->u.exidx.unwind_edit_list;
- edit_tail = arm_data->u.exidx.unwind_edit_tail;
-
- if (!edit_list)
- goto fallback_label;
-
- output_section = input_section->output_section;
- offset = output_section->vma + input_section->output_offset;
-
- bed = get_elf_backend_data (output_bfd);
- esdo = elf_section_data (output_section);
- if (esdo->rel.hdr && esdo->rel.hdr->sh_entsize == input_rel_hdr->sh_entsize)
- {
- output_reldata = &esdo->rel;
- swap_out = bed->s->swap_reloc_out;
- }
- else if (esdo->rela.hdr
- && esdo->rela.hdr->sh_entsize == input_rel_hdr->sh_entsize)
- {
- output_reldata = &esdo->rela;
- swap_out = bed->s->swap_reloca_out;
- }
- else
- {
- (*_bfd_error_handler)
- (_("%B: relocation size mismatch in %B section %A"),
- output_bfd, input_section->owner, input_section);
- bfd_set_error (bfd_error_wrong_format);
- return FALSE;
- }
-
- output_rel_hdr = output_reldata->hdr;
- erel = output_rel_hdr->contents;
- erel += output_reldata->count * input_rel_hdr->sh_entsize;
-
- irela = internal_relocs;
- irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr)
- * bed->s->int_rels_per_ext_rel);
- while (irela < irelaend)
- {
- arm_unwind_table_edit *edit_node, *edit_next;
- Elf_Internal_Rela rel;
- bfd_vma bias;
- bfd_vma index;
-
- index = (irela->r_offset - offset) / 8;
-
- bias = 0;
- edit_node = edit_list;
- for (edit_next = edit_list;
- edit_next && edit_next->index <= index;
- edit_next = edit_node->next)
- {
- bias++;
- edit_node = edit_next;
- }
-
- if (edit_node->type != DELETE_EXIDX_ENTRY || edit_node->index != index)
- {
- rel.r_offset = irela->r_offset - bias * 8;
- rel.r_info = irela->r_info;
- rel.r_addend = irela->r_addend;
-
- (*swap_out) (output_bfd, &rel, erel);
- erel += output_rel_hdr->sh_entsize;
- output_reldata->count++;
- }
-
- irela += bed->s->int_rels_per_ext_rel;
- }
-
- if (edit_tail->type == INSERT_EXIDX_CANTUNWIND_AT_END)
- {
- /* New relocation entity. */
- asection *text_sec = edit_tail->linked_section;
- asection *text_out = text_sec->output_section;
- bfd_vma exidx_offset = offset + input_section->size - 8;
- Elf_Internal_Rela rel;
-
- rel.r_addend = 0;
- rel.r_offset = exidx_offset;
- rel.r_info = ELF32_R_INFO (text_out->target_index, R_ARM_PREL31);
- (*swap_out) (output_bfd, &rel, erel);
- output_reldata->count++;
- }
-
- return TRUE;
-
-fallback_label:
- return fallback (output_bfd, input_section, input_rel_hdr,
- internal_relocs, rel_hash);
-}
-
-static bfd_boolean
-elf32_arm_emit_relocs (bfd * output_bfd,
- asection * input_section,
- Elf_Internal_Shdr * input_rel_hdr,
- Elf_Internal_Rela * internal_relocs,
- struct elf_link_hash_entry ** rel_hash)
-{
- return emit_relocs (output_bfd, input_section, input_rel_hdr, internal_relocs,
- rel_hash, _bfd_elf_link_output_relocs);
-}
-
#undef elf_backend_copy_special_section_fields
#define elf_backend_copy_special_section_fields elf32_arm_copy_special_section_fields
#define bfd_elf32_bfd_final_link elf32_arm_final_link
#define bfd_elf32_get_synthetic_symtab elf32_arm_get_synthetic_symtab
-#define elf_backend_emit_relocs elf32_arm_emit_relocs
#define elf_backend_get_symbol_type elf32_arm_get_symbol_type
#define elf_backend_gc_mark_hook elf32_arm_gc_mark_hook
#define elf_backend_gc_mark_extra_sections elf32_arm_gc_mark_extra_sections
#define elf_backend_gc_sweep_hook elf32_arm_gc_sweep_hook
#define elf_backend_check_relocs elf32_arm_check_relocs
+#define elf_backend_update_relocs elf32_arm_update_relocs
#define elf_backend_relocate_section elf32_arm_relocate_section
#define elf_backend_write_section elf32_arm_write_section
#define elf_backend_adjust_dynamic_symbol elf32_arm_adjust_dynamic_symbol
#define elf_backend_begin_write_processing elf32_arm_begin_write_processing
#define elf_backend_add_symbol_hook elf32_arm_add_symbol_hook
#define elf_backend_count_additional_relocs elf32_arm_count_additional_relocs
-#define elf_backend_count_output_relocs elf32_arm_count_output_relocs
#define elf_backend_symbol_processing elf32_arm_backend_symbol_processing
#define elf_backend_can_refcount 1
elf_vxworks_final_write_processing (abfd, linker);
}
-static bfd_boolean
-elf32_arm_vxworks_emit_relocs (bfd * output_bfd,
- asection * input_section,
- Elf_Internal_Shdr * input_rel_hdr,
- Elf_Internal_Rela * internal_relocs,
- struct elf_link_hash_entry ** rel_hash)
-{
- return emit_relocs (output_bfd, input_section, input_rel_hdr, internal_relocs,
- rel_hash, elf_vxworks_emit_relocs);
-}
-
#undef elf32_bed
#define elf32_bed elf32_arm_vxworks_bed
#undef elf_backend_final_write_processing
#define elf_backend_final_write_processing elf32_arm_vxworks_final_write_processing
#undef elf_backend_emit_relocs
-#define elf_backend_emit_relocs elf32_arm_vxworks_emit_relocs
+#define elf_backend_emit_relocs elf_vxworks_emit_relocs
#undef elf_backend_may_use_rel_p
#define elf_backend_may_use_rel_p 0
object file when linking. */
static bfd_boolean
-elf32_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
+elf32_arm_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
{
+ bfd *obfd = info->output_bfd;
flagword out_flags;
flagword in_flags;
bfd_boolean flags_compatible = TRUE;
asection *sec;
/* Check if we have the same endianness. */
- if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+ if (! _bfd_generic_verify_endian_match (ibfd, info))
return FALSE;
if (! is_arm_elf (ibfd) || ! is_arm_elf (obfd))
return TRUE;
- if (!elf32_arm_merge_eabi_attributes (ibfd, obfd))
+ if (!elf32_arm_merge_eabi_attributes (ibfd, info))
return FALSE;
/* The input BFD must have had its flags initialised. */
#define ELF_DYNAMIC_SEC_FLAGS \
(SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED)
-#undef elf_backend_emit_relocs
-#define elf_backend_emit_relocs elf32_arm_emit_relocs
+#undef elf_backend_emit_relocs
#undef bfd_elf32_bfd_link_hash_table_create
#define bfd_elf32_bfd_link_hash_table_create elf32_arm_symbian_link_hash_table_create