/* 32-bit ELF support for ARM
- Copyright (C) 1998-2018 Free Software Foundation, Inc.
+ Copyright (C) 1998-2019 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
#include <limits.h>
#include "bfd.h"
-#include "bfd_stdint.h"
#include "libiberty.h"
#include "libbfd.h"
#include "elf-bfd.h"
va_start (ap, note_type);
memset (data, 0, sizeof (data));
strncpy (data + 28, va_arg (ap, const char *), 16);
-#if GCC_VERSION == 8001
+#if GCC_VERSION == 8000 || GCC_VERSION == 8001
DIAGNOSTIC_PUSH;
- /* GCC 8.1 warns about 80 equals destination size with
+ /* GCC 8.0 and 8.1 warn about 80 equals destination size with
-Wstringop-truncation:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85643
*/
DIAGNOSTIC_IGNORE_STRINGOP_TRUNCATION;
#endif
strncpy (data + 44, va_arg (ap, const char *), 80);
-#if GCC_VERSION == 8001
+#if GCC_VERSION == 8000 || GCC_VERSION == 8001
DIAGNOSTIC_POP;
#endif
va_end (ap);
asection *section;
Elf_Internal_Sym *local_syms = NULL;
- if (!is_arm_elf (input_bfd))
+ if (!is_arm_elf (input_bfd)
+ || (elf_dyn_lib_class (input_bfd) & DYN_AS_NEEDED) != 0)
continue;
num_a8_relocs = 0;
arm_plt->got_offset = sgotplt->size - 8 * htab->num_tls_desc;
if (htab->fdpic_p)
/* Function descriptor takes 64 bits in GOT. */
- sgotplt->size += 8;
+ sgotplt->size += 8;
else
sgotplt->size += 4;
}
After the reserved .got.plt entries, all symbols appear in
the same order as in .plt. */
if (htab->fdpic_p)
- /* Function descriptor takes 8 bytes. */
- plt_index = (got_offset - got_header_size) / 8;
+ /* Function descriptor takes 8 bytes. */
+ plt_index = (got_offset - got_header_size) / 8;
else
- plt_index = (got_offset - got_header_size) / 4;
+ plt_index = (got_offset - got_header_size) / 4;
/* Calculate the address of the GOT entry. */
got_address = (sgot->output_section->vma
/* PR 21523: Use an absolute value. The user of this reloc will
have already selected an ADD or SUB insn appropriately. */
- value = labs (relocation);
+ value = llabs (relocation);
if (value >= 0x1000)
return bfd_reloc_overflow;
&& (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak))
outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
- else if (globals->fdpic_p)
- isrofixup = 1;
else
- outrel.r_info = 0;
+ {
+ outrel.r_info = 0;
+ if (globals->fdpic_p)
+ isrofixup = 1;
+ }
outrel.r_addend = dynreloc_value;
}
/* The GOT entry is initialized to zero by default.
See if we should install a different value. */
if (outrel.r_addend != 0
- && (outrel.r_info == 0 || globals->use_rel || isrofixup))
+ && (globals->use_rel || outrel.r_info == 0))
{
bfd_put_32 (output_bfd, outrel.r_addend,
sgot->contents + off);
outrel.r_addend = 0;
}
- if (outrel.r_info != 0 && !isrofixup)
+ if (isrofixup)
+ arm_elf_add_rofixup (output_bfd,
+ elf32_arm_hash_table(info)->srofixup,
+ sgot->output_section->vma
+ + sgot->output_offset + off);
+
+ else if (outrel.r_info != 0)
{
outrel.r_offset = (sgot->output_section->vma
+ sgot->output_offset
+ off);
elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
}
- else if (isrofixup)
- {
- arm_elf_add_rofixup(output_bfd,
- elf32_arm_hash_table(info)->srofixup,
- sgot->output_section->vma
- + sgot->output_offset + off);
- }
+
h->got.offset |= 1;
}
value = sgot->output_offset + off;
off &= ~1;
else
{
- if (globals->use_rel)
- bfd_put_32 (output_bfd, dynreloc_value, sgot->contents + off);
+ Elf_Internal_Rela outrel;
+ int isrofixup = 0;
- if (bfd_link_pic (info) || dynreloc_st_type == STT_GNU_IFUNC)
+ if (dynreloc_st_type == STT_GNU_IFUNC)
+ outrel.r_info = ELF32_R_INFO (0, R_ARM_IRELATIVE);
+ else if (bfd_link_pic (info))
+ outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
+ else
{
- Elf_Internal_Rela outrel;
+ outrel.r_info = 0;
+ if (globals->fdpic_p)
+ isrofixup = 1;
+ }
+ /* The GOT entry is initialized to zero by default.
+ See if we should install a different value. */
+ if (globals->use_rel || outrel.r_info == 0)
+ bfd_put_32 (output_bfd, dynreloc_value, sgot->contents + off);
+
+ if (isrofixup)
+ arm_elf_add_rofixup (output_bfd,
+ globals->srofixup,
+ sgot->output_section->vma
+ + sgot->output_offset + off);
+
+ else if (outrel.r_info != 0)
+ {
outrel.r_addend = addend + dynreloc_value;
outrel.r_offset = (sgot->output_section->vma
+ sgot->output_offset
+ off);
- if (dynreloc_st_type == STT_GNU_IFUNC)
- outrel.r_info = ELF32_R_INFO (0, R_ARM_IRELATIVE);
- else
- outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
}
- else if (globals->fdpic_p)
- {
- /* For FDPIC executables, we use rofixup to fix
- address at runtime. */
- arm_elf_add_rofixup(output_bfd, globals->srofixup,
- sgot->output_section->vma + sgot->output_offset
- + off);
- }
local_got_offsets[r_symndx] |= 1;
}
case R_ARM_GOTOFFFUNCDESC:
{
- if (h == NULL)
+ if (h == NULL)
{
struct fdpic_local *local_fdpic_cnts = elf32_arm_local_fdpic_cnts(input_bfd);
int dynindx = elf_section_data (sym_sec->output_section)->dynindx;
case R_ARM_GOTFUNCDESC:
{
- if (h != NULL)
+ if (h != NULL)
{
Elf_Internal_Rela outrel;
outrel.r_addend = 0;
if (h->dynindx == -1 && !bfd_link_pic(info))
if (h->root.type == bfd_link_hash_undefweak)
- arm_elf_add_rofixup(output_bfd, globals->srofixup, -1);
+ arm_elf_add_rofixup(output_bfd, globals->srofixup, -1);
else
- arm_elf_add_rofixup(output_bfd, globals->srofixup, outrel.r_offset);
+ arm_elf_add_rofixup(output_bfd, globals->srofixup,
+ outrel.r_offset);
else
elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
eh->fdpic_cnts.gotfuncdesc_offset |= 1;
case R_ARM_FUNCDESC:
{
- if (h == NULL)
+ if (h == NULL)
{
struct fdpic_local *local_fdpic_cnts = elf32_arm_local_fdpic_cnts(input_bfd);
Elf_Internal_Rela outrel;
eh->fdpic_cnts.gotfuncdesc_offset = s->size;
s->size += 4;
if (h->dynindx == -1 && !bfd_link_pic(info))
- htab->srofixup->size += 4;
+ htab->srofixup->size += 4;
else
- elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+ elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
}
if (eh->fdpic_cnts.funcdesc_cnt > 0)
: ARM_MAP_ARM;
if (elf32_arm_plt_needs_thumb_stub_p (osi->info, arm_plt))
- if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr - 4))
- return FALSE;
+ if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr - 4))
+ return FALSE;
if (!elf32_arm_output_map_sym (osi, type, addr))
- return FALSE;
+ return FALSE;
if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 16))
- return FALSE;
+ return FALSE;
if (htab->plt_entry_size == 4 * ARRAY_SIZE(elf32_arm_fdpic_plt_entry))
- if (!elf32_arm_output_map_sym (osi, type, addr + 24))
- return FALSE;
+ if (!elf32_arm_output_map_sym (osi, type, addr + 24))
+ return FALSE;
}
else if (using_thumb_only (htab))
{
#define elf32_bed elf32_arm_fdpic_bed
#undef bfd_elf32_bfd_link_hash_table_create
-#define bfd_elf32_bfd_link_hash_table_create elf32_arm_fdpic_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create elf32_arm_fdpic_link_hash_table_create
#undef elf_backend_omit_section_dynsym
#define elf_backend_omit_section_dynsym elf32_arm_fdpic_omit_section_dynsym