return FALSE;
}
- if (! info->traditional_format)
- {
- s = bfd_make_section_with_flags (abfd, ".eh_frame_hdr",
- flags | SEC_READONLY);
- if (s == NULL
- || ! bfd_set_section_alignment (abfd, s, 2))
- return FALSE;
- elf_hash_table (info)->eh_info.hdr_sec = s;
- }
-
/* Create sections to hold version informations. These are removed
if they are not needed. */
s = bfd_make_section_with_flags (abfd, ".gnu.version_d",
sec = bfd_abs_section_ptr;
else if (sec->kept_section)
{
- /* Symbols from discarded section are undefined, and have
- default visibility. */
+ /* Symbols from discarded section are undefined. We keep
+ its visibility. */
sec = bfd_und_section_ptr;
isym->st_shndx = SHN_UNDEF;
- isym->st_other = (STV_DEFAULT
- | (isym->st_other & ~ ELF_ST_VISIBILITY (-1)));
}
else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
value -= sec->vma;
}
}
- /* Remember the symbol size and type. */
- if (isym->st_size != 0
+ /* Remember the symbol size if it isn't undefined. */
+ if ((isym->st_size != 0 && isym->st_shndx != SHN_UNDEF)
&& (definition || h->size == 0))
{
- if (h->size != 0 && h->size != isym->st_size && ! size_change_ok)
+ if (h->size != 0
+ && h->size != isym->st_size
+ && ! size_change_ok)
(*_bfd_error_handler)
(_("Warning: size of symbol `%s' changed"
" from %lu in %B to %lu in %B"),
unsigned int i;
/* Restore the symbol table. */
+ if (bed->as_needed_cleanup)
+ (*bed->as_needed_cleanup) (abfd, info);
old_hash = (char *) old_tab + tabsize;
old_ent = (char *) old_hash + hashsize;
sym_hash = elf_sym_hashes (abfd);
&& ! (*bed->elf_backend_always_size_sections) (output_bfd, info))
return FALSE;
+ if (! _bfd_elf_maybe_strip_eh_frame_hdr (info))
+ return FALSE;
+
dynobj = elf_hash_table (info)->dynobj;
/* If there were no dynamic objects in the link, there is nothing to
if (dynobj == NULL)
return TRUE;
- if (! _bfd_elf_maybe_strip_eh_frame_hdr (info))
- return FALSE;
-
if (elf_hash_table (info)->dynamic_sections_created)
{
struct elf_info_failed eif;
if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
continue;
- /* Keep .gcc_except_table.* if the associated .text.* is
+ /* Keep .gcc_except_table.* if the associated .text.* (or the
+ associated .gnu.linkonce.t.* if .text.* doesn't exist) is
marked. This isn't very nice, but the proper solution,
splitting .eh_frame up and using comdat doesn't pan out
easily due to needing special relocs to handle the
difference of two symbols in separate sections.
Don't keep code sections referenced by .eh_frame. */
#define TEXT_PREFIX ".text."
+#define TEXT_PREFIX2 ".gnu.linkonce.t."
#define GCC_EXCEPT_TABLE_PREFIX ".gcc_except_table."
for (o = sub->sections; o != NULL; o = o->next)
if (!o->gc_mark && o->gc_mark_from_eh && (o->flags & SEC_CODE) == 0)
char *fn_name;
const char *sec_name;
asection *fn_text;
- unsigned o_name_prefix_len = strlen (GCC_EXCEPT_TABLE_PREFIX);
- unsigned fn_name_prefix_len = strlen (TEXT_PREFIX);
+ unsigned o_name_prefix_len , fn_name_prefix_len, tmp;
+ o_name_prefix_len = strlen (GCC_EXCEPT_TABLE_PREFIX);
sec_name = o->name + o_name_prefix_len;
- fn_name = bfd_malloc (strlen (sec_name) + fn_name_prefix_len + 1);
+ fn_name_prefix_len = strlen (TEXT_PREFIX);
+ tmp = strlen (TEXT_PREFIX2);
+ if (tmp > fn_name_prefix_len)
+ fn_name_prefix_len = tmp;
+ fn_name
+ = bfd_malloc (fn_name_prefix_len + strlen (sec_name) + 1);
if (fn_name == NULL)
return FALSE;
+
+ /* Try the first prefix. */
sprintf (fn_name, "%s%s", TEXT_PREFIX, sec_name);
fn_text = bfd_get_section_by_name (sub, fn_name);
+
+ /* Try the second prefix. */
+ if (fn_text == NULL)
+ {
+ sprintf (fn_name, "%s%s", TEXT_PREFIX2, sec_name);
+ fn_text = bfd_get_section_by_name (sub, fn_name);
+ }
+
free (fn_name);
if (fn_text == NULL || !fn_text->gc_mark)
continue;