/* ELF linking support for BFD.
- Copyright (C) 1995-2022 Free Software Foundation, Inc.
+ Copyright (C) 1995-2023 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
return false;
/* Read the relocations. */
- if (bfd_bread (external_relocs, shdr->sh_size, abfd) != shdr->sh_size)
+ if (bfd_read (external_relocs, shdr->sh_size, abfd) != shdr->sh_size)
return false;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
abfd = abfd->plugin_dummy_bfd;
hdr = &elf_tdata (abfd)->symtab_hdr;
}
- else if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0)
- hdr = &elf_tdata (abfd)->symtab_hdr;
else
- hdr = &elf_tdata (abfd)->dynsymtab_hdr;
+ {
+ if (elf_use_dt_symtab_p (abfd))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
+ if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0)
+ hdr = &elf_tdata (abfd)->symtab_hdr;
+ else
+ hdr = &elf_tdata (abfd)->dynsymtab_hdr;
+ }
symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
htab = elf_hash_table (info);
bed = get_elf_backend_data (abfd);
+ if (elf_use_dt_symtab_p (abfd))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
if ((abfd->flags & DYNAMIC) == 0)
dynamic = false;
else
| DYN_NO_NEEDED)) == 0;
s = bfd_get_section_by_name (abfd, ".dynamic");
- if (s != NULL && s->size != 0)
+ if (s != NULL && s->size != 0 && (s->flags & SEC_HAS_CONTENTS) != 0)
{
bfd_byte *dynbuf;
bfd_byte *extdyn;
else
_bfd_error_handler
/* xgettext:c-format */
- (_("warning: alignment %u of symbol `%s' in %pB"
- " is smaller than %u in %pB"),
+ (_("warning: alignment %u of normal symbol `%s' in %pB"
+ " is smaller than %u used by the common definition in %pB"),
1 << normal_align, name, normal_bfd,
1 << common_align, common_bfd);
+
+ /* PR 30499: make sure that users understand that this warning is serious. */
+ _bfd_error_handler
+ (_("warning: NOTE: alignment discrepancies can cause real problems. Investigation is advised."));
}
}
if (h->size != 0
&& h->size != isym->st_size
&& ! size_change_ok)
- _bfd_error_handler
- /* xgettext:c-format */
- (_("warning: size of symbol `%s' changed"
- " from %" PRIu64 " in %pB to %" PRIu64 " in %pB"),
- name, (uint64_t) h->size, old_bfd,
- (uint64_t) isym->st_size, abfd);
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("warning: size of symbol `%s' changed"
+ " from %" PRIu64 " in %pB to %" PRIu64 " in %pB"),
+ name, (uint64_t) h->size, old_bfd,
+ (uint64_t) isym->st_size, abfd);
+
+ /* PR 30499: make sure that users understand that this warning is serious. */
+ _bfd_error_handler
+ (_("warning: NOTE: size discrepancies can cause real problems. Investigation is advised."));
+ }
h->size = isym->st_size;
}
h->unique_global = (flags & BSF_GNU_UNIQUE) != 0;
}
- if (definition && !dynamic)
+ /* Don't add indirect symbols for .symver x, x@FOO aliases
+ in IR. Since all data or text symbols in IR have the
+ same type, value and section, we can't tell if a symbol
+ is an alias of another symbol by their types, values and
+ sections. */
+ if (definition
+ && !dynamic
+ && (abfd->flags & BFD_PLUGIN) == 0)
{
char *p = strchr (name, ELF_VER_CHR);
if (p != NULL && p[1] != ELF_VER_CHR)
/* If the user has explicitly requested warnings, then generate one even
though the choice is the result of another command line option. */
if (info->warn_execstack == 1)
- _bfd_error_handler
- (_("\
+ {
+ if (info->error_execstack)
+ {
+ _bfd_error_handler
+ (_("\
+error: creating an executable stack because of -z execstack command line option"));
+ return false;
+ }
+
+ _bfd_error_handler
+ (_("\
warning: enabling an executable stack because of -z execstack command line option"));
+ }
+
elf_stack_flags (output_bfd) = PF_R | PF_W | PF_X;
}
else if (info->noexecstack)
being enabled despite the fact that it was not requested
on the command line. */
if (noteobj)
- _bfd_error_handler (_("\
+ {
+ if (info->error_execstack)
+ {
+ _bfd_error_handler (_("\
+error: %s: is triggering the generation of an executable stack (because it has an executable .note.GNU-stack section)"),
+ bfd_get_filename (noteobj));
+ return false;
+ }
+
+ _bfd_error_handler (_("\
warning: %s: requires executable stack (because the .note.GNU-stack section is executable)"),
bfd_get_filename (noteobj));
+ }
else if (emptyobj)
{
+ if (info->error_execstack)
+ {
+ _bfd_error_handler (_("\
+error: %s: is triggering the generation of an executable stack because it does not have a .note.GNU-stack section"),
+ bfd_get_filename (emptyobj));
+ return false;
+ }
+
_bfd_error_handler (_("\
warning: %s: missing .note.GNU-stack section implies executable stack"),
bfd_get_filename (emptyobj));
return true;
s = bfd_get_section_by_name (abfd, ".dynamic");
- if (s == NULL || s->size == 0)
+ if (s == NULL || s->size == 0 || (s->flags & SEC_HAS_CONTENTS) == 0)
return true;
if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
if (ELF_ST_BIND (elfsym->st_info) == STB_GNU_UNIQUE)
elf_tdata (flinfo->output_bfd)->has_gnu_osabi |= elf_gnu_osabi_unique;
- if (name == NULL
- || *name == '\0'
- || (!bfd_link_relocatable (flinfo->info)
- && (input_sec->flags & SEC_EXCLUDE)))
+ if (name == NULL || *name == '\0')
elfsym->st_name = (unsigned long) -1;
else
{
pos = hdr->sh_offset + hdr->sh_size;
amt = bed->s->sizeof_sym * flinfo->output_bfd->symcount;
if (bfd_seek (flinfo->output_bfd, pos, SEEK_SET) == 0
- && bfd_bwrite (symbuf, amt, flinfo->output_bfd) == amt)
+ && bfd_write (symbuf, amt, flinfo->output_bfd) == amt)
{
hdr->sh_size += amt;
ret = true;
/* If this symbol is defined in a section which we are
discarding, we don't need to keep it. */
- if (isym->st_shndx != SHN_UNDEF
- && isym->st_shndx < SHN_LORESERVE
- && isec->output_section == NULL
- && flinfo->info->non_contiguous_regions
- && flinfo->info->non_contiguous_regions_warnings)
- {
- _bfd_error_handler (_("warning: --enable-non-contiguous-regions "
- "discards section `%s' from '%s'\n"),
- isec->name, bfd_get_filename (isec->owner));
- continue;
- }
-
- if (isym->st_shndx != SHN_UNDEF
- && isym->st_shndx < SHN_LORESERVE
- && bfd_section_removed_from_list (output_bfd,
- isec->output_section))
+ if (isym->st_shndx < SHN_LORESERVE
+ && (isec->output_section == NULL
+ || bfd_section_removed_from_list (output_bfd,
+ isec->output_section)))
continue;
/* Get the name of the symbol. */
contents = flinfo->contents;
}
}
+ else if (!(o->flags & SEC_RELOC)
+ && !bed->elf_backend_write_section
+ && o->sec_info_type == SEC_INFO_TYPE_MERGE)
+ /* A MERGE section that has no relocations doesn't need the
+ contents anymore, they have been recorded earlier. Except
+ if the backend has special provisions for writing sections. */
+ contents = NULL;
else
{
contents = flinfo->contents;
later. Use bfd_malloc since it will be freed by
bfd_compress_section_contents. */
unsigned char *contents = esdo->this_hdr.contents;
- if ((o->flags & SEC_ELF_COMPRESS) == 0 || contents != NULL)
+ if (contents != NULL)
abort ();
contents
= (unsigned char *) bfd_malloc (esdo->this_hdr.sh_size);
off, true);
if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0
- || (bfd_bwrite (flinfo.symshndxbuf, amt, abfd) != amt))
+ || (bfd_write (flinfo.symshndxbuf, amt, abfd) != amt))
{
ret = false;
goto return_local_hash_table;
/* Return the local debug definition section. */
asection *isec = bfd_section_from_elf_index (sec->owner,
sym->st_shndx);
- if ((isec->flags & SEC_DEBUGGING) != 0)
+ if (isec != NULL && (isec->flags & SEC_DEBUGGING) != 0)
return isec;
}