/* 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;
if (strindex >= hdr->sh_size)
{
unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx;
- (*_bfd_error_handler)
+ _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;
- (*_bfd_error_handler) (_("%B symbol number %lu references "
- "nonexistent SHT_SYMTAB_SHNDX section"),
- ibfd, (unsigned long) symoffset);
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%B symbol number %lu references "
+ "nonexistent SHT_SYMTAB_SHNDX section"),
+ ibfd, (unsigned long) symoffset);
if (alloc_intsym != NULL)
free (alloc_intsym);
intsym_buf = NULL;
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 (idx >= shnum)
{
- ((*_bfd_error_handler)
- (_("%B: invalid SHT_GROUP entry"), abfd));
+ _bfd_error_handler
+ (_("%B: invalid SHT_GROUP entry"), abfd);
idx = 0;
}
dest->shdr = elf_elfsections (abfd)[idx];
{
elf_tdata (abfd)->group_sect_ptr = NULL;
elf_tdata (abfd)->num_group = num_group = -1;
- (*_bfd_error_handler) (_("%B: no valid group sections found"), abfd);
+ _bfd_error_handler
+ (_("%B: no valid group sections found"), abfd);
bfd_set_error (bfd_error_bad_value);
}
}
if (elf_group_name (newsect) == NULL)
{
- (*_bfd_error_handler) (_("%B: no group info for section %A"),
- abfd, newsect);
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%B: no group info for section %A"),
+ abfd, newsect);
return FALSE;
}
return TRUE;
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);
}
sh_link. We don't want to proceed. */
if (linksec == NULL)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: sh_link [%d] in section `%A' is incorrect"),
- s->owner, s, elfsec);
+ s->owner, elfsec, s);
result = FALSE;
}
elf_linked_to_section (s) = linksec;
}
}
+ else if (this_hdr->sh_type == SHT_GROUP
+ && 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;
+ }
}
/* Process section groups. */
/* PR binutils/18758: Beware of corrupt binaries with invalid group data. */
if (shdr == NULL || shdr->bfd_section == NULL || shdr->contents == NULL)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: section group entry number %u is corrupt"),
abfd, i);
result = FALSE;
else
{
/* There are some unknown sections in the group. */
- (*_bfd_error_handler)
- (_("%B: unknown [%d] section `%s' in group [%s]"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: unknown [%d] section `%s' in group [%A]"),
abfd,
(unsigned int) idx->shdr->sh_type,
bfd_elf_string_from_elf_section (abfd,
(elf_elfheader (abfd)
->e_shstrndx),
idx->shdr->sh_name),
- shdr->bfd_section->name);
+ shdr->bfd_section);
result = FALSE;
}
}
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)
+ _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)
+ _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 (sections_being_created [shindex])
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: warning: loop in section dependencies detected"), abfd);
return FALSE;
}
Unusual, but possible. Warn, but continue. */
if (elf_onesymtab (abfd) != 0)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: warning: multiple symbol tables detected - ignoring the table in section %u"),
abfd, shindex);
goto success;
Unusual, but possible. Warn, but continue. */
if (elf_dynsymtab (abfd) != 0)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: warning: multiple dynamic symbol tables detected - ignoring the table in section %u"),
abfd, shindex);
goto success;
/* Check for a bogus link to avoid crashing. */
if (hdr->sh_link >= num_sec)
{
- ((*_bfd_error_handler)
- (_("%B: invalid link %lu for reloc section %s (index %u)"),
- abfd, hdr->sh_link, name, shindex));
+ _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,
shindex);
goto success;
if ((hdr->sh_flags & SHF_ALLOC) != 0)
/* FIXME: How to properly handle allocated section reserved
for applications? */
- (*_bfd_error_handler)
+ _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);
else if (hdr->sh_type >= SHT_LOPROC
&& hdr->sh_type <= SHT_HIPROC)
/* FIXME: We should handle this section. */
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: don't know how to handle processor specific section "
"`%s' [0x%8x]"),
abfd, name, hdr->sh_type);
/* SHF_OS_NONCONFORMING indicates that special knowledge is
required to correctly process the section and the file should
be rejected with an error message. */
- (*_bfd_error_handler)
+ _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)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: don't know how to handle section `%s' [0x%8x]"),
abfd, name, hdr->sh_type);
static const struct bfd_elf_special_section special_sections_f[] =
{
- { STRING_COMMA_LEN (".fini"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
- { STRING_COMMA_LEN (".fini_array"), 0, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE },
- { NULL, 0, 0, 0, 0 }
+ { STRING_COMMA_LEN (".fini"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+ { STRING_COMMA_LEN (".fini_array"), -2, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE },
+ { NULL, 0 , 0, 0, 0 }
};
static const struct bfd_elf_special_section special_sections_g[] =
static const struct bfd_elf_special_section special_sections_i[] =
{
- { STRING_COMMA_LEN (".init"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
- { STRING_COMMA_LEN (".init_array"), 0, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE },
- { STRING_COMMA_LEN (".interp"), 0, SHT_PROGBITS, 0 },
- { NULL, 0, 0, 0, 0 }
+ { STRING_COMMA_LEN (".init"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+ { STRING_COMMA_LEN (".init_array"), -2, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".interp"), 0, SHT_PROGBITS, 0 },
+ { NULL, 0, 0, 0, 0 }
};
static const struct bfd_elf_special_section special_sections_l[] =
static const struct bfd_elf_special_section special_sections_p[] =
{
- { STRING_COMMA_LEN (".preinit_array"), 0, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE },
- { STRING_COMMA_LEN (".plt"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
- { NULL, 0, 0, 0, 0 }
+ { STRING_COMMA_LEN (".preinit_array"), -2, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".plt"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+ { NULL, 0, 0, 0, 0 }
};
static const struct bfd_elf_special_section special_sections_r[] =
compressed. */
asect->flags |= SEC_ELF_COMPRESS;
- /* If this section will be compressed, delay adding setion
+ /* If this section will be compressed, delay adding section
name to section name section after it is compressed in
_bfd_elf_assign_file_positions_for_non_load. */
delay_st_name_p = TRUE;
/* PR 17512: file: 0eb809fe, 8b0535ee. */
if (asect->alignment_power >= (sizeof (bfd_vma) * 8) - 1)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: error: Alignment power %d of section `%A' is too big"),
- abfd, asect, asect->alignment_power);
+ abfd, asect->alignment_power, asect);
arg->failed = TRUE;
return;
}
allow the link to proceed. This can happen when users link
non-bss input sections to bss output sections, or emit data
to a bss output section via a linker script. */
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("warning: section `%A' type changed to PROGBITS"), asect);
this_hdr->sh_type = sh_type;
}
/* The ELF backend linker sets sh_info to -2 when the group
signature symbol is global, and thus the index can't be
set until all local symbols are output. */
- asection *igroup = elf_sec_group (elf_next_in_group (sec));
- struct bfd_elf_section_data *sec_data = elf_section_data (igroup);
- unsigned long symndx = sec_data->this_hdr.sh_info;
- unsigned long extsymoff = 0;
+ asection *igroup;
+ struct bfd_elf_section_data *sec_data;
+ unsigned long symndx;
+ unsigned long extsymoff;
struct elf_link_hash_entry *h;
+ /* The point of this little dance to the first SHF_GROUP section
+ then back to the SHT_GROUP section is that this gets us to
+ the SHT_GROUP in the input object. */
+ igroup = elf_sec_group (elf_next_in_group (sec));
+ sec_data = elf_section_data (igroup);
+ symndx = sec_data->this_hdr.sh_info;
+ extsymoff = 0;
if (!elf_bad_symtab (igroup->owner))
{
Elf_Internal_Shdr *symtab_hdr;
d->rela.idx = 0;
}
- elf_shstrtab_sec (abfd) = section_number++;
- _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
- elf_elfheader (abfd)->e_shstrndx = elf_shstrtab_sec (abfd);
-
need_symtab = (bfd_get_symcount (abfd) > 0
|| (link_info == NULL
&& ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC))
_bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
}
+ elf_shstrtab_sec (abfd) = section_number++;
+ _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
+ elf_elfheader (abfd)->e_shstrndx = elf_shstrtab_sec (abfd);
+
if (section_number >= SHN_LORESERVE)
{
+ /* xgettext:c-format */
_bfd_error_handler (_("%B: too many sections: %u"),
abfd, section_number);
return FALSE;
if (discarded_section (s))
{
asection *kept;
- (*_bfd_error_handler)
+ _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);
/* Handle objcopy. */
if (s->output_section == NULL)
{
- (*_bfd_error_handler)
+ _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);
}
continue;
h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, FALSE);
+ if (h == NULL)
+ continue;
if (h->type != bfd_link_hash_defined && h->type != bfd_link_hash_defweak)
continue;
-
if (h->linker_def || h->ldscript_def)
continue;
}
}
- /* Let the backend count up any program headers it might need. */
bed = get_elf_backend_data (abfd);
- if (bed->elf_backend_additional_program_headers)
+
+ if ((abfd->flags & D_PAGED) != 0)
+ {
+ /* Add a PT_GNU_MBIND segment for each mbind section. */
+ unsigned int page_align_power = bfd_log2 (bed->commonpagesize);
+ for (s = abfd->sections; s != NULL; s = s->next)
+ if (elf_section_flags (s) & SHF_GNU_MBIND)
+ {
+ if (elf_section_data (s)->this_hdr.sh_info
+ > PT_GNU_MBIND_NUM)
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: GNU_MBIN section `%A' has invalid sh_info field: %d"),
+ abfd, s, elf_section_data (s)->this_hdr.sh_info);
+ continue;
+ }
+ /* Align mbind section to page size. */
+ if (s->alignment_power < page_align_power)
+ s->alignment_power = page_align_power;
+ segs ++;
+ }
+ }
+
+ /* Let the backend count up any program headers it might need. */
+ if (bed->elf_backend_additional_program_headers)
{
int a;
}
(*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;
bfd_boolean writable;
int tls_count = 0;
asection *first_tls = NULL;
+ asection *first_mbind = NULL;
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++)
first_tls = s;
tls_count++;
}
+ if (first_mbind == NULL
+ && (elf_section_flags (s) & SHF_GNU_MBIND) != 0)
+ first_mbind = s;
}
/* If there are any SHF_TLS output sections, add PT_TLS segment. */
pm = &m->next;
}
+ if (first_mbind && (abfd->flags & D_PAGED) != 0)
+ for (s = first_mbind; s != NULL; s = s->next)
+ if ((elf_section_flags (s) & SHF_GNU_MBIND) != 0
+ && (elf_section_data (s)->this_hdr.sh_info
+ <= PT_GNU_MBIND_NUM))
+ {
+ /* Mandated PF_R. */
+ unsigned long p_flags = PF_R;
+ if ((s->flags & SEC_READONLY) == 0)
+ p_flags |= PF_W;
+ if ((s->flags & SEC_CODE) != 0)
+ p_flags |= PF_X;
+
+ amt = sizeof (struct elf_segment_map) + sizeof (asection *);
+ m = bfd_zalloc (abfd, amt);
+ if (m == NULL)
+ goto error_return;
+ m->next = NULL;
+ m->p_type = (PT_GNU_MBIND_LO
+ + elf_section_data (s)->this_hdr.sh_info);
+ m->count = 1;
+ m->p_flags_valid = 1;
+ m->sections[0] = s;
+ m->p_flags = p_flags;
+
+ *pm = m;
+ pm = &m->next;
+ }
+
/* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME
segment. */
eh_frame_hdr = elf_eh_frame_hdr (abfd);
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->p_memsz = bed->s->sizeof_ehdr;
if (m->count > 0)
{
- if (p->p_vaddr < (bfd_vma) off)
+ if (p->p_vaddr < (bfd_vma) off
+ || (!m->p_paddr_valid
+ && p->p_paddr < (bfd_vma) off))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: Not enough room for program headers, try linking with -N"),
abfd);
bfd_set_error (bfd_error_bad_value);
&& (s_start < p_end
|| p_end < p_start))
{
- (*_bfd_error_handler)
+ _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;
if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0)
&& !ELF_TBSS_SPECIAL (this_hdr, p))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: section `%A' can't be allocated in segment %d"),
abfd, sec, j);
print_segment_map (m);
else if ((hdr->sh_flags & SHF_ALLOC) != 0)
{
if (hdr->sh_size != 0)
- (*_bfd_error_handler)
+ _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);
+ _bfd_error_handler
+ (_("%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;
return FALSE;
name = new_name;
}
- /* Add setion name to section name section. */
+ /* Add section name to section name section. */
if (shdrp->sh_name != (unsigned int) -1)
abort ();
shdrp->sh_name
name, FALSE);
d = elf_section_data (sec);
- /* Add reloc setion name to section name section. */
+ /* Add reloc section name to section name section. */
if (d->rel.hdr
&& !_bfd_elf_set_reloc_sh_name (abfd,
d->rel.hdr,
{
/* This case can occur when using --strip-symbol on a symbol
which is used in a relocation entry. */
- (*_bfd_error_handler)
+ _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);
/* Special segments, such as the PT_PHDR segment, may contain
no sections, but ordinary, loadable segments should contain
something. They are allowed by the ELF spec however, so only
- a warning is produced. */
- if (segment->p_type == PT_LOAD)
- (*_bfd_error_handler) (_("\
-%B: warning: Empty loadable segment detected, is this intentional ?"),
- ibfd);
+ a warning is produced.
+ There is however the valid use case of embedded systems which
+ have segments with p_filesz of 0 and a p_memsz > 0 to initialize
+ flash memory with zeros. No warning is shown for that case. */
+ if (segment->p_type == PT_LOAD
+ && (segment->p_filesz > 0 || segment->p_memsz == 0))
+ /* xgettext:c-format */
+ _bfd_error_handler (_("\
+%B: warning: Empty loadable segment detected at vaddr=0x%.8x, is this intentional ?"),
+ ibfd, segment->p_vaddr);
map->count = 0;
*pointer_to_map = map;
{
/* PR 17512: file: f17299af. */
if (segment->p_align > (bfd_vma) 1 << ((sizeof (bfd_vma) * 8) - 2))
- (*_bfd_error_handler) (_("\
+ /* xgettext:c-format */
+ _bfd_error_handler (_("\
%B: warning: segment alignment of 0x%llx is too large"),
- ibfd, (long long) segment->p_align);
+ ibfd, (long long) segment->p_align);
else
maxpagesize = segment->p_align;
}
elf_section_flags (osec) |= (elf_section_flags (isec)
& (SHF_MASKOS | SHF_MASKPROC));
+ /* Copy sh_info from input for mbind section. */
+ if (elf_section_flags (isec) & SHF_GNU_MBIND)
+ elf_section_data (osec)->this_hdr.sh_info
+ = elf_section_data (isec)->this_hdr.sh_info;
+
/* Set things up for objcopy and relocatable link. The output
SHT_GROUP section will have its elf_next_in_group pointing back
to the input group members. Ignore linker created group section.
section of a symbol to be a section that is
actually in the output file. */
sec2 = bfd_get_section_by_name (abfd, sec->name);
- if (sec2 == NULL)
+ if (sec2 != NULL)
+ 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>",
bfd_set_error (bfd_error_invalid_operation);
goto error_return;
}
-
- shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
- BFD_ASSERT (shndx != SHN_BAD);
}
}
if (hdr->sh_info == 0 || hdr->sh_size < sizeof (Elf_External_Verneed))
{
error_return_bad_verref:
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: .gnu.version_r invalid entry"), abfd);
bfd_set_error (bfd_error_bad_value);
error_return_verref:
if (hdr->sh_info == 0 || hdr->sh_size < sizeof (Elf_External_Verdef))
{
error_return_bad_verdef:
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: .gnu.version_d invalid entry"), abfd);
bfd_set_error (bfd_error_bad_value);
error_return_verdef:
return TRUE;
fail:
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: unsupported relocation type %s"),
abfd, areloc->howto->name);
bfd_set_error (bfd_error_bad_value);
default:
return TRUE;
+ case NT_GNU_PROPERTY_TYPE_0:
+ return _bfd_elf_parse_gnu_properties (abfd, note);
+
case NT_GNU_BUILD_ID:
return elfobj_grok_gnu_build_id (abfd, note);
}
{
size_t offset;
- /* Check for version 1 in pr_version. */
- if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1)
- return FALSE;
- offset = 4;
-
- /* Skip over pr_psinfosz. */
switch (abfd->arch_info->bits_per_word)
{
case 32:
- offset += 4;
+ if (note->descsz < 108)
+ return FALSE;
break;
case 64:
- offset += 4; /* Padding before pr_psinfosz. */
- offset += 8;
+ if (note->descsz < 120)
+ return FALSE;
break;
default:
return FALSE;
}
+ /* Check for version 1 in pr_version. */
+ if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1)
+ return FALSE;
+ offset = 4;
+
+ /* Skip over pr_psinfosz. */
+ if (abfd->arch_info->bits_per_word == 32)
+ offset += 4;
+ else
+ {
+ offset += 4; /* Padding before pr_psinfosz. */
+ offset += 8;
+ }
+
/* pr_fname is PRFNAMESZ (16) + 1 bytes in size. */
elf_tdata (abfd)->core->program
= _bfd_elfcore_strndup (abfd, note->descdata + offset, 17);
/* pr_psargs is PRARGSZ (80) + 1 bytes in size. */
elf_tdata (abfd)->core->command
= _bfd_elfcore_strndup (abfd, note->descdata + offset, 81);
+ offset += 81;
+
+ /* Padding before pr_pid. */
+ offset += 2;
+
+ /* The pr_pid field was added in version "1a". */
+ if (note->descsz < offset + 4)
+ return TRUE;
+
+ elf_tdata (abfd)->core->pid
+ = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
return TRUE;
}
return n;
}
-/* It is only used by x86-64 so far. */
+/* It is only used by x86-64 so far.
+ ??? This repeats *COM* id of zero. sec->id is supposed to be unique,
+ but current usage would allow all of _bfd_std_section to be zero. t*/
asection _bfd_elf_large_com_section
- = BFD_FAKE_SECTION (_bfd_elf_large_com_section,
- SEC_IS_COMMON, NULL, "LARGE_COMMON", 0);
+ = BFD_FAKE_SECTION (_bfd_elf_large_com_section, NULL,
+ "LARGE_COMMON", 0, SEC_IS_COMMON);
void
_bfd_elf_post_process_headers (bfd * abfd,