/* ELF executable support for BFD.
- Copyright (C) 1993-2016 Free Software Foundation, Inc.
+ Copyright (C) 1993-2017 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
if (hdr->sh_type != SHT_STRTAB && hdr->sh_type < SHT_LOOS)
{
/* PR 17512: file: f057ec89. */
+ /* xgettext:c-format */
_bfd_error_handler (_("%B: attempt to load strings from a non-string section (number %d)"),
abfd, shindex);
return NULL;
{
unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx;
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: invalid string offset %u >= %lu for section `%s'"),
abfd, strindex, (unsigned long) hdr->sh_size,
(shindex == shstrndx && strindex == hdr->sh_name
if (!(*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym))
{
symoffset += (esym - (bfd_byte *) extsym_buf) / extsym_size;
+ /* xgettext:c-format */
_bfd_error_handler (_("%B symbol number %lu references "
"nonexistent SHT_SYMTAB_SHNDX section"),
ibfd, (unsigned long) symoffset);
if (shdr->contents == NULL)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: corrupt size field in group section header: 0x%lx"), abfd, shdr->sh_size);
bfd_set_error (bfd_error_bad_value);
-- num_group;
!= shdr->sh_size))
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: invalid size field in group section header: 0x%lx"), abfd, shdr->sh_size);
bfd_set_error (bfd_error_bad_value);
-- num_group;
if (elf_group_name (newsect) == NULL)
{
+ /* xgettext:c-format */
_bfd_error_handler (_("%B: no group info for section %A"),
abfd, newsect);
return FALSE;
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
if (bed->link_order_error_handler)
bed->link_order_error_handler
+ /* xgettext:c-format */
(_("%B: warning: sh_link not set for section `%A'"),
abfd, s);
}
if (linksec == NULL)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: sh_link [%d] in section `%A' is incorrect"),
s->owner, s, elfsec);
result = FALSE;
&& elf_next_in_group (s) == NULL)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: SHT_GROUP section [index %d] has no SHF_GROUP sections"),
abfd, elf_section_data (s)->this_idx);
result = FALSE;
if (shdr == NULL || shdr->bfd_section == NULL || shdr->contents == NULL)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: section group entry number %u is corrupt"),
abfd, i);
result = FALSE;
{
/* There are some unknown sections in the group. */
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: unknown [%d] section `%s' in group [%s]"),
abfd,
(unsigned int) idx->shdr->sh_type,
if (!bfd_malloc_and_get_section (abfd, newsect, &contents))
return FALSE;
- elf_parse_notes (abfd, (char *) contents, hdr->sh_size, -1);
+ elf_parse_notes (abfd, (char *) contents, hdr->sh_size, hdr->sh_offset);
free (contents);
}
if (!bfd_init_section_compress_status (abfd, newsect))
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: unable to initialize compress status for section %s"),
abfd, name);
return FALSE;
if (!bfd_init_section_decompress_status (abfd, newsect))
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: unable to initialize decompress status for section %s"),
abfd, name);
return FALSE;
Elf_Internal_Shdr ** oheaders = elf_elfsections (obfd);
unsigned int i;
- if (section_match (oheaders[hint], iheader))
+ BFD_ASSERT (iheader != NULL);
+
+ /* See PR 20922 for a reproducer of the NULL test. */
+ if (oheaders[hint] != NULL
+ && section_match (oheaders[hint], iheader))
return hint;
for (i = 1; i < elf_numsections (obfd); i++)
{
Elf_Internal_Shdr * oheader = oheaders[i];
+ if (oheader == NULL)
+ continue;
if (section_match (oheader, iheader))
/* FIXME: Do we care if there is a potential for
multiple matches ? */
in the input bfd. */
if (iheader->sh_link != SHN_UNDEF)
{
+ /* See PR 20931 for a reproducer. */
+ if (iheader->sh_link >= elf_numsections (ibfd))
+ {
+ (* _bfd_error_handler)
+ /* xgettext:c-format */
+ (_("%B: Invalid sh_link field (%d) in section number %d"),
+ ibfd, iheader->sh_link, secnum);
+ return FALSE;
+ }
+
sh_link = find_link (obfd, iheaders[iheader->sh_link], iheader->sh_link);
if (sh_link != SHN_UNDEF)
{
/* FIXME: Should we install iheader->sh_link
if we could not find a match ? */
(* _bfd_error_handler)
+ /* xgettext:c-format */
(_("%B: Failed to find link section for section %d"), obfd, secnum);
}
}
else
(* _bfd_error_handler)
+ /* xgettext:c-format */
(_("%B: Failed to find info section for section %d"), obfd, secnum);
}
if (elf_onesymtab (abfd) != 0)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: warning: multiple symbol tables detected - ignoring the table in section %u"),
abfd, shindex);
goto success;
if (elf_dynsymtab (abfd) != 0)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: warning: multiple dynamic symbol tables detected - ignoring the table in section %u"),
abfd, shindex);
goto success;
if (hdr->sh_link >= num_sec)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: invalid link %lu for reloc section %s (index %u)"),
abfd, hdr->sh_link, name, shindex);
ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name,
/* FIXME: How to properly handle allocated section reserved
for applications? */
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: don't know how to handle allocated, application "
"specific section `%s' [0x%8x]"),
abfd, name, hdr->sh_type);
&& hdr->sh_type <= SHT_HIPROC)
/* FIXME: We should handle this section. */
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: don't know how to handle processor specific section "
"`%s' [0x%8x]"),
abfd, name, hdr->sh_type);
required to correctly process the section and the file should
be rejected with an error message. */
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: don't know how to handle OS specific section "
"`%s' [0x%8x]"),
abfd, name, hdr->sh_type);
else
/* FIXME: We should handle this section. */
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: don't know how to handle section `%s' [0x%8x]"),
abfd, name, hdr->sh_type);
if (asect->alignment_power >= (sizeof (bfd_vma) * 8) - 1)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: error: Alignment power %d of section `%A' is too big"),
abfd, asect, asect->alignment_power);
arg->failed = TRUE;
if (section_number >= SHN_LORESERVE)
{
+ /* xgettext:c-format */
_bfd_error_handler (_("%B: too many sections: %u"),
abfd, section_number);
return FALSE;
{
asection *kept;
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"),
abfd, d->this_hdr.bfd_section,
s, s->owner);
if (s->output_section == NULL)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: sh_link of section `%A' points to removed section `%A' of `%B'"),
abfd, d->this_hdr.bfd_section, s, s->owner);
bfd_set_error (bfd_error_bad_value);
= get_elf_backend_data (abfd);
if (bed->link_order_error_handler)
bed->link_order_error_handler
+ /* xgettext:c-format */
(_("%B: warning: sh_link not set for section `%A'"),
abfd, sec);
}
}
(*m)->count = new_count;
- if (remove_empty_load && (*m)->p_type == PT_LOAD && (*m)->count == 0)
+ if (remove_empty_load
+ && (*m)->p_type == PT_LOAD
+ && (*m)->count == 0
+ && !(*m)->includes_phdrs)
*m = (*m)->next;
else
m = &(*m)->next;
asection *dynsec, *eh_frame_hdr;
bfd_size_type amt;
bfd_vma addr_mask, wrap_to = 0;
+ bfd_boolean linker_created_pt_phdr_segment = FALSE;
/* Select the allocated sections, and sort them. */
m->p_flags = PF_R | PF_X;
m->p_flags_valid = 1;
m->includes_phdrs = 1;
-
+ linker_created_pt_phdr_segment = TRUE;
*pm = m;
pm = &m->next;
|| ((sections[0]->lma & addr_mask) % maxpagesize
< phdr_size % maxpagesize)
|| (sections[0]->lma & addr_mask & -maxpagesize) < wrap_to)
- phdr_in_segment = FALSE;
+ {
+ /* PR 20815: The ELF standard says that a PT_PHDR segment, if
+ present, must be included as part of the memory image of the
+ program. Ie it must be part of a PT_LOAD segment as well.
+ If we have had to create our own PT_PHDR segment, but it is
+ not going to be covered by the first PT_LOAD segment, then
+ force the inclusion if we can... */
+ if ((abfd->flags & D_PAGED) != 0
+ && linker_created_pt_phdr_segment)
+ phdr_in_segment = TRUE;
+ else
+ phdr_in_segment = FALSE;
+ }
}
for (i = 0, hdrpp = sections; i < count; i++, hdrpp++)
Elf_Internal_Phdr *p;
file_ptr off;
bfd_size_type maxpagesize;
+ unsigned int pt_load_count = 0;
unsigned int alloc;
unsigned int i, j;
bfd_vma header_pad = 0;
maxpagesize = m->p_align;
p->p_align = maxpagesize;
+ pt_load_count += 1;
}
else if (m->p_align_valid)
p->p_align = m->p_align;
}
off_adjust = vma_page_aligned_bias (p->p_vaddr, off, align);
+
+ /* Broken hardware and/or kernel require that files do not
+ map the same page with different permissions on some hppa
+ processors. */
+ if (pt_load_count > 1
+ && bed->no_page_alias
+ && (off & (maxpagesize - 1)) != 0
+ && (off & -maxpagesize) == ((off + off_adjust) & -maxpagesize))
+ off_adjust += maxpagesize;
off += off_adjust;
if (no_contents)
{
|| p_end < p_start))
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: section %A lma %#lx adjusted to %#lx"), abfd, sec,
(unsigned long) s_start, (unsigned long) p_end);
adjust = 0;
&& !ELF_TBSS_SPECIAL (this_hdr, p))
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: section `%A' can't be allocated in segment %d"),
abfd, sec, j);
print_segment_map (m);
{
if (hdr->sh_size != 0)
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: warning: allocated section `%s' not in segment"),
abfd,
(hdr->bfd_section == NULL
else if (m->count != 0)
{
unsigned int i;
+
if (p->p_type != PT_LOAD
&& (p->p_type != PT_NOTE
|| bfd_get_format (abfd) != bfd_core))
{
+ /* A user specified segment layout may include a PHDR
+ segment that overlaps with a LOAD segment... */
+ if (p->p_type == PT_PHDR)
+ {
+ m->count = 0;
+ continue;
+ }
+
if (m->includes_filehdr || m->includes_phdrs)
{
/* PR 17512: file: 2195325e. */
_bfd_error_handler
- (_("%B: warning: non-load segment includes file header and/or program header"),
- abfd);
+ (_("%B: error: non-load segment %d includes file header and/or program header"),
+ abfd, (int)(p - phdrs));
return FALSE;
}
/* Write out the program headers. */
alloc = elf_program_header_size (abfd) / bed->s->sizeof_phdr;
+
+ /* Sort the program headers into the ordering required by the ELF standard. */
+ if (alloc == 0)
+ return TRUE;
+
+ /* PR ld/20815 - Check that the program header segment, if present, will
+ be loaded into memory. FIXME: The check below is not sufficient as
+ really all PT_LOAD segments should be checked before issuing an error
+ message. Plus the PHDR segment does not have to be the first segment
+ in the program header table. But this version of the check should
+ catch all real world use cases.
+
+ FIXME: We used to have code here to sort the PT_LOAD segments into
+ ascending order, as per the ELF spec. But this breaks some programs,
+ including the Linux kernel. But really either the spec should be
+ changed or the programs updated. */
+ if (alloc > 1
+ && tdata->phdr[0].p_type == PT_PHDR
+ && ! bed->elf_backend_allow_non_load_phdr (abfd, tdata->phdr, alloc)
+ && tdata->phdr[1].p_type == PT_LOAD
+ && (tdata->phdr[1].p_vaddr > tdata->phdr[0].p_vaddr
+ || (tdata->phdr[1].p_vaddr + tdata->phdr[1].p_memsz)
+ < (tdata->phdr[0].p_vaddr + tdata->phdr[0].p_memsz)))
+ {
+ /* The fix for this error is usually to edit the linker script being
+ used and set up the program headers manually. Either that or
+ leave room for the headers at the start of the SECTIONS. */
+ _bfd_error_handler (_("\
+%B: error: PHDR segment not covered by LOAD segment"),
+ abfd);
+ return FALSE;
+ }
+
if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0
|| bed->s->write_out_phdrs (abfd, tdata->phdr, alloc) != 0)
return FALSE;
/* This case can occur when using --strip-symbol on a symbol
which is used in a relocation entry. */
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: symbol `%s' required but not present"),
abfd, bfd_asymbol_name (asym_ptr));
bfd_set_error (bfd_error_no_symbols);
{
/* PR 17512: file: f17299af. */
if (segment->p_align > (bfd_vma) 1 << ((sizeof (bfd_vma) * 8) - 2))
+ /* xgettext:c-format */
_bfd_error_handler (_("\
%B: warning: segment alignment of 0x%llx is too large"),
ibfd, (long long) segment->p_align);
shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
if (shndx == SHN_BAD)
{
+ /* xgettext:c-format */
_bfd_error_handler (_("\
Unable to find equivalent output section for symbol '%s' from section '%s'"),
syms[idx]->name ? syms[idx]->name : "<Local sym>",
fail:
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: unsupported relocation type %s"),
abfd, areloc->howto->name);
bfd_set_error (bfd_error_bad_value);