/* ARC-specific support for 32-bit ELF
- Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ Copyright (C) 1994-2018 Free Software Foundation, Inc.
Contributed by Cupertino Miranda (cmiranda@synopsys.com).
This file is part of BFD, the Binary File Descriptor library.
if (_htab->dynamic_sections_created == TRUE) \
{ \
BFD_ASSERT (_htab->srel##SECTION &&_htab->srel##SECTION->contents); \
- _loc = _htab->srel##SECTION->contents \
- + ((_htab->srel##SECTION->reloc_count) \
- * sizeof (Elf32_External_Rela)); \
- _htab->srel##SECTION->reloc_count++; \
- _rel.r_addend = ADDEND; \
- _rel.r_offset = (_htab->s##SECTION)->output_section->vma \
- + (_htab->s##SECTION)->output_offset + OFFSET; \
- BFD_ASSERT ((long) SYM_IDX != -1); \
- _rel.r_info = ELF32_R_INFO (SYM_IDX, TYPE); \
- bfd_elf32_swap_reloca_out (BFD, &_rel, _loc); \
+ _loc = _htab->srel##SECTION->contents \
+ + ((_htab->srel##SECTION->reloc_count) \
+ * sizeof (Elf32_External_Rela)); \
+ _htab->srel##SECTION->reloc_count++; \
+ _rel.r_addend = ADDEND; \
+ _rel.r_offset = (_htab->s##SECTION)->output_section->vma \
+ + (_htab->s##SECTION)->output_offset + OFFSET; \
+ BFD_ASSERT ((long) SYM_IDX != -1); \
+ _rel.r_info = ELF32_R_INFO (SYM_IDX, TYPE); \
+ bfd_elf32_swap_reloca_out (BFD, &_rel, _loc); \
} \
}
break;
}
}
+
#undef ARC_RELOC_HOWTO
/* Try to minimize the amount of space occupied by relocation tables
};
/* Should be included at this location due to static declarations
- * defined before this point. */
+ defined before this point. */
#include "arc-got.h"
#define arc_bfd_get_8(A,B,C) bfd_get_8(A,B)
#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
TYPE = VALUE,
+
enum howto_list
{
#include "elf/arc-reloc.def"
HOWTO_LIST_LAST
};
+
#undef ARC_RELOC_HOWTO
#define ARC_RELOC_HOWTO(TYPE, VALUE, RSIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
};
#undef ARC_RELOC_HOWTO
-static void arc_elf_howto_init (void)
+static void
+arc_elf_howto_init (void)
{
#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
- elf_arc_howto_table[TYPE].pc_relative = \
+ elf_arc_howto_table[TYPE].pc_relative = \
(strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL); \
- elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0); \
- /* Only 32 bit data relocations should be marked as ME. */ \
- if (strstr (#FORMULA, " ME ") != NULL) \
- { \
- BFD_ASSERT (SIZE == 2); \
+ elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0); \
+ /* Only 32 bit data relocations should be marked as ME. */ \
+ if (strstr (#FORMULA, " ME ") != NULL) \
+ { \
+ BFD_ASSERT (SIZE == 2); \
}
#include "elf/arc-reloc.def"
#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
[TYPE] = VALUE,
+
const int howto_table_lookup[] =
{
#include "elf/arc-reloc.def"
};
+
#undef ARC_RELOC_HOWTO
static reloc_howto_type *
#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
{ BFD_RELOC_##TYPE, R_##TYPE },
+
static const struct arc_reloc_map arc_reloc_map[] =
{
#include "elf/arc-reloc.def"
{BFD_RELOC_24, R_ARC_24},
{BFD_RELOC_32, R_ARC_32},
};
+
#undef ARC_RELOC_HOWTO
typedef ATTRIBUTE_UNUSED bfd_vma (*replace_func) (unsigned, int ATTRIBUTE_UNUSED);
case TYPE: \
func = (void *) RELOC_FUNCTION; \
break;
+
static replace_func
get_replace_function (bfd *abfd, unsigned int r_type)
{
}
if (func == replace_bits24 && bfd_big_endian (abfd))
- return (replace_func) replace_bits24_be;
+ func = replace_bits24_be;
return (replace_func) func;
}
/* Set the howto pointer for an ARC ELF reloc. */
-static void
-arc_info_to_howto_rel (bfd * abfd ATTRIBUTE_UNUSED,
+static bfd_boolean
+arc_info_to_howto_rel (bfd * abfd,
arelent * cache_ptr,
Elf_Internal_Rela * dst)
{
unsigned int r_type;
r_type = ELF32_R_TYPE (dst->r_info);
- BFD_ASSERT (r_type < (unsigned int) R_ARC_max);
+ if (r_type >= (unsigned int) R_ARC_max)
+ {
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+ abfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
cache_ptr->howto = arc_elf_howto (r_type);
+ return TRUE;
}
/* Extract CPU features from an NTBS. */
/* It's sometimes ok to mix different configs, so this is only
a warning. */
_bfd_error_handler
- (_("Warning: %B: Conflicting platform configuration "
- "%s with %s.\n"), ibfd,
+ (_("warning: %pB: conflicting platform configuration "
+ "%s with %s"), ibfd,
tagval[in_attr[i].i],
tagval[out_attr[i].i]);
}
BFD_ASSERT (out_attr[i].i < 5);
/* We cannot mix code for different CPUs. */
_bfd_error_handler
- (_("error: %B: unable to merge CPU base attributes "
- "%s with %s.\n"),
+ (_("error: %pB: unable to merge CPU base attributes "
+ "%s with %s"),
obfd,
tagval[in_attr[i].i],
tagval[out_attr[i].i]);
&& (!(cpu_out & bfd_feature_list[j].cpus)))
{
_bfd_error_handler
- (_("error: %B: unable to merge ISA extension attributes "
- "%s.\n"),
+ (_("error: %pB: unable to merge ISA extension attributes "
+ "%s"),
obfd, bfd_feature_list[j].name);
result = FALSE;
break;
p2 = (char *) bfd_feature_list[k].name;
}
_bfd_error_handler
- (_("error: %B: conflicting ISA extension attributes "
- "%s with %s.\n"),
+ (_("error: %pB: conflicting ISA extension attributes "
+ "%s with %s"),
obfd, p1, p2);
result = FALSE;
break;
{
/* We cannot mix code with rf16 and without. */
_bfd_error_handler
- (_("error: %B: cannot mix rf16 with full register set %B.\n"),
+ (_("error: %pB: cannot mix rf16 with full register set %pB"),
obfd, ibfd);
result = FALSE;
}
&& out_attr[i].i != in_attr[i].i)
{
_bfd_error_handler
- (_("error: %B: conflicting attributes %s: %s with %s.\n"),
+ (_("error: %pB: conflicting attributes %s: %s with %s"),
obfd, tagname,
tagval[in_attr[i].i],
tagval[out_attr[i].i]);
&& out_attr[i].i != in_attr[i].i)
{
_bfd_error_handler
- (_("error: %B: conflicting attributes %s.\n"),
+ (_("error: %pB: conflicting attributes %s"),
obfd, tagname);
result = FALSE;
}
if (mach_ibfd != mach_obfd)
{
/* xgettext:c-format */
- _bfd_error_handler (_("ERROR: Attempting to link %B "
- "with a binary %B of different architecture"),
+ _bfd_error_handler (_("error: attempting to link %pB "
+ "with a binary %pB of different architecture"),
ibfd, obfd);
return FALSE;
}
/* Warn if different flags. */
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: uses different e_flags (0x%lx) fields than "
- "previous modules (0x%lx)"),
- ibfd, (long) in_flags, (long) out_flags);
+ (_("%pB: uses different e_flags (%#x) fields than "
+ "previous modules (%#x)"),
+ ibfd, in_flags, out_flags);
if (in_flags && out_flags)
return FALSE;
/* MWDT doesnt set the eflags hence make sure we choose the
if (e_machine == EM_ARC)
{
_bfd_error_handler
- (_("Error: The ARC4 architecture is no longer supported.\n"));
+ (_("error: the ARC4 architecture is no longer supported"));
return FALSE;
}
else
{
_bfd_error_handler
- (_("Warning: unset or old architecture flags. \n"
- " Use default machine.\n"));
+ (_("warning: unset or old architecture flags; "
+ "use default machine"));
}
}
if (reloc_data.reloc_addend == 0)
_bfd_error_handler
/* xgettext:c-format */
- (_("%B(%A+0x%lx): CMEM relocation to `%s' is invalid, "
- "16 MSB should be 0x%04x (value is 0x%lx)"),
+ (_("%pB(%pA+%#" PRIx64 "): CMEM relocation to `%s' is invalid, "
+ "16 MSB should be %#x (value is %#" PRIx64 ")"),
reloc_data.input_section->owner,
reloc_data.input_section,
- reloc_data.reloc_offset,
+ (uint64_t) reloc_data.reloc_offset,
reloc_data.symbol_name,
NPS_CMEM_HIGH_VALUE,
- (relocation));
+ (uint64_t) relocation);
else
_bfd_error_handler
/* xgettext:c-format */
- (_("%B(%A+0x%lx): CMEM relocation to `%s+0x%lx' is invalid, "
- "16 MSB should be 0x%04x (value is 0x%lx)"),
+ (_("%pB(%pA+%#" PRIx64 "): CMEM relocation to `%s+%#" PRIx64
+ "' is invalid, 16 MSB should be %#x (value is %#" PRIx64 ")"),
reloc_data.input_section->owner,
reloc_data.input_section,
- reloc_data.reloc_offset,
+ (uint64_t) reloc_data.reloc_offset,
reloc_data.symbol_name,
- reloc_data.reloc_addend,
+ (uint64_t) reloc_data.reloc_addend,
NPS_CMEM_HIGH_VALUE,
- (relocation));
+ (uint64_t) relocation);
return bfd_reloc_overflow;
}
break;
+ (reloc_data.reloc_offset))))
#define SECTSTART (bfd_signed_vma) (reloc_data.sym_section->output_section->vma \
+ reloc_data.sym_section->output_offset)
-
+#define JLI (bfd_signed_vma) (reloc_data.sym_section->output_section->vma)
#define _SDA_BASE_ (bfd_signed_vma) (reloc_data.sdata_begin_symbol_vma)
#define TLS_REL (bfd_signed_vma) \
((elf_hash_table (info))->tls_sec->output_section->vma)
#define TLS_TBSS (8)
-#define TCB_SIZE (8)
#define none (0)
#else
#define PRINT_DEBUG_RELOC_INFO_BEFORE(...)
-#define PRINT_DEBUG_RELOC_INFO_AFTER
+#define PRINT_DEBUG_RELOC_INFO_AFTER
#endif /* ARC_ENABLE_DEBUG */
#undef P
#undef SECTSTAR
#undef SECTSTART
+#undef JLI
#undef _SDA_BASE_
#undef none
corresponding to the st_shndx field of each
local symbol. */
static bfd_boolean
-elf_arc_relocate_section (bfd * output_bfd,
+elf_arc_relocate_section (bfd * output_bfd,
struct bfd_link_info * info,
- bfd * input_bfd,
- asection * input_section,
- bfd_byte * contents,
+ bfd * input_bfd,
+ asection * input_section,
+ bfd_byte * contents,
Elf_Internal_Rela * relocs,
Elf_Internal_Sym * local_syms,
- asection ** local_sections)
+ asection ** local_sections)
{
- Elf_Internal_Shdr * symtab_hdr;
+ Elf_Internal_Shdr * symtab_hdr;
struct elf_link_hash_entry ** sym_hashes;
- Elf_Internal_Rela * rel;
- Elf_Internal_Rela * wrel;
- Elf_Internal_Rela * relend;
+ Elf_Internal_Rela * rel;
+ Elf_Internal_Rela * wrel;
+ Elf_Internal_Rela * relend;
struct elf_link_hash_table * htab = elf_hash_table (info);
symtab_hdr = &((elf_tdata (input_bfd))->symtab_hdr);
relend = relocs + input_section->reloc_count;
for (; rel < relend; wrel++, rel++)
{
- enum elf_arc_reloc_type r_type;
+ enum elf_arc_reloc_type r_type;
reloc_howto_type * howto;
unsigned long r_symndx;
struct elf_link_hash_entry * h;
Elf_Internal_Sym * sym;
asection * sec;
struct elf_link_hash_entry * h2;
- const char * msg;
+ const char * msg;
+ bfd_boolean unresolved_reloc = FALSE;
struct arc_relocation_data reloc_data =
{
.reloc_offset = 0,
.reloc_addend = 0,
.got_offset_value = 0,
- .sym_value = 0,
+ .sym_value = 0,
.sym_section = NULL,
.howto = NULL,
.input_section = NULL,
}
else
{
+ bfd_boolean warned, ignored;
+ bfd_vma relocation ATTRIBUTE_UNUSED;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
/* TODO: This code is repeated from below. We should
clean it and remove duplications.
Sec is used check for discarded sections.
{
_bfd_clear_contents (howto, input_bfd, input_section,
contents + rel->r_offset);
- rel->r_offset = rel->r_offset;
rel->r_info = 0;
rel->r_addend = 0;
{
create_got_dynrelocs_for_single_entry (
got_entry_for_type (list,
- arc_got_entry_type_for_reloc (howto)),
+ arc_got_entry_type_for_reloc (howto)),
output_bfd, info, NULL);
}
}
&& !reloc_data.sdata_begin_symbol_vma_set)
{
_bfd_error_handler
- ("Error: Linker symbol __SDATA_BEGIN__ not found");
+ ("error: linker symbol __SDATA_BEGIN__ not found");
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
&& reloc_data.sym_section == NULL)
{
_bfd_error_handler
- (_("GOT and PLT relocations cannot be fixed with a non dynamic linker."));
+ (_("GOT and PLT relocations cannot be fixed with a non dynamic linker"));
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
case bfd_reloc_other:
/* xgettext:c-format */
- msg = _("%B(%A): warning: unaligned access to symbol '%s' in the small data area");
+ msg = _("%pB(%pA): warning: unaligned access to symbol '%s' in the small data area");
break;
case bfd_reloc_outofrange:
/* xgettext:c-format */
- msg = _("%B(%A): internal error: out of range error");
+ msg = _("%pB(%pA): internal error: out of range error");
break;
case bfd_reloc_notsupported:
/* xgettext:c-format */
- msg = _("%B(%A): internal error: unsupported relocation error");
+ msg = _("%pB(%pA): internal error: unsupported relocation error");
break;
case bfd_reloc_dangerous:
/* xgettext:c-format */
- msg = _("%B(%A): internal error: dangerous relocation");
+ msg = _("%pB(%pA): internal error: dangerous relocation");
break;
default:
/* xgettext:c-format */
- msg = _("%B(%A): internal error: unknown error");
+ msg = _("%pB(%pA): internal error: unknown error");
break;
}
const Elf_Internal_Rela * rel_end;
bfd * dynobj;
asection * sreloc = NULL;
+ struct elf_link_hash_table * htab = elf_hash_table (info);
if (bfd_link_relocatable (info))
return TRUE;
+ if (htab->dynobj == NULL)
+ htab->dynobj = abfd;
+
dynobj = (elf_hash_table (info))->dynobj;
symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
sym_hashes = elf_sym_hashes (abfd);
}
howto = arc_elf_howto (r_type);
- if (dynobj == NULL
- && (is_reloc_for_GOT (howto)
- || is_reloc_for_TLS (howto)))
- {
- dynobj = elf_hash_table (info)->dynobj = abfd;
- if (! _bfd_elf_create_got_section (abfd, info))
- return FALSE;
- }
-
/* Load symbol information. */
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol. */
name = "UNKNOWN";
_bfd_error_handler
/* xgettext:c-format */
- (_("\
-%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
- abfd,
- arc_elf_howto (r_type)->name,
- name);
+ (_("%pB: relocation %s against `%s' can not be used"
+ " when making a shared object; recompile with -fPIC"),
+ abfd,
+ arc_elf_howto (r_type)->name,
+ name);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
{
if (sreloc == NULL)
{
+ if (info->dynamic
+ && ! htab->dynamic_sections_created
+ && ! _bfd_elf_link_create_dynamic_sections (abfd, info))
+ return FALSE;
sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
2, abfd,
/*rela*/
if (is_reloc_for_GOT (howto)
|| is_reloc_for_TLS (howto))
{
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
+
arc_fill_got_info_for_reloc (
arc_got_entry_type_for_reloc (howto),
get_got_entry_list_for_symbol (abfd, r_symndx, h),
/* If this is a weak symbol, and there is a real definition, the
processor independent code will have arranged for us to see the
real definition first, and we can just use the same value. */
- if (h->u.weakdef != NULL)
+ if (h->is_weakalias)
{
- BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
- || h->u.weakdef->root.type == bfd_link_hash_defweak);
- h->root.u.def.section = h->u.weakdef->root.u.def.section;
- h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ struct elf_link_hash_entry *def = weakdef (h);
+ BFD_ASSERT (def->root.type == bfd_link_hash_defined);
+ h->root.u.def.section = def->root.u.def.section;
+ h->root.u.def.value = def->root.u.def.value;
return TRUE;
}
const char *name = s->name + 5;
bfd *ibfd;
for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next)
- if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour)
+ if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
+ && ibfd->flags & DYNAMIC)
{
asection *target = bfd_get_section_by_name (ibfd, name);
if (target != NULL
if ((tag & 127) < (Tag_ARC_ISA_mpy_option + 1))
{
_bfd_error_handler
- (_("%B: Unknown mandatory ARC object attribute %d."),
+ (_("%pB: unknown mandatory ARC object attribute %d"),
abfd, tag);
bfd_set_error (bfd_error_bad_value);
return FALSE;
else
{
_bfd_error_handler
- (_("Warning: %B: Unknown ARC object attribute %d."),
+ (_("warning: %pB: unknown ARC object attribute %d"),
abfd, tag);
return TRUE;
}
#define elf_backend_obj_attrs_arg_type elf32_arc_obj_attrs_arg_type
#undef elf_backend_obj_attrs_section_type
#define elf_backend_obj_attrs_section_type SHT_ARC_ATTRIBUTES
-#define elf_backend_obj_attrs_handle_unknown elf32_arc_obj_attrs_handle_unknown
+#define elf_backend_obj_attrs_handle_unknown elf32_arc_obj_attrs_handle_unknown
-#define elf_backend_section_from_shdr elf32_arc_section_from_shdr
+#define elf_backend_section_from_shdr elf32_arc_section_from_shdr
#include "elf32-target.h"