0x00000000, /* src_mask. */
0x00000000, /* dst_mask. */
FALSE), /* pcrel_offset. */
+ /* Relocations for Armv8.1-M Mainline. */
+ HOWTO (R_ARM_THM_BF16, /* type. */
+ 0, /* rightshift. */
+ 1, /* size (0 = byte, 1 = short, 2 = long). */
+ 16, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont,/* do not complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_ARM_THM_BF16", /* name. */
+ FALSE, /* partial_inplace. */
+ 0x001f0ffe, /* src_mask. */
+ 0x001f0ffe, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+ HOWTO (R_ARM_THM_BF12, /* type. */
+ 0, /* rightshift. */
+ 1, /* size (0 = byte, 1 = short, 2 = long). */
+ 12, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont,/* do not complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_ARM_THM_BF12", /* name. */
+ FALSE, /* partial_inplace. */
+ 0x00010ffe, /* src_mask. */
+ 0x00010ffe, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+ HOWTO (R_ARM_THM_BF18, /* type. */
+ 0, /* rightshift. */
+ 1, /* size (0 = byte, 1 = short, 2 = long). */
+ 18, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont,/* do not complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_ARM_THM_BF18", /* name. */
+ FALSE, /* partial_inplace. */
+ 0x007f0ffe, /* src_mask. */
+ 0x007f0ffe, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
};
/* 160 onwards: */
{BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC, R_ARM_THM_ALU_ABS_G3_NC},
{BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC, R_ARM_THM_ALU_ABS_G2_NC},
{BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC, R_ARM_THM_ALU_ABS_G1_NC},
- {BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC, R_ARM_THM_ALU_ABS_G0_NC}
+ {BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC, R_ARM_THM_ALU_ABS_G0_NC},
+ {BFD_RELOC_ARM_THUMB_BF17, R_ARM_THM_BF16},
+ {BFD_RELOC_ARM_THUMB_BF13, R_ARM_THM_BF12},
+ {BFD_RELOC_ARM_THUMB_BF19, R_ARM_THM_BF18}
};
static reloc_howto_type *
#define CMSE_PREFIX "__acle_se_"
+#define CMSE_STUB_NAME ".gnu.sgstubs"
+
/* The name of the dynamic interpreter. This is put in the .interp
section. */
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, Tag_CPU_arch);
/* Force return logic to be reviewed for each new architecture. */
- BFD_ASSERT (arch <= TAG_CPU_ARCH_V8M_MAIN);
+ BFD_ASSERT (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
if (arch == TAG_CPU_ARCH_V6_M
|| arch == TAG_CPU_ARCH_V6S_M
|| arch == TAG_CPU_ARCH_V7E_M
|| arch == TAG_CPU_ARCH_V8M_BASE
- || arch == TAG_CPU_ARCH_V8M_MAIN)
+ || arch == TAG_CPU_ARCH_V8M_MAIN
+ || arch == TAG_CPU_ARCH_V8_1M_MAIN)
return TRUE;
return FALSE;
arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, Tag_CPU_arch);
/* Force return logic to be reviewed for each new architecture. */
- BFD_ASSERT (arch <= TAG_CPU_ARCH_V8M_MAIN);
+ BFD_ASSERT (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
return (arch == TAG_CPU_ARCH_V6T2
|| arch == TAG_CPU_ARCH_V7
|| arch == TAG_CPU_ARCH_V7E_M
|| arch == TAG_CPU_ARCH_V8
|| arch == TAG_CPU_ARCH_V8R
- || arch == TAG_CPU_ARCH_V8M_MAIN);
+ || arch == TAG_CPU_ARCH_V8M_MAIN
+ || arch == TAG_CPU_ARCH_V8_1M_MAIN);
}
/* Determine whether Thumb-2 BL instruction is available. */
bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, Tag_CPU_arch);
/* Force return logic to be reviewed for each new architecture. */
- BFD_ASSERT (arch <= TAG_CPU_ARCH_V8M_MAIN);
+ BFD_ASSERT (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
/* Architecture was introduced after ARMv6T2 (eg. ARMv6-M). */
return (arch == TAG_CPU_ARCH_V6T2
Tag_CPU_arch);
/* Force return logic to be reviewed for each new architecture. */
- BFD_ASSERT (arch <= TAG_CPU_ARCH_V8M_MAIN);
+ BFD_ASSERT (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
return (arch == TAG_CPU_ARCH_V6T2
|| arch == TAG_CPU_ARCH_V6K
if ((input_section->flags & SEC_CODE) == 0)
return NULL;
+ /* If the input section is the CMSE stubs one and it needs a long
+ branch stub to reach it's final destination, give up with an
+ error message: this is not supported. See PR ld/24709. */
+ if (!strncmp (input_section->name, CMSE_STUB_NAME, strlen(CMSE_STUB_NAME)))
+ {
+ bfd *output_bfd = htab->obfd;
+ asection *out_sec = bfd_get_section_by_name (output_bfd, CMSE_STUB_NAME);
+
+ _bfd_error_handler (_("ERROR: CMSE stub (%s section) too far "
+ "(%#" PRIx64 ") from destination (%#" PRIx64 ")"),
+ CMSE_STUB_NAME,
+ (uint64_t)out_sec->output_section->vma
+ + out_sec->output_offset,
+ (uint64_t)sym_sec->output_section->vma
+ + sym_sec->output_offset
+ + h->root.root.u.def.value);
+ /* Exit, rather than leave incompletely processed
+ relocations. */
+ xexit(1);
+ }
+
/* If this input section is part of a group of sections sharing one
stub section, then use the id of the first section in the group.
Stub names need to include a section id, as there may well be
switch (stub_type)
{
case arm_stub_cmse_branch_thumb_only:
- return ".gnu.sgstubs";
+ return CMSE_STUB_NAME;
default:
BFD_ASSERT (!arm_dedicated_stub_output_section_required (stub_type));
s = bfd_get_linker_section (abfd, name);
BFD_ASSERT (s != NULL);
- contents = (bfd_byte *) bfd_alloc (abfd, size);
+ contents = (bfd_byte *) bfd_zalloc (abfd, size);
BFD_ASSERT (s->size == size);
s->contents = contents;
*unresolved_reloc_p = FALSE;
return bfd_reloc_ok;
+ case R_ARM_THM_BF16:
+ {
+ bfd_vma relocation;
+ bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
+ bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
+
+ if (globals->use_rel)
+ {
+ bfd_vma immA = (upper_insn & 0x001f);
+ bfd_vma immB = (lower_insn & 0x07fe) >> 1;
+ bfd_vma immC = (lower_insn & 0x0800) >> 11;
+ addend = (immA << 12);
+ addend |= (immB << 2);
+ addend |= (immC << 1);
+ addend |= 1;
+ /* Sign extend. */
+ signed_addend = (addend & 0x10000) ? addend - (1 << 17) : addend;
+ }
+
+ relocation = value + signed_addend;
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ /* Put RELOCATION back into the insn. */
+ {
+ bfd_vma immA = (relocation & 0x0001f000) >> 12;
+ bfd_vma immB = (relocation & 0x00000ffc) >> 2;
+ bfd_vma immC = (relocation & 0x00000002) >> 1;
+
+ upper_insn = (upper_insn & 0xffe0) | immA;
+ lower_insn = (lower_insn & 0xf001) | (immC << 11) | (immB << 1);
+ }
+
+ /* Put the relocated value back in the object file: */
+ bfd_put_16 (input_bfd, upper_insn, hit_data);
+ bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
+
+ return bfd_reloc_ok;
+ }
+
+ case R_ARM_THM_BF12:
+ {
+ bfd_vma relocation;
+ bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
+ bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
+
+ if (globals->use_rel)
+ {
+ bfd_vma immA = (upper_insn & 0x0001);
+ bfd_vma immB = (lower_insn & 0x07fe) >> 1;
+ bfd_vma immC = (lower_insn & 0x0800) >> 11;
+ addend = (immA << 12);
+ addend |= (immB << 2);
+ addend |= (immC << 1);
+ addend |= 1;
+ /* Sign extend. */
+ addend = (addend & 0x1000) ? addend - (1 << 13) : addend;
+ signed_addend = addend;
+ }
+
+ relocation = value + signed_addend;
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ /* Put RELOCATION back into the insn. */
+ {
+ bfd_vma immA = (relocation & 0x00001000) >> 12;
+ bfd_vma immB = (relocation & 0x00000ffc) >> 2;
+ bfd_vma immC = (relocation & 0x00000002) >> 1;
+
+ upper_insn = (upper_insn & 0xfffe) | immA;
+ lower_insn = (lower_insn & 0xf001) | (immC << 11) | (immB << 1);
+ }
+
+ /* Put the relocated value back in the object file: */
+ bfd_put_16 (input_bfd, upper_insn, hit_data);
+ bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
+
+ return bfd_reloc_ok;
+ }
+
+ case R_ARM_THM_BF18:
+ {
+ bfd_vma relocation;
+ bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
+ bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
+
+ if (globals->use_rel)
+ {
+ bfd_vma immA = (upper_insn & 0x007f);
+ bfd_vma immB = (lower_insn & 0x07fe) >> 1;
+ bfd_vma immC = (lower_insn & 0x0800) >> 11;
+ addend = (immA << 12);
+ addend |= (immB << 2);
+ addend |= (immC << 1);
+ addend |= 1;
+ /* Sign extend. */
+ addend = (addend & 0x40000) ? addend - (1 << 19) : addend;
+ signed_addend = addend;
+ }
+
+ relocation = value + signed_addend;
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ /* Put RELOCATION back into the insn. */
+ {
+ bfd_vma immA = (relocation & 0x0007f000) >> 12;
+ bfd_vma immB = (relocation & 0x00000ffc) >> 2;
+ bfd_vma immC = (relocation & 0x00000002) >> 1;
+
+ upper_insn = (upper_insn & 0xff80) | immA;
+ lower_insn = (lower_insn & 0xf001) | (immC << 11) | (immB << 1);
+ }
+
+ /* Put the relocated value back in the object file: */
+ bfd_put_16 (input_bfd, upper_insn, hit_data);
+ bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
+
+ return bfd_reloc_ok;
+ }
+
default:
return bfd_reloc_notsupported;
}
return bfd_mach_arm_8M_BASE;
case TAG_CPU_ARCH_V8M_MAIN:
return bfd_mach_arm_8M_MAIN;
+ case TAG_CPU_ARCH_V8_1M_MAIN:
+ return bfd_mach_arm_8_1M_MAIN;
default:
/* Force entry to be added for any new known Tag_CPU_arch value. */
T(V8M_MAIN), /* V8-M BASELINE. */
T(V8M_MAIN) /* V8-M MAINLINE. */
};
+ const int v8_1m_mainline[] =
+ {
+ -1, /* PRE_V4. */
+ -1, /* V4. */
+ -1, /* V4T. */
+ -1, /* V5T. */
+ -1, /* V5TE. */
+ -1, /* V5TEJ. */
+ -1, /* V6. */
+ -1, /* V6KZ. */
+ -1, /* V6T2. */
+ -1, /* V6K. */
+ T(V8_1M_MAIN), /* V7. */
+ T(V8_1M_MAIN), /* V6_M. */
+ T(V8_1M_MAIN), /* V6S_M. */
+ T(V8_1M_MAIN), /* V7E_M. */
+ -1, /* V8. */
+ -1, /* V8R. */
+ T(V8_1M_MAIN), /* V8-M BASELINE. */
+ T(V8_1M_MAIN), /* V8-M MAINLINE. */
+ -1, /* Unused (18). */
+ -1, /* Unused (19). */
+ -1, /* Unused (20). */
+ T(V8_1M_MAIN) /* V8.1-M MAINLINE. */
+ };
const int v4t_plus_v6_m[] =
{
-1, /* PRE_V4. */
-1, /* V8R. */
T(V8M_BASE), /* V8-M BASELINE. */
T(V8M_MAIN), /* V8-M MAINLINE. */
+ -1, /* Unused (18). */
+ -1, /* Unused (19). */
+ -1, /* Unused (20). */
+ T(V8_1M_MAIN), /* V8.1-M MAINLINE. */
T(V4T_PLUS_V6_M) /* V4T plus V6_M. */
};
const int *comb[] =
v8r,
v8m_baseline,
v8m_mainline,
+ NULL,
+ NULL,
+ NULL,
+ v8_1m_mainline,
/* Pseudo-architecture. */
v4t_plus_v6_m
};
case Tag_CPU_unaligned_access:
case Tag_T2EE_use:
case Tag_MPextension_use:
+ case Tag_MVE_arch:
/* Use the largest value specified. */
if (in_attr[i].i > out_attr[i].i)
out_attr[i].i = in_attr[i].i;
/* This relocation describes which C++ vtable entries are actually
used. Record for later use during GC. */
case R_ARM_GNU_VTENTRY:
- BFD_ASSERT (h != NULL);
- if (h != NULL
- && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
return FALSE;
break;
}
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;
+ offset = i->output_offset;
if (eadi->elf.rel.hdr &&
eadi->elf.rel.hdr->sh_entsize == rel_hdr->sh_entsize)
struct elf_link_hash_entry **sym_hashes;
struct elf32_arm_link_hash_entry *cmse_hash;
bfd_boolean again, is_v8m, first_bfd_browse = TRUE;
+ bfd_boolean debug_sec_need_to_be_marked = FALSE;
+ asection *isec;
_bfd_elf_gc_mark_extra_sections (info, gc_mark_hook);
if (!cmse_sec->gc_mark
&& !_bfd_elf_gc_mark (info, cmse_sec, gc_mark_hook))
return FALSE;
+ /* The debug sections related to these secure entry
+ functions are marked on enabling below flag. */
+ debug_sec_need_to_be_marked = TRUE;
}
}
+
+ if (debug_sec_need_to_be_marked)
+ {
+ /* Looping over all the sections of the object file containing
+ Armv8-M secure entry functions and marking all the debug
+ sections. */
+ for (isec = sub->sections; isec != NULL; isec = isec->next)
+ {
+ /* If not a debug sections, skip it. */
+ if (!isec->gc_mark && (isec->flags & SEC_DEBUGGING))
+ isec->gc_mark = 1 ;
+ }
+ debug_sec_need_to_be_marked = FALSE;
+ }
}
}
first_bfd_browse = FALSE;
BFD_ARM_SPECIAL_SYM_TYPE_ANY);
}
-/* This is a copy of elf_find_function() from elf.c except that
+/* This is a version of _bfd_elf_find_function() from dwarf2.c except that
ARM mapping symbols are ignored when looking for function names
and STT_ARM_TFUNC is considered to a function type. */
static bfd_boolean
-arm_elf_find_function (bfd * abfd ATTRIBUTE_UNUSED,
+arm_elf_find_function (bfd * abfd,
asymbol ** symbols,
asection * section,
bfd_vma offset,
bfd_vma low_func = 0;
asymbol ** p;
+ if (symbols == NULL)
+ return FALSE;
+
+ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+ return FALSE;
+
for (p = symbols; *p != NULL; p++)
{
elf_symbol_type *q;
if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
filename_ptr, functionname_ptr,
line_ptr, discriminator_ptr,
- dwarf_debug_sections, 0,
+ dwarf_debug_sections,
& elf_tdata (abfd)->dwarf2_find_line_info))
{
if (!*functionname_ptr)
}
static void
-elf32_arm_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
+arm_final_write_processing (bfd *abfd)
{
bfd_arm_update_notes (abfd, ARM_NOTE_SECTION);
}
+static bfd_boolean
+elf32_arm_final_write_processing (bfd *abfd)
+{
+ arm_final_write_processing (abfd);
+ return _bfd_elf_final_write_processing (abfd);
+}
+
/* Return TRUE if this is an unwinding table entry. */
static bfd_boolean
&& nacl_modify_segment_map (abfd, info));
}
-static void
-elf32_arm_nacl_final_write_processing (bfd *abfd, bfd_boolean linker)
+static bfd_boolean
+elf32_arm_nacl_final_write_processing (bfd *abfd)
{
- elf32_arm_final_write_processing (abfd, linker);
- nacl_final_write_processing (abfd, linker);
+ arm_final_write_processing (abfd);
+ return nacl_final_write_processing (abfd);
}
static bfd_vma
return ret;
}
-static void
-elf32_arm_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
+static bfd_boolean
+elf32_arm_vxworks_final_write_processing (bfd *abfd)
{
- elf32_arm_final_write_processing (abfd, linker);
- elf_vxworks_final_write_processing (abfd, linker);
+ arm_final_write_processing (abfd);
+ return elf_vxworks_final_write_processing (abfd);
}
#undef elf32_bed