diff options
Diffstat (limited to 'bfd/elflink.h')
-rw-r--r-- | bfd/elflink.h | 95 |
1 files changed, 64 insertions, 31 deletions
diff --git a/bfd/elflink.h b/bfd/elflink.h index 7b32491d945..8acb7a93632 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -474,7 +474,7 @@ elf_link_add_object_symbols (abfd, info) .gnu.warning.SYMBOL are treated as warning symbols for the given symbol. This differs from .gnu.warning sections, which generate warnings when they are included in an output file. */ - if (! info->shared) + if (info->executable) { asection *s; @@ -1321,7 +1321,7 @@ elf_link_add_object_symbols (abfd, info) } else new_flag = ELF_LINK_HASH_DEF_REGULAR; - if (info->shared + if (! info->executable || (old_flags & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_DYNAMIC)) != 0) dynsym = TRUE; @@ -1937,6 +1937,43 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath, if (! is_elf_hash_table (info)) return TRUE; + if (info->execstack) + elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X; + else if (info->noexecstack) + elf_tdata (output_bfd)->stack_flags = PF_R | PF_W; + else + { + bfd *inputobj; + asection *notesec = NULL; + int exec = 0; + + for (inputobj = info->input_bfds; + inputobj; + inputobj = inputobj->link_next) + { + asection *s; + + if (inputobj->flags & DYNAMIC) + continue; + s = bfd_get_section_by_name (inputobj, ".note.GNU-stack"); + if (s) + { + if (s->flags & SEC_CODE) + exec = PF_X; + notesec = s; + } + else + exec = PF_X; + } + if (notesec) + { + elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | exec; + if (exec && info->relocateable + && notesec->output_section != bfd_abs_section_ptr) + notesec->output_section->flags |= SEC_CODE; + } + } + /* Any syms created from now on start with -1 in got.refcount/offset and plt.refcount/offset. */ elf_hash_table (info)->init_refcount = elf_hash_table (info)->init_offset; @@ -2174,7 +2211,7 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath, if (bfd_get_section_by_name (output_bfd, ".preinit_array") != NULL) { /* DT_PREINIT_ARRAY is not allowed in shared library. */ - if (info->shared) + if (! info->executable) { bfd *sub; asection *o; @@ -2440,7 +2477,7 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath, if (info->flags_1) { - if (! info->shared) + if (info->executable) info->flags_1 &= ~ (DF_1_INITFIRST | DF_1_NODELETE | DF_1_NOOPEN); @@ -4417,7 +4454,8 @@ elf_link_output_extsym (h, data) referenced by regular files, because we will already have issued warnings for them. */ if (! finfo->info->relocateable - && (! finfo->info->shared || ! finfo->info->allow_shlib_undefined) + && (finfo->info->executable + || ! finfo->info->allow_shlib_undefined) && h->root.type == bfd_link_hash_undefined && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0 && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0 @@ -5002,13 +5040,13 @@ elf_link_input_bfd (finfo, input_bfd) memset (rel, 0, sizeof (*rel)); } else - { - if (! ((*finfo->info->callbacks->undefined_symbol) - (finfo->info, h->root.root.string, - input_bfd, o, rel->r_offset, - TRUE))) - return FALSE; - } + finfo->info->callbacks->error_handler + (LD_DEFINITION_IN_DISCARDED_SECTION, + _("%T: discarded in section `%s' from %s\n"), + h->root.root.string, + h->root.root.string, + h->root.u.def.section->name, + bfd_archive_filename (h->root.u.def.section->owner)); } } else @@ -5027,26 +5065,21 @@ elf_link_input_bfd (finfo, input_bfd) } else { - bfd_boolean ok; - const char *msg - = _("local symbols in discarded section %s"); - bfd_size_type amt - = strlen (sec->name) + strlen (msg) - 1; - char *buf = (char *) bfd_malloc (amt); - - if (buf != NULL) - sprintf (buf, msg, sec->name); - else - buf = (char *) sec->name; - ok = (*finfo->info->callbacks - ->undefined_symbol) (finfo->info, buf, - input_bfd, o, - rel->r_offset, - TRUE); - if (buf != sec->name) + static int count; + int ok; + char *buf; + + ok = asprintf (&buf, "local symbol %d", + count++); + if (ok <= 0) + buf = (char *) "local symbol"; + finfo->info->callbacks->error_handler + (LD_DEFINITION_IN_DISCARDED_SECTION, + _("%T: discarded in section `%s' from %s\n"), + buf, buf, sec->name, + bfd_archive_filename (input_bfd)); + if (ok != -1) free (buf); - if (!ok) - return FALSE; } } } |