/* Xtensa-specific support for 32-bit ELF.
- Copyright (C) 2003-2017 Free Software Foundation, Inc.
+ Copyright (C) 2003-2018 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
int elf32xtensa_no_literal_movement = 1;
+/* Place property records for a section into individual property section
+ with xt.prop. prefix. */
+
+bfd_boolean elf32xtensa_separate_props = FALSE;
+
/* Rename one of the generic section flags to better document how it
is used here. */
/* Whether relocations have been processed. */
break;
}
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, (int) code);
+ bfd_set_error (bfd_error_bad_value);
TRACE ("Unknown");
return NULL;
}
/* Given an ELF "rela" relocation, find the corresponding howto and record
it in the BFD internal arelent representation of the relocation. */
-static void
-elf_xtensa_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+static bfd_boolean
+elf_xtensa_info_to_howto_rela (bfd *abfd,
arelent *cache_ptr,
Elf_Internal_Rela *dst)
{
if (r_type >= (unsigned int) R_XTENSA_max)
{
/* xgettext:c-format */
- _bfd_error_handler (_("%B: invalid XTENSA reloc number: %d"), abfd, r_type);
- r_type = 0;
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+ abfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
}
cache_ptr->howto = &elf_howto_table[r_type];
+ return TRUE;
}
\f
blocks[blk - 1].size != 0)
{
/* xgettext:c-format */
- _bfd_error_handler (_("%B(%A): invalid property table"),
+ _bfd_error_handler (_("%pB(%pA): invalid property table"),
abfd, section);
bfd_set_error (bfd_error_bad_value);
free (blocks);
if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
{
/* xgettext:c-format */
- _bfd_error_handler (_("%B: bad symbol index: %d"),
+ _bfd_error_handler (_("%pB: bad symbol index: %d"),
abfd, r_symndx);
return FALSE;
}
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: `%s' accessed both as normal and thread local symbol"),
+ (_("%pB: `%s' accessed both as normal and thread local symbol"),
abfd,
h ? h->root.root.string : "<local>");
return FALSE;
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%B(%A+%#Lx): relocation offset out of range (size=%#Lx)"),
- input_bfd, input_section, rel->r_offset, input_size);
+ (_("%pB(%pA+%#" PRIx64 "): "
+ "relocation offset out of range (size=%#" PRIx64 ")"),
+ input_bfd, input_section, (uint64_t) rel->r_offset,
+ (uint64_t) input_size);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
_bfd_error_handler
((sym_type == STT_TLS
/* xgettext:c-format */
- ? _("%B(%A+%#Lx): %s used with TLS symbol %s")
+ ? _("%pB(%pA+%#" PRIx64 "): %s used with TLS symbol %s")
/* xgettext:c-format */
- : _("%B(%A+%#Lx): %s used with non-TLS symbol %s")),
+ : _("%pB(%pA+%#" PRIx64 "): %s used with non-TLS symbol %s")),
input_bfd,
input_section,
- rel->r_offset,
+ (uint64_t) rel->r_offset,
howto->name,
name);
}
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%B(%A+%#Lx): unresolvable %s relocation against symbol `%s'"),
+ (_("%pB(%pA+%#" PRIx64 "): "
+ "unresolvable %s relocation against symbol `%s'"),
input_bfd,
input_section,
- rel->r_offset,
+ (uint64_t) rel->r_offset,
howto->name,
name);
return FALSE;
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: incompatible machine type. Output is 0x%x. Input is 0x%x"),
+ (_("%pB: incompatible machine type; output is 0x%x; input is 0x%x"),
ibfd, out_mach, in_mach);
bfd_set_error (bfd_error_wrong_format);
return FALSE;
if (content_length < address)
{
- *error_message = _("Attempt to convert L32R/CALLX to CALL failed");
+ *error_message = _("attempt to convert L32R/CALLX to CALL failed");
return bfd_reloc_other;
}
direct_call_opcode = swap_callx_for_call_opcode (opcode);
if (direct_call_opcode == XTENSA_UNDEFINED)
{
- *error_message = _("Attempt to convert L32R/CALLX to CALL failed");
+ *error_message = _("attempt to convert L32R/CALLX to CALL failed");
return bfd_reloc_other;
}
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%B(%A+%#Lx): could not decode instruction; "
+ (_("%pB(%pA+%#" PRIx64 "): could not decode instruction; "
"possible configuration mismatch"),
- ebb->sec->owner, ebb->sec, ebb->end_offset + insn_block_len);
+ ebb->sec->owner, ebb->sec,
+ (uint64_t) (ebb->end_offset + insn_block_len));
return FALSE;
}
ebb->end_offset += insn_block_len;
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%B(%A+%#Lx): could not decode instruction; "
+ (_("%pB(%pA+%#" PRIx64 "): could not decode instruction; "
"possible configuration mismatch"),
- ebb->sec->owner, ebb->sec, ebb->end_offset + insn_block_len);
+ ebb->sec->owner, ebb->sec,
+ (uint64_t) (ebb->end_offset + insn_block_len));
return FALSE;
}
ebb->start_offset -= insn_block_len;
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%B(%A+%#Lx): could not decode instruction for "
+ (_("%pB(%pA+%#" PRIx64 "): could not decode instruction for "
"XTENSA_ASM_SIMPLIFY relocation; "
"possible configuration mismatch"),
- sec->owner, sec, r_offset);
+ sec->owner, sec, (uint64_t) r_offset);
continue;
}
decode_error:
_bfd_error_handler
/* xgettext:c-format */
- (_("%B(%A+%#Lx): could not decode instruction; "
+ (_("%pB(%pA+%#" PRIx64 "): could not decode instruction; "
"possible configuration mismatch"),
- ebb->sec->owner, ebb->sec, offset);
+ ebb->sec->owner, ebb->sec, (uint64_t) offset);
return FALSE;
}
struct xlate_map_entry
{
- unsigned orig_address;
- unsigned new_address;
+ bfd_vma orig_address;
+ bfd_vma new_address;
unsigned size;
};
{
void *r;
xlate_map_entry_t *e;
+ struct xlate_map_entry se;
if (map == NULL)
return offset_with_removed_text (action_list, offset);
if (map->entry_count == 0)
return offset;
- r = bsearch (&offset, map->entry, map->entry_count,
+ se.orig_address = offset;
+ r = bsearch (&se, map->entry, map->entry_count,
sizeof (xlate_map_entry_t), &xlate_compare);
e = (xlate_map_entry_t *) r;
+ /* There could be a jump past the end of the section,
+ allow it using the last xlate map entry to translate its address. */
+ if (e == NULL)
+ {
+ e = map->entry + map->entry_count - 1;
+ if (xlate_compare (&se, e) <= 0)
+ e = NULL;
+ }
BFD_ASSERT (e != NULL);
if (e == NULL)
return offset;
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%B(%A+%#Lx): unexpected fix for %s relocation"),
- input_bfd, input_section, rel->r_offset,
+ (_("%pB(%pA+%#" PRIx64 "): unexpected fix for %s relocation"),
+ input_bfd, input_section, (uint64_t) rel->r_offset,
elf_howto_table[r_type].name);
return FALSE;
}
}
+static char *
+xtensa_add_names (const char *base, const char *suffix)
+{
+ if (suffix)
+ {
+ size_t base_len = strlen (base);
+ size_t suffix_len = strlen (suffix);
+ char *str = bfd_malloc (base_len + suffix_len + 1);
+
+ memcpy (str, base, base_len);
+ memcpy (str + base_len, suffix, suffix_len + 1);
+ return str;
+ }
+ else
+ {
+ return strdup (base);
+ }
+}
+
static int linkonce_len = sizeof (".gnu.linkonce.") - 1;
static char *
-xtensa_property_section_name (asection *sec, const char *base_name)
+xtensa_property_section_name (asection *sec, const char *base_name,
+ bfd_boolean separate_sections)
{
const char *suffix, *group_name;
char *prop_sec_name;
suffix = strrchr (sec->name, '.');
if (suffix == sec->name)
suffix = 0;
- prop_sec_name = (char *) bfd_malloc (strlen (base_name) + 1
- + (suffix ? strlen (suffix) : 0));
- strcpy (prop_sec_name, base_name);
- if (suffix)
- strcat (prop_sec_name, suffix);
+ prop_sec_name = xtensa_add_names (base_name, suffix);
}
else if (strncmp (sec->name, ".gnu.linkonce.", linkonce_len) == 0)
{
strcat (prop_sec_name + linkonce_len, suffix);
}
else
- prop_sec_name = strdup (base_name);
+ {
+ prop_sec_name = xtensa_add_names (base_name,
+ separate_sections ? sec->name : NULL);
+ }
return prop_sec_name;
}
static asection *
-xtensa_get_property_section (asection *sec, const char *base_name)
+xtensa_get_separate_property_section (asection *sec, const char *base_name,
+ bfd_boolean separate_section)
{
char *prop_sec_name;
asection *prop_sec;
- prop_sec_name = xtensa_property_section_name (sec, base_name);
+ prop_sec_name = xtensa_property_section_name (sec, base_name,
+ separate_section);
prop_sec = bfd_get_section_by_name_if (sec->owner, prop_sec_name,
match_section_group,
(void *) elf_group_name (sec));
return prop_sec;
}
+static asection *
+xtensa_get_property_section (asection *sec, const char *base_name)
+{
+ asection *prop_sec;
+
+ /* Try individual property section first. */
+ prop_sec = xtensa_get_separate_property_section (sec, base_name, TRUE);
+
+ /* Refer to a common property section if individual is not present. */
+ if (!prop_sec)
+ prop_sec = xtensa_get_separate_property_section (sec, base_name, FALSE);
+
+ return prop_sec;
+}
+
asection *
xtensa_make_property_section (asection *sec, const char *base_name)
asection *prop_sec;
/* Check if the section already exists. */
- prop_sec_name = xtensa_property_section_name (sec, base_name);
+ prop_sec_name = xtensa_property_section_name (sec, base_name,
+ elf32xtensa_separate_props);
prop_sec = bfd_get_section_by_name_if (sec->owner, prop_sec_name,
match_section_group,
(void *) elf_group_name (sec));
#define elf_backend_relocate_section elf_xtensa_relocate_section
#define elf_backend_size_dynamic_sections elf_xtensa_size_dynamic_sections
#define elf_backend_always_size_sections elf_xtensa_always_size_sections
-#define elf_backend_omit_section_dynsym \
- ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_omit_section_dynsym _bfd_elf_omit_section_dynsym_all
#define elf_backend_special_sections elf_xtensa_special_sections
#define elf_backend_action_discarded elf_xtensa_action_discarded
#define elf_backend_copy_indirect_symbol elf_xtensa_copy_indirect_symbol