#include <limits.h>
#include "bfd.h"
+#include "bfd_stdint.h"
#include "libiberty.h"
#include "libbfd.h"
#include "elf-bfd.h"
#define ARM_ELF_ABI_VERSION 0
#define ARM_ELF_OS_ABI_VERSION ELFOSABI_ARM
+/* The Adjusted Place, as defined by AAELF. */
+#define Pa(X) ((X) & 0xfffffffc)
+
static bfd_boolean elf32_arm_write_section (bfd *output_bfd,
struct bfd_link_info *link_info,
asection *sec,
0xe08cc00f, /* add ip, ip, pc */
0xe52dc008, /* str ip, [sp, #-8]! */
/* Second bundle: */
- 0xe7dfcf1f, /* bfc ip, #30, #2 */
- 0xe59cc000, /* ldr ip, [ip] */
+ 0xe3ccc103, /* bic ip, ip, #0xc0000000 */
+ 0xe59cc000, /* ldr ip, [ip] */
0xe3ccc13f, /* bic ip, ip, #0xc000000f */
- 0xe12fff1c, /* bx ip */
+ 0xe12fff1c, /* bx ip */
/* Third bundle: */
- 0xe320f000, /* nop */
- 0xe320f000, /* nop */
- 0xe320f000, /* nop */
+ 0xe320f000, /* nop */
+ 0xe320f000, /* nop */
+ 0xe320f000, /* nop */
/* .Lplt_tail: */
0xe50dc004, /* str ip, [sp, #-4] */
/* Fourth bundle: */
- 0xe7dfcf1f, /* bfc ip, #30, #2 */
- 0xe59cc000, /* ldr ip, [ip] */
+ 0xe3ccc103, /* bic ip, ip, #0xc0000000 */
+ 0xe59cc000, /* ldr ip, [ip] */
0xe3ccc13f, /* bic ip, ip, #0xc000000f */
- 0xe12fff1c, /* bx ip */
+ 0xe12fff1c, /* bx ip */
};
#define ARM_NACL_PLT_TAIL_OFFSET (11 * 4)
if (htab->root.iplt == NULL)
{
- s = bfd_make_section_with_flags (dynobj, ".iplt",
- flags | SEC_READONLY | SEC_CODE);
+ s = bfd_make_section_anyway_with_flags (dynobj, ".iplt",
+ flags | SEC_READONLY | SEC_CODE);
if (s == NULL
|| !bfd_set_section_alignment (dynobj, s, bed->plt_alignment))
return FALSE;
if (htab->root.irelplt == NULL)
{
- s = bfd_make_section_with_flags (dynobj, RELOC_SECTION (htab, ".iplt"),
- flags | SEC_READONLY);
+ s = bfd_make_section_anyway_with_flags (dynobj,
+ RELOC_SECTION (htab, ".iplt"),
+ flags | SEC_READONLY);
if (s == NULL
|| !bfd_set_section_alignment (dynobj, s, bed->s->log_file_align))
return FALSE;
if (htab->root.igotplt == NULL)
{
- s = bfd_make_section_with_flags (dynobj, ".igot.plt", flags);
+ s = bfd_make_section_anyway_with_flags (dynobj, ".igot.plt", flags);
if (s == NULL
|| !bfd_set_section_alignment (dynobj, s, bed->s->log_file_align))
return FALSE;
if (!_bfd_elf_create_dynamic_sections (dynobj, info))
return FALSE;
- htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
if (!info->shared)
- htab->srelbss = bfd_get_section_by_name (dynobj,
- RELOC_SECTION (htab, ".bss"));
+ htab->srelbss = bfd_get_linker_section (dynobj,
+ RELOC_SECTION (htab, ".bss"));
if (htab->vxworks_p)
{
/* Do not include empty glue sections in the output. */
if (abfd != NULL)
{
- s = bfd_get_section_by_name (abfd, name);
+ s = bfd_get_linker_section (abfd, name);
if (s != NULL)
s->flags |= SEC_EXCLUDE;
}
BFD_ASSERT (abfd != NULL);
- s = bfd_get_section_by_name (abfd, name);
+ s = bfd_get_linker_section (abfd, name);
BFD_ASSERT (s != NULL);
contents = (bfd_byte *) bfd_alloc (abfd, size);
BFD_ASSERT (globals != NULL);
BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
- s = bfd_get_section_by_name
+ s = bfd_get_linker_section
(globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
BFD_ASSERT (s != NULL);
if (globals->bx_glue_offset[reg])
return;
- s = bfd_get_section_by_name
+ s = bfd_get_linker_section
(globals->bfd_of_glue_owner, ARM_BX_GLUE_SECTION_NAME);
BFD_ASSERT (s != NULL);
BFD_ASSERT (hash_table != NULL);
BFD_ASSERT (hash_table->bfd_of_glue_owner != NULL);
- s = bfd_get_section_by_name
+ s = bfd_get_linker_section
(hash_table->bfd_of_glue_owner, VFP11_ERRATUM_VENEER_SECTION_NAME);
sec_data = elf32_arm_section_data (s);
{
asection * sec;
- sec = bfd_get_section_by_name (abfd, name);
+ sec = bfd_get_linker_section (abfd, name);
if (sec != NULL)
/* Already made. */
return TRUE;
- sec = bfd_make_section_with_flags (abfd, name, ARM_GLUE_SECTION_FLAGS);
+ sec = bfd_make_section_anyway_with_flags (abfd, name, ARM_GLUE_SECTION_FLAGS);
if (sec == NULL
|| !bfd_set_section_alignment (abfd, sec, 2))
my_offset = myh->root.u.def.value;
- s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
- THUMB2ARM_GLUE_SECTION_NAME);
+ s = bfd_get_linker_section (globals->bfd_of_glue_owner,
+ THUMB2ARM_GLUE_SECTION_NAME);
BFD_ASSERT (s != NULL);
BFD_ASSERT (s->contents != NULL);
BFD_ASSERT (globals != NULL);
BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
- s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
- ARM2THUMB_GLUE_SECTION_NAME);
+ s = bfd_get_linker_section (globals->bfd_of_glue_owner,
+ ARM2THUMB_GLUE_SECTION_NAME);
BFD_ASSERT (s != NULL);
BFD_ASSERT (s->contents != NULL);
BFD_ASSERT (s->output_section != NULL);
BFD_ASSERT (globals != NULL);
BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
- s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
- ARM2THUMB_GLUE_SECTION_NAME);
+ s = bfd_get_linker_section (globals->bfd_of_glue_owner,
+ ARM2THUMB_GLUE_SECTION_NAME);
BFD_ASSERT (s != NULL);
BFD_ASSERT (s->contents != NULL);
BFD_ASSERT (s->output_section != NULL);
BFD_ASSERT (globals != NULL);
BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
- s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
- ARM_BX_GLUE_SECTION_NAME);
+ s = bfd_get_linker_section (globals->bfd_of_glue_owner,
+ ARM_BX_GLUE_SECTION_NAME);
BFD_ASSERT (s != NULL);
BFD_ASSERT (s->contents != NULL);
BFD_ASSERT (s->output_section != NULL);
{
/* Calculate the displacement between the PLT slot and the
common tail that's part of the special initial PLT slot. */
- bfd_vma tail_displacement
+ int32_t tail_displacement
= ((splt->output_section->vma + splt->output_offset
+ ARM_NACL_PLT_TAIL_OFFSET)
- (plt_address + htab->plt_entry_size + 4));
/* Calculate the displacement between the PLT slot and the entry
in the GOT. The offset accounts for the value produced by
adding to pc in the penultimate instruction of the PLT stub. */
- got_displacement = got_address - (plt_address + htab->plt_entry_size);
+ got_displacement = (got_address
+ - (plt_address + htab->plt_entry_size));
/* NaCl does not support interworking at all. */
BFD_ASSERT (!elf32_arm_plt_needs_thumb_stub_p (info, arm_plt));
}
relocation = value + signed_addend;
- relocation -= (input_section->output_section->vma
- + input_section->output_offset
- + rel->r_offset);
+ relocation -= Pa (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
value = abs (relocation);
insn = bfd_get_16 (input_bfd, hit_data);
if (globals->use_rel)
- addend = (insn & 0x00ff) << 2;
+ addend = ((((insn & 0x00ff) << 2) + 4) & 0x3ff) -4;
relocation = value + addend;
- relocation -= (input_section->output_section->vma
- + input_section->output_offset
- + rel->r_offset);
+ relocation -= Pa (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
value = abs (relocation);
}
relocation = value + signed_addend;
- relocation -= (input_section->output_section->vma
- + input_section->output_offset
- + rel->r_offset);
+ relocation -= Pa (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
value = abs (relocation);
(_("%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"),
input_bfd, input_section,
(long) rel->r_offset, howto->name);
- return (bfd_reloc_status_type) FALSE;
+ return bfd_reloc_notsupported;
}
else
value = tpoff (info, value);
{
asection *sec, *osec;
- sec = bfd_get_section_by_name (ibfd, name);
+ sec = bfd_get_linker_section (ibfd, name);
if (sec == NULL || (sec->flags & SEC_EXCLUDE) != 0)
return TRUE;
return bfd_mach_arm_iWMMXt2;
if (strcmp (name, "IWMMXT") == 0)
- return bfd_mach_arm_iWMMXt;
+ return bfd_mach_arm_iWMMXt;
}
return bfd_mach_arm_5TE;
T(V7E_M), /* V6S_M. */
T(V7E_M) /* V7E_M. */
};
+ const int v8[] =
+ {
+ T(V8), /* PRE_V4. */
+ T(V8), /* V4. */
+ T(V8), /* V4T. */
+ T(V8), /* V5T. */
+ T(V8), /* V5TE. */
+ T(V8), /* V5TEJ. */
+ T(V8), /* V6. */
+ T(V8), /* V6KZ. */
+ T(V8), /* V6T2. */
+ T(V8), /* V6K. */
+ T(V8), /* V7. */
+ T(V8), /* V6_M. */
+ T(V8), /* V6S_M. */
+ T(V8), /* V7E_M. */
+ T(V8) /* V8. */
+ };
const int v4t_plus_v6_m[] =
{
-1, /* PRE_V4. */
T(V6_M), /* V6_M. */
T(V6S_M), /* V6S_M. */
T(V7E_M), /* V7E_M. */
+ T(V8), /* V8. */
T(V4T_PLUS_V6_M) /* V4T plus V6_M. */
};
const int *comb[] =
v6_m,
v6s_m,
v7e_m,
+ v8,
/* Pseudo-architecture. */
v4t_plus_v6_m
};
"ARM v6K",
"ARM v7",
"ARM v6-M",
- "ARM v6S-M"
+ "ARM v6S-M",
+ "ARM v8"
};
/* Merge Tag_CPU_arch and Tag_also_compatible_with. */
when it's 0. It might mean absence of FP hardware if
Tag_FP_arch is zero, otherwise it is effectively SP + DP. */
+#define VFP_VERSION_COUNT 8
static const struct
{
int ver;
int regs;
- } vfp_versions[7] =
+ } vfp_versions[VFP_VERSION_COUNT] =
{
{0, 0},
{1, 16},
{3, 32},
{3, 16},
{4, 32},
- {4, 16}
+ {4, 16},
+ {8, 32}
};
int ver;
int regs;
/* Now we can handle Tag_FP_arch. */
- /* Values greater than 6 aren't defined, so just pick the
- biggest */
- if (in_attr[i].i > 6 && in_attr[i].i > out_attr[i].i)
+ /* Values of VFP_VERSION_COUNT or more aren't defined, so just
+ pick the biggest. */
+ if (in_attr[i].i >= VFP_VERSION_COUNT
+ && in_attr[i].i > out_attr[i].i)
{
out_attr[i] = in_attr[i];
break;
regs = vfp_versions[out_attr[i].i].regs;
/* This assumes all possible supersets are also a valid
options. */
- for (newval = 6; newval > 0; newval--)
+ for (newval = VFP_VERSION_COUNT - 1; newval > 0; newval--)
{
if (regs == vfp_versions[newval].regs
&& ver == vfp_versions[newval].ver)
case EF_ARM_EABI_VER5:
fprintf (file, _(" [Version5 EABI]"));
+
+ if (flags & EF_ARM_ABI_FLOAT_SOFT)
+ fprintf (file, _(" [soft-float ABI]"));
+
+ if (flags & EF_ARM_ABI_FLOAT_HARD)
+ fprintf (file, _(" [hard-float ABI]"));
+
+ flags &= ~(EF_ARM_ABI_FLOAT_SOFT | EF_ARM_ABI_FLOAT_HARD);
+
eabi:
if (flags & EF_ARM_BE8)
fprintf (file, _(" [BE8]"));
/* If the symbol is a function that doesn't bind locally,
this relocation will need a PLT entry. */
- root_plt->refcount += 1;
+ if (root_plt->refcount != -1)
+ root_plt->refcount += 1;
if (!call_reloc_p)
arm_plt->noncall_refcount++;
if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
section, symbols, offset,
filename_ptr, functionname_ptr,
- line_ptr, 0,
+ line_ptr, NULL, 0,
& elf_tdata (abfd)->dwarf2_find_line_info))
{
if (!*functionname_ptr)
determine the address it must put in the global offset table, so
both the dynamic object and the regular object will refer to the
same memory location for the variable. */
- s = bfd_get_section_by_name (dynobj, ".dynbss");
+ s = bfd_get_linker_section (dynobj, ".dynbss");
BFD_ASSERT (s != NULL);
/* We must generate a R_ARM_COPY reloc to tell the dynamic linker to
{
asection *srel;
- srel = bfd_get_section_by_name (dynobj, RELOC_SECTION (globals, ".bss"));
+ srel = bfd_get_linker_section (dynobj, RELOC_SECTION (globals, ".bss"));
elf32_arm_allocate_dynrelocs (info, srel, 1);
h->needs_copy = 1;
}
/* Set the contents of the .interp section to the interpreter. */
if (info->executable)
{
- s = bfd_get_section_by_name (dynobj, ".interp");
+ s = bfd_get_linker_section (dynobj, ".interp");
BFD_ASSERT (s != NULL);
s->size = sizeof ELF_DYNAMIC_INTERPRETER;
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. On VxWorks,
the _GLOBAL_OFFSET_TABLE_ symbol is not absolute: it is relative
to the ".got" section. */
- if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+ if (h == htab->root.hdynamic
|| (!htab->vxworks_p && h == htab->root.hgot))
sym->st_shndx = SHN_ABS;
Catch this here so that we do not seg-fault later on. */
if (sgot != NULL && bfd_is_abs_section (sgot->output_section))
return FALSE;
- sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
if (elf_hash_table (info)->dynamic_sections_created)
{
name = RELOC_SECTION (htab, ".plt");
get_vma:
s = bfd_get_section_by_name (output_bfd, name);
- BFD_ASSERT (s != NULL);
+ if (s == NULL)
+ {
+ /* PR ld/14397: Issue an error message if a required section is missing. */
+ (*_bfd_error_handler)
+ (_("error: required section '%s' not found in the linker script"), name);
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
if (!htab->symbian_p)
dyn.d_un.d_ptr = s->vma;
else
if (globals != NULL && globals->byteswap_code)
i_ehdrp->e_flags |= EF_ARM_BE8;
}
+
+ if (EF_ARM_EABI_VERSION (i_ehdrp->e_flags) == EF_ARM_EABI_VER5
+ && ((i_ehdrp->e_type == ET_DYN) || (i_ehdrp->e_type == ET_EXEC)))
+ {
+ int abi = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC, Tag_ABI_VFP_args);
+ if (abi)
+ i_ehdrp->e_flags |= EF_ARM_ABI_FLOAT_HARD;
+ else
+ i_ehdrp->e_flags |= EF_ARM_ABI_FLOAT_SOFT;
+ }
}
static enum elf_reloc_type_class
/* ARM->Thumb glue. */
if (htab->arm_glue_size > 0)
{
- osi.sec = bfd_get_section_by_name (htab->bfd_of_glue_owner,
- ARM2THUMB_GLUE_SECTION_NAME);
+ osi.sec = bfd_get_linker_section (htab->bfd_of_glue_owner,
+ ARM2THUMB_GLUE_SECTION_NAME);
osi.sec_shndx = _bfd_elf_section_from_bfd_section
(output_bfd, osi.sec->output_section);
/* Thumb->ARM glue. */
if (htab->thumb_glue_size > 0)
{
- osi.sec = bfd_get_section_by_name (htab->bfd_of_glue_owner,
- THUMB2ARM_GLUE_SECTION_NAME);
+ osi.sec = bfd_get_linker_section (htab->bfd_of_glue_owner,
+ THUMB2ARM_GLUE_SECTION_NAME);
osi.sec_shndx = _bfd_elf_section_from_bfd_section
(output_bfd, osi.sec->output_section);
/* ARMv4 BX veneers. */
if (htab->bx_glue_size > 0)
{
- osi.sec = bfd_get_section_by_name (htab->bfd_of_glue_owner,
- ARM_BX_GLUE_SECTION_NAME);
+ osi.sec = bfd_get_linker_section (htab->bfd_of_glue_owner,
+ ARM_BX_GLUE_SECTION_NAME);
osi.sec_shndx = _bfd_elf_section_from_bfd_section
(output_bfd, osi.sec->output_section);