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. */
}
/* xgettext:c-format */
- _bfd_error_handler (_("%pB: invalid relocation type %d"), abfd, (int) code);
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, (int) code);
bfd_set_error (bfd_error_bad_value);
TRACE ("Unknown");
return NULL;
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;
}
+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));